diff --git a/DEPS b/DEPS
index b1b8bb0..a5f1ece 100644
--- a/DEPS
+++ b/DEPS
@@ -79,11 +79,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': '22c528dccef2716d04bb2ee8906cb5ac17c5b09e',
+  'skia_revision': '16aa82a974f61589fa3ec8040aa1386c64a8e8df',
   # 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': 'c5c99c66680fcbef309e4575bdeb24b96934e1d3',
+  'v8_revision': '2fc50dd0840565cef5b8cd4abdb66030aa786883',
   # 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.
@@ -91,7 +91,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '61d5325e631ea66f0f6b630fb2ecd6b48adb6309',
+  'angle_revision': '1776fd08e9f2fff20a2c3ce68cd682c5eb7148c6',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling build tools
   # and whatever else without interference from each other.
@@ -336,7 +336,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '539248475d66ddfa89af165b96e4a93871ef6800',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'b13fba7efb083a8bb4b7ed47b876a91df3a010d3',
 
   'src/third_party/devtools-node-modules':
     Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'),
@@ -652,7 +652,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'd458ada06171a85af00367251a4ed55db7fe2018',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '6ade76d69d857c98b82f814f080e9990b7fcfe6a', # commit position 21742
+    Var('webrtc_git') + '/src.git' + '@' + '06c944f0353d1885d4a1661a16a20e907f6e9c0b', # commit position 21742
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
@@ -1193,7 +1193,7 @@
   {
     'name': 'tools_traffic_annotation_windows',
     'pattern': '.',
-    'condition': 'host_os == "windows" and checkout_traffic_annotation_tools',
+    'condition': 'host_os == "win" and checkout_traffic_annotation_tools',
     'action': [ 'python',
                 'src/third_party/depot_tools/download_from_google_storage.py',
                 '--no_resume',
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 7b5d6d81..badde29 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -318,16 +318,6 @@
       (),
     ),
     (
-      r'/(WebThread|BrowserThread)::(FILE|FILE_USER_BLOCKING|DB|CACHE)',
-      (
-        'The non-UI/IO BrowserThreads are deprecated, please migrate this',
-        'code to TaskScheduler. See https://goo.gl/mDSxKl for details.',
-        'For questions, contact base/task_scheduler/OWNERS.',
-      ),
-      True,
-      (),
-    ),
-    (
       'base::SequenceChecker',
       (
         'Consider using SEQUENCE_CHECKER macros instead of the class directly.',
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 26f0220..90f66d8 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -88,6 +88,7 @@
 import org.chromium.content_public.common.BrowserSideNavigationPolicy;
 import org.chromium.content_public.common.ContentUrlConstants;
 import org.chromium.content_public.common.Referrer;
+import org.chromium.content_public.common.UseZoomForDSFPolicy;
 import org.chromium.device.gamepad.GamepadList;
 import org.chromium.net.NetworkChangeNotifier;
 import org.chromium.ui.base.ActivityWindowAndroid;
@@ -3366,10 +3367,16 @@
             if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
                 // Note this will trigger IPC back to browser even if nothing is
                 // hit.
-                float dipScale = getDeviceScaleFactor();
-                nativeRequestNewHitTestDataAt(mNativeAwContents,
-                        event.getX() / dipScale, event.getY() / dipScale,
-                        Math.max(event.getTouchMajor(), event.getTouchMinor()) / dipScale);
+                float eventX = event.getX();
+                float eventY = event.getY();
+                float touchMajor = Math.max(event.getTouchMajor(), event.getTouchMinor());
+                if (!UseZoomForDSFPolicy.isUseZoomForDSFEnabled()) {
+                    float dipScale = getDeviceScaleFactor();
+                    eventX /= dipScale;
+                    eventY /= dipScale;
+                    touchMajor /= dipScale;
+                }
+                nativeRequestNewHitTestDataAt(mNativeAwContents, eventX, eventY, touchMajor);
             }
 
             if (mOverScrollGlow != null) {
@@ -3616,7 +3623,8 @@
     private native void nativeKillRenderProcess(long nativeAwContents);
     private native byte[] nativeGetCertificate(long nativeAwContents);
 
-    // Coordinates in desity independent pixels.
+    // Coordinates are in physical pixels when --use-zoom-for-dsf is enabled.
+    // Otherwise, coordinates are in desity independent pixels.
     private native void nativeRequestNewHitTestDataAt(long nativeAwContents, float x, float y,
             float touchMajor);
     private native void nativeUpdateLastHitTestData(long nativeAwContents);
diff --git a/ash/magnifier/magnification_controller.cc b/ash/magnifier/magnification_controller.cc
index 49c7ed93..b91e5a7 100644
--- a/ash/magnifier/magnification_controller.cc
+++ b/ash/magnifier/magnification_controller.cc
@@ -12,6 +12,7 @@
 #include "ash/display/root_window_transformers.h"
 #include "ash/host/ash_window_tree_host.h"
 #include "ash/host/root_window_transformer.h"
+#include "ash/public/cpp/ash_switches.h"
 #include "ash/public/cpp/config.h"
 #include "ash/root_window_controller.h"
 #include "ash/shell.h"
@@ -20,7 +21,6 @@
 #include "base/numerics/ranges.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/timer/timer.h"
-#include "chromeos/chromeos_switches.h"
 #include "ui/aura/client/cursor_client.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_tree_host.h"
@@ -35,7 +35,9 @@
 #include "ui/display/screen.h"
 #include "ui/events/event.h"
 #include "ui/events/event_handler.h"
+#include "ui/events/event_rewriter.h"
 #include "ui/events/gesture_event_details.h"
+#include "ui/events/gestures/gesture_provider_aura.h"
 #include "ui/gfx/geometry/point3_f.h"
 #include "ui/gfx/geometry/point_conversions.h"
 #include "ui/gfx/geometry/point_f.h"
@@ -52,6 +54,9 @@
 const float kInitialMagnifiedScale = 2.0f;
 const float kScrollScaleChangeFactor = 0.00125f;
 
+const float kZoomGestureLockThreshold = 0.2f;
+const float kScrollGestureLockThreshold = 2500.0f;
+
 // Default animation parameters for redrawing the magnification window.
 const gfx::Tween::Type kDefaultAnimationTweenType = gfx::Tween::EASE_OUT;
 const int kDefaultAnimationDurationInMs = 100;
@@ -92,11 +97,21 @@
 ////////////////////////////////////////////////////////////////////////////////
 // MagnificationControllerImpl:
 
+// MagnificationControllerImpl implements GestureConsumer as it has its own
+// GestureProvider to recognize gestures with screen coordinates of touches.
+// Logical coordinates of touches cannot be used as they are changed with
+// viewport change: scroll, zoom.
+// MagnificationControllerImpl implements EventRewriter to see and rewrite touch
+// events. Once the controller detects two fingers pinch or scroll, it starts
+// consuming all touch events not to confuse an app or a browser on the screen.
+// It needs to rewrite events to dispatch touch cancel events.
 class MagnificationControllerImpl : public MagnificationController,
                                     public ui::EventHandler,
                                     public ui::ImplicitAnimationObserver,
                                     public aura::WindowObserver,
-                                    public ui::InputMethodObserver {
+                                    public ui::InputMethodObserver,
+                                    public ui::GestureConsumer,
+                                    public ui::EventRewriter {
  public:
   MagnificationControllerImpl();
   ~MagnificationControllerImpl() override;
@@ -126,6 +141,8 @@
     return point_of_interest_;
   }
 
+  void AddEventRewriterForTesting() override;
+
   bool IsOnAnimationForTesting() const override { return is_on_animation_; }
 
   void DisableMoveMagnifierDelayForTesting() override {
@@ -133,6 +150,28 @@
   }
 
  private:
+  class GestureProviderClient : public ui::GestureProviderAuraClient {
+   public:
+    GestureProviderClient() = default;
+    ~GestureProviderClient() override = default;
+
+    // ui::GestureProviderAuraClient overrides:
+    void OnGestureEvent(GestureConsumer* consumer,
+                        ui::GestureEvent* event) override {
+      // Do nothing. OnGestureEvent is for timer based gesture events, e.g. tap.
+      // MagnificationController is interested only in pinch and scroll
+      // gestures.
+      DCHECK_NE(ui::ET_GESTURE_SCROLL_BEGIN, event->type());
+      DCHECK_NE(ui::ET_GESTURE_SCROLL_END, event->type());
+      DCHECK_NE(ui::ET_GESTURE_SCROLL_UPDATE, event->type());
+      DCHECK_NE(ui::ET_GESTURE_PINCH_BEGIN, event->type());
+      DCHECK_NE(ui::ET_GESTURE_PINCH_END, event->type());
+      DCHECK_NE(ui::ET_GESTURE_PINCH_UPDATE, event->type());
+    }
+  };
+
+  enum LockedGestureType { NO_GESTURE, ZOOM, SCROLL };
+
   // ui::ImplicitAnimationObserver overrides:
   void OnImplicitAnimationsCompleted() override;
 
@@ -199,6 +238,18 @@
   void OnTouchEvent(ui::TouchEvent* event) override;
   void OnGestureEvent(ui::GestureEvent* event) override;
 
+  // ui::EventRewriter overrides:
+  ui::EventRewriteStatus RewriteEvent(
+      const ui::Event& event,
+      std::unique_ptr<ui::Event>* rewritten_event) override;
+  ui::EventRewriteStatus NextDispatchEvent(
+      const ui::Event& last_event,
+      std::unique_ptr<ui::Event>* new_event) override;
+
+  // Process pending gestures in |gesture_provider_|. This method returns true
+  // if the controller needs to cancel existing touches.
+  bool ProcessGestures();
+
   // Moves the view port when |point| is located within
   // |x_panning_margin| and |y_pannin_margin| to the edge of the visible
   // window region. The view port will be moved so that the |point| will be
@@ -255,8 +306,35 @@
   float scale_;
   gfx::PointF origin_;
 
+  float original_scale_;
+  gfx::PointF original_origin_;
+
   ScrollDirection scroll_direction_;
 
+  // MagnificationController locks gesture once user performs either scroll or
+  // pinch gesture above those thresholds.
+  LockedGestureType locked_gesture_ = NO_GESTURE;
+
+  // If true, MagnificationController consumes all touch events.
+  bool consume_touch_event_ = false;
+
+  // Number of touch points on the screen.
+  int32_t touch_points_ = 0;
+
+  // Map for holding ET_TOUCH_PRESS events. Those events are used to dispatch
+  // ET_TOUCH_CANCELLED events. Events will be removed from this map when press
+  // events are cancelled, i.e. size of this map can be different from number of
+  // touches on the screen. Key is pointer id.
+  std::map<int32_t, std::unique_ptr<ui::TouchEvent>> press_event_map_;
+
+  std::unique_ptr<GestureProviderClient> gesture_provider_client_;
+
+  // MagnificationCotroller owns its GestureProvider to detect gestures with
+  // screen coordinates of touch events. As MagnificationController changes zoom
+  // level and moves viewport, logical coordinates of touches cannot be used for
+  // gesture detection as they are changed if the controller reacts to gestures.
+  std::unique_ptr<ui::GestureProviderAura> gesture_provider_;
+
   // Timer for moving magnifier window when it fires.
   base::OneShotTimer move_magnifier_timer_;
 
@@ -280,11 +358,22 @@
       keep_focus_centered_(false),
       move_cursor_after_animation_(false),
       scale_(kNonMagnifiedScale),
+      original_scale_(kNonMagnifiedScale),
       scroll_direction_(SCROLL_NONE),
       disable_move_magnifier_delay_(false) {
   Shell::Get()->AddPreTargetHandler(this);
   root_window_->AddObserver(this);
+
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          ash::switches::kAshNewTouchSupportForScreenMagnification)) {
+    root_window_->GetHost()->GetEventSource()->AddEventRewriter(this);
+  }
+
   point_of_interest_ = root_window_->bounds().CenterPoint();
+
+  gesture_provider_client_ = std::make_unique<GestureProviderClient>();
+  gesture_provider_ = std::make_unique<ui::GestureProviderAura>(
+      this, gesture_provider_client_.get());
 }
 
 MagnificationControllerImpl::~MagnificationControllerImpl() {
@@ -292,6 +381,11 @@
   if (input_method)
     input_method->RemoveObserver(this);
 
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          ash::switches::kAshNewTouchSupportForScreenMagnification)) {
+    root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this);
+  }
+
   root_window_->RemoveObserver(this);
 
   Shell::Get()->RemovePreTargetHandler(this);
@@ -476,6 +570,13 @@
   root_window_->AddObserver(this);
 }
 
+void MagnificationControllerImpl::AddEventRewriterForTesting() {
+  DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
+      ash::switches::kAshNewTouchSupportForScreenMagnification));
+
+  root_window_->GetHost()->GetEventSource()->AddEventRewriter(this);
+}
+
 void MagnificationControllerImpl::AfterAnimationMoveCursorTo(
     const gfx::Point& location) {
   DCHECK(root_window_);
@@ -707,12 +808,177 @@
   }
 }
 
+ui::EventRewriteStatus MagnificationControllerImpl::RewriteEvent(
+    const ui::Event& event,
+    std::unique_ptr<ui::Event>* rewritten_event) {
+  if (!IsEnabled())
+    return ui::EVENT_REWRITE_CONTINUE;
+
+  if (!event.IsTouchEvent())
+    return ui::EVENT_REWRITE_CONTINUE;
+
+  const ui::TouchEvent* touch_event = event.AsTouchEvent();
+
+  if (touch_event->type() == ui::ET_TOUCH_PRESSED) {
+    touch_points_++;
+    press_event_map_[touch_event->pointer_details().id] =
+        std::make_unique<ui::TouchEvent>(*touch_event);
+  } else if (touch_event->type() == ui::ET_TOUCH_RELEASED) {
+    touch_points_--;
+    press_event_map_.erase(touch_event->pointer_details().id);
+  }
+
+  ui::TouchEvent touch_event_copy = *touch_event;
+  if (gesture_provider_->OnTouchEvent(&touch_event_copy)) {
+    gesture_provider_->OnTouchEventAck(
+        touch_event_copy.unique_event_id(), false /* event_consumed */,
+        false /* is_source_touch_event_set_non_blocking */);
+  } else {
+    return ui::EVENT_REWRITE_DISCARD;
+  }
+
+  // User can change zoom level with two fingers pinch and pan around with two
+  // fingers scroll. Once MagnificationController detects one of those two
+  // gestures, it starts consuming all touch events with cancelling existing
+  // touches. If cancel_pressed_touches is set to true, ET_TOUCH_CANCELLED
+  // events are dispatched for existing touches after the next for-loop.
+  bool cancel_pressed_touches = ProcessGestures();
+
+  if (cancel_pressed_touches) {
+    DCHECK_EQ(2u, press_event_map_.size());
+
+    // MagnificationController starts consuming all touch events after it
+    // cancells existing touches.
+    consume_touch_event_ = true;
+
+    auto it = press_event_map_.begin();
+
+    std::unique_ptr<ui::TouchEvent> rewritten_touch_event =
+        std::make_unique<ui::TouchEvent>(ui::ET_TOUCH_CANCELLED, gfx::Point(),
+                                         touch_event->time_stamp(),
+                                         it->second->pointer_details());
+    rewritten_touch_event->set_location_f(it->second->location_f());
+    rewritten_touch_event->set_root_location_f(it->second->root_location_f());
+    rewritten_touch_event->set_flags(it->second->flags());
+    *rewritten_event = std::move(rewritten_touch_event);
+
+    // The other event is cancelled in NextDispatchEvent.
+    press_event_map_.erase(it);
+
+    return ui::EVENT_REWRITE_DISPATCH_ANOTHER;
+  }
+
+  bool discard = consume_touch_event_;
+
+  // Reset state once no point is touched on the screen.
+  if (touch_points_ == 0) {
+    consume_touch_event_ = false;
+    locked_gesture_ = NO_GESTURE;
+
+    // Jump back to exactly 1.0 if we are just a tiny bit zoomed in.
+    if (scale_ < kMinMagnifiedScaleThreshold) {
+      SetScale(kNonMagnifiedScale, true /* animate */);
+    }
+  }
+
+  if (discard)
+    return ui::EVENT_REWRITE_DISCARD;
+
+  return ui::EVENT_REWRITE_CONTINUE;
+}
+
+bool MagnificationControllerImpl::ProcessGestures() {
+  bool cancel_pressed_touches = false;
+
+  std::vector<std::unique_ptr<ui::GestureEvent>> gestures =
+      gesture_provider_->GetAndResetPendingGestures();
+  for (const auto& gesture : gestures) {
+    const ui::GestureEventDetails& details = gesture->details();
+
+    if (details.touch_points() != 2)
+      continue;
+
+    if (gesture->type() == ui::ET_GESTURE_PINCH_BEGIN) {
+      original_scale_ = scale_;
+
+      // Start consuming touch events with cancelling existing touches.
+      if (!consume_touch_event_)
+        cancel_pressed_touches = true;
+    } else if (gesture->type() == ui::ET_GESTURE_PINCH_UPDATE) {
+      if (locked_gesture_ == NO_GESTURE || locked_gesture_ == ZOOM) {
+        float scale = GetScale() * details.scale();
+        ValidateScale(&scale);
+
+        if (locked_gesture_ == NO_GESTURE &&
+            std::abs(scale - original_scale_) > kZoomGestureLockThreshold) {
+          locked_gesture_ = MagnificationControllerImpl::ZOOM;
+        }
+
+        RedrawDIP(origin_, scale, 0, kDefaultAnimationTweenType);
+      }
+    } else if (gesture->type() == ui::ET_GESTURE_SCROLL_BEGIN) {
+      original_origin_ = origin_;
+
+      // Start consuming all touch events with cancelling existing touches.
+      if (!consume_touch_event_)
+        cancel_pressed_touches = true;
+    } else if (gesture->type() == ui::ET_GESTURE_SCROLL_UPDATE) {
+      if (locked_gesture_ == NO_GESTURE || locked_gesture_ == SCROLL) {
+        // Divide by scale to keep scroll speed same at any scale.
+        float new_x = origin_.x() + (-1.0f * details.scroll_x() / scale_);
+        float new_y = origin_.y() + (-1.0f * details.scroll_y() / scale_);
+
+        if (locked_gesture_ == NO_GESTURE) {
+          float diff_x = (new_x - original_origin_.x()) * scale_;
+          float diff_y = (new_y - original_origin_.y()) * scale_;
+          float squared_distance = (diff_x * diff_x) + (diff_y * diff_y);
+          if (squared_distance > kScrollGestureLockThreshold) {
+            locked_gesture_ = SCROLL;
+          }
+        }
+
+        RedrawDIP(gfx::PointF(new_x, new_y), scale_, 0,
+                  kDefaultAnimationTweenType);
+      }
+    }
+  }
+
+  return cancel_pressed_touches;
+}
+
+ui::EventRewriteStatus MagnificationControllerImpl::NextDispatchEvent(
+    const ui::Event& last_event,
+    std::unique_ptr<ui::Event>* new_event) {
+  DCHECK_EQ(1u, press_event_map_.size());
+
+  auto it = press_event_map_.begin();
+
+  std::unique_ptr<ui::TouchEvent> event = std::make_unique<ui::TouchEvent>(
+      ui::ET_TOUCH_CANCELLED, gfx::Point(), last_event.time_stamp(),
+      it->second->pointer_details());
+  event->set_location_f(it->second->location_f());
+  event->set_root_location_f(it->second->root_location_f());
+  event->set_flags(it->second->flags());
+  *new_event = std::move(event);
+
+  press_event_map_.erase(it);
+
+  DCHECK_EQ(0u, press_event_map_.size());
+
+  return ui::EVENT_REWRITE_REWRITTEN;
+}
+
 void MagnificationControllerImpl::OnGestureEvent(ui::GestureEvent* event) {
+  // TODO(yawano): Remove old touch support implementation once the new one is
+  // enabled by default.
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          ash::switches::kAshNewTouchSupportForScreenMagnification)) {
+    return;
+  }
+
   if (!IsEnabled())
     return;
 
-  // TODO(katie): Scroll and pinch gestures are not firing at very high
-  // magnification, i.e. above about a scale of 5 on a snappy test device.
   const ui::GestureEventDetails& details = event->details();
   if (details.type() == ui::ET_GESTURE_SCROLL_UPDATE &&
       details.touch_points() == 2) {
diff --git a/ash/magnifier/magnification_controller.h b/ash/magnifier/magnification_controller.h
index f24e9b1d..1edb7548 100644
--- a/ash/magnifier/magnification_controller.h
+++ b/ash/magnifier/magnification_controller.h
@@ -94,6 +94,10 @@
   virtual void SwitchTargetRootWindow(aura::Window* new_root_window,
                                       bool redraw_original_root) = 0;
 
+  // Adds event rewriter for testing. Event rewriter is added at construction of
+  // the controller. But test run happens after the construction.
+  virtual void AddEventRewriterForTesting() = 0;
+
  protected:
   MagnificationController() {}
 
diff --git a/ash/magnifier/magnification_controller_unittest.cc b/ash/magnifier/magnification_controller_unittest.cc
index 802fcd01..5197c4f 100644
--- a/ash/magnifier/magnification_controller_unittest.cc
+++ b/ash/magnifier/magnification_controller_unittest.cc
@@ -4,8 +4,10 @@
 
 #include "ash/magnifier/magnification_controller.h"
 
+#include "ash/public/cpp/ash_switches.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
+#include "base/command_line.h"
 #include "base/strings/stringprintf.h"
 #include "ui/aura/env.h"
 #include "ui/aura/test/aura_test_utils.h"
@@ -13,6 +15,7 @@
 #include "ui/base/ime/input_method.h"
 #include "ui/display/manager/display_manager.h"
 #include "ui/display/screen.h"
+#include "ui/events/event_handler.h"
 #include "ui/events/test/event_generator.h"
 #include "ui/gfx/geometry/rect_conversions.h"
 #include "ui/views/controls/textfield/textfield.h"
@@ -52,6 +55,21 @@
   DISALLOW_COPY_AND_ASSIGN(TextInputView);
 };
 
+class TouchEventWatcher : public ui::EventHandler {
+ public:
+  TouchEventWatcher() = default;
+  ~TouchEventWatcher() override = default;
+
+  void OnTouchEvent(ui::TouchEvent* touch_event) override {
+    touch_events.push_back(*touch_event);
+  }
+
+  std::vector<ui::TouchEvent> touch_events;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TouchEventWatcher);
+};
+
 }  // namespace
 
 class MagnificationControllerTest : public AshTestBase {
@@ -64,11 +82,19 @@
     UpdateDisplay(base::StringPrintf("%dx%d", kRootWidth, kRootHeight));
 
     GetMagnificationController()->DisableMoveMagnifierDelayForTesting();
+
+    touch_event_watcher_ = std::make_unique<TouchEventWatcher>();
+    GetRootWindow()->PrependPreTargetHandler(touch_event_watcher_.get());
   }
 
-  void TearDown() override { AshTestBase::TearDown(); }
+  void TearDown() override {
+    GetRootWindow()->RemovePreTargetHandler(touch_event_watcher_.get());
+    AshTestBase::TearDown();
+  }
 
  protected:
+  std::unique_ptr<TouchEventWatcher> touch_event_watcher_;
+
   aura::Window* GetRootWindow() const { return Shell::GetPrimaryRootWindow(); }
 
   std::string GetHostMouseLocation() {
@@ -128,6 +154,37 @@
     text_input_view_->FocusOnTextInput();
   }
 
+  void DispatchTouchEvent(ui::EventType event_type,
+                          const gfx::Point& point,
+                          const base::TimeTicks& time,
+                          const ui::PointerDetails& pointer_details) {
+    ui::TouchEvent event(event_type, point, time, pointer_details);
+    GetEventGenerator().Dispatch(&event);
+  }
+
+  void PerformTwoFingersScrollGesture() {
+    base::TimeTicks time = base::TimeTicks::Now();
+    ui::PointerDetails pointer_details1(
+        ui::EventPointerType::POINTER_TYPE_TOUCH, 0);
+    ui::PointerDetails pointer_details2(
+        ui::EventPointerType::POINTER_TYPE_TOUCH, 1);
+
+    DispatchTouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(150, 10), time,
+                       pointer_details1);
+    DispatchTouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(150, 20), time,
+                       pointer_details2);
+
+    DispatchTouchEvent(ui::ET_TOUCH_MOVED, gfx::Point(200, 10), time,
+                       pointer_details1);
+    DispatchTouchEvent(ui::ET_TOUCH_MOVED, gfx::Point(200, 20), time,
+                       pointer_details2);
+
+    DispatchTouchEvent(ui::ET_TOUCH_RELEASED, gfx::Point(200, 10), time,
+                       pointer_details1);
+    DispatchTouchEvent(ui::ET_TOUCH_RELEASED, gfx::Point(200, 20), time,
+                       pointer_details2);
+  }
+
  private:
   TextInputView* text_input_view_;
 
@@ -738,4 +795,185 @@
   EXPECT_NE(21.0f / 2.0f, GetMagnificationController()->GetScaleFromScroll(.5));
 }
 
+// Performs pinch zoom and confirm that zoom level is changed. This test case
+// also tests touch event handling.
+TEST_F(MagnificationControllerTest, PinchZoom) {
+  // TODO(yawano): remove this once the flag is removed.
+  base::CommandLine::ForCurrentProcess()->AppendSwitch(
+      ash::switches::kAshNewTouchSupportForScreenMagnification);
+  GetMagnificationController()->AddEventRewriterForTesting();
+
+  ASSERT_EQ(0u, touch_event_watcher_->touch_events.size());
+
+  GetMagnificationController()->SetEnabled(true);
+  ASSERT_EQ(2.0f, GetMagnificationController()->GetScale());
+
+  base::TimeTicks time = base::TimeTicks::Now();
+  ui::PointerDetails pointer_details1(ui::EventPointerType::POINTER_TYPE_TOUCH,
+                                      0);
+  ui::PointerDetails pointer_details2(ui::EventPointerType::POINTER_TYPE_TOUCH,
+                                      1);
+
+  // Simulate pinch gesture.
+  DispatchTouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(900, 10), time,
+                     pointer_details1);
+  DispatchTouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(1100, 10), time,
+                     pointer_details2);
+
+  ASSERT_EQ(2u, touch_event_watcher_->touch_events.size());
+  EXPECT_EQ(ui::ET_TOUCH_PRESSED, touch_event_watcher_->touch_events[0].type());
+  EXPECT_EQ(ui::ET_TOUCH_PRESSED, touch_event_watcher_->touch_events[1].type());
+
+  DispatchTouchEvent(ui::ET_TOUCH_MOVED, gfx::Point(850, 10), time,
+                     pointer_details1);
+  DispatchTouchEvent(ui::ET_TOUCH_MOVED, gfx::Point(1150, 10), time,
+                     pointer_details2);
+
+  // Expect that event watcher receives touch cancelled events. Magnification
+  // controller should cancel existing touches when it detects interested
+  // gestures.
+  ASSERT_EQ(4u, touch_event_watcher_->touch_events.size());
+  EXPECT_EQ(ui::ET_TOUCH_CANCELLED,
+            touch_event_watcher_->touch_events[2].type());
+  EXPECT_EQ(ui::ET_TOUCH_CANCELLED,
+            touch_event_watcher_->touch_events[3].type());
+
+  DispatchTouchEvent(ui::ET_TOUCH_MOVED, gfx::Point(800, 10), time,
+                     pointer_details1);
+  DispatchTouchEvent(ui::ET_TOUCH_MOVED, gfx::Point(1200, 10), time,
+                     pointer_details2);
+
+  DispatchTouchEvent(ui::ET_TOUCH_RELEASED, gfx::Point(800, 10), time,
+                     pointer_details1);
+  DispatchTouchEvent(ui::ET_TOUCH_RELEASED, gfx::Point(1200, 10), time,
+                     pointer_details2);
+
+  // All events are consumed by the controller after it detects gesture.
+  EXPECT_EQ(4u, touch_event_watcher_->touch_events.size());
+
+  EXPECT_LT(2.0f, GetMagnificationController()->GetScale());
+
+  float ratio = GetMagnificationController()->GetScale() / 2.0f;
+
+  // Peform pinch gesture again with 4.0x.
+  GetMagnificationController()->SetScale(4.0f, false /* animate */);
+
+  DispatchTouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(900, 10), time,
+                     pointer_details1);
+  DispatchTouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(1100, 10), time,
+                     pointer_details2);
+
+  DispatchTouchEvent(ui::ET_TOUCH_MOVED, gfx::Point(800, 10), time,
+                     pointer_details1);
+  DispatchTouchEvent(ui::ET_TOUCH_MOVED, gfx::Point(1200, 10), time,
+                     pointer_details2);
+
+  DispatchTouchEvent(ui::ET_TOUCH_RELEASED, gfx::Point(800, 10), time,
+                     pointer_details1);
+  DispatchTouchEvent(ui::ET_TOUCH_RELEASED, gfx::Point(1200, 10), time,
+                     pointer_details2);
+
+  float ratio_zoomed = GetMagnificationController()->GetScale() / 4.0f;
+
+  // Ratio of zoom level change should be the same regardless of current zoom
+  // level.
+  EXPECT_GT(0.01f, std::abs(ratio - ratio_zoomed));
+}
+
+TEST_F(MagnificationControllerTest, TwoFingersScroll) {
+  // TODO(yawano): remove this once the flag is removed.
+  base::CommandLine::ForCurrentProcess()->AppendSwitch(
+      ash::switches::kAshNewTouchSupportForScreenMagnification);
+  GetMagnificationController()->AddEventRewriterForTesting();
+
+  GetMagnificationController()->SetEnabled(true);
+  ASSERT_EQ(2.0f, GetMagnificationController()->GetScale());
+
+  const gfx::Point initial_position =
+      GetMagnificationController()->GetWindowPosition();
+  PerformTwoFingersScrollGesture();
+  const gfx::Point moved_position =
+      GetMagnificationController()->GetWindowPosition();
+
+  // Confirm that two fingers scroll gesture moves viewport.
+  EXPECT_GT(initial_position.x(), moved_position.x());
+  EXPECT_EQ(initial_position.y(), moved_position.y());
+  EXPECT_EQ(2.0f, GetMagnificationController()->GetScale());
+
+  int32_t delta = initial_position.x() - moved_position.x();
+
+  // Perform the same gesture with 4.0x.
+  GetMagnificationController()->SetScale(4.0f, false /* animate */);
+
+  const gfx::Point initial_position_zoomed =
+      GetMagnificationController()->GetWindowPosition();
+  PerformTwoFingersScrollGesture();
+  const gfx::Point moved_position_zoomed =
+      GetMagnificationController()->GetWindowPosition();
+
+  EXPECT_GT(initial_position_zoomed.x(), moved_position_zoomed.x());
+  EXPECT_EQ(initial_position_zoomed.y(), moved_position_zoomed.y());
+  EXPECT_EQ(4.0f, GetMagnificationController()->GetScale());
+
+  int32_t delta_zoomed =
+      initial_position_zoomed.x() - moved_position_zoomed.x();
+
+  // Scrolled delta becomes half with 4.0x compared to 2.0x.
+  EXPECT_EQ(delta, delta_zoomed * 2);
+}
+
+TEST_F(MagnificationControllerTest, GestureLock) {
+  // TODO(yawano): remove this once flag is removed.
+  base::CommandLine::ForCurrentProcess()->AppendSwitch(
+      ash::switches::kAshNewTouchSupportForScreenMagnification);
+  GetMagnificationController()->AddEventRewriterForTesting();
+
+  GetMagnificationController()->SetEnabled(true);
+  ASSERT_EQ(2.0f, GetMagnificationController()->GetScale());
+
+  // Perform pinch zoom gesture.
+  base::TimeTicks time = base::TimeTicks::Now();
+  ui::PointerDetails pointer_details1(ui::EventPointerType::POINTER_TYPE_TOUCH,
+                                      0);
+  ui::PointerDetails pointer_details2(ui::EventPointerType::POINTER_TYPE_TOUCH,
+                                      1);
+
+  DispatchTouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(900, 10), time,
+                     pointer_details1);
+  DispatchTouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(1100, 10), time,
+                     pointer_details2);
+
+  DispatchTouchEvent(ui::ET_TOUCH_MOVED, gfx::Point(800, 10), time,
+                     pointer_details1);
+  DispatchTouchEvent(ui::ET_TOUCH_MOVED, gfx::Point(1200, 10), time,
+                     pointer_details2);
+
+  // Confirm that zoom level has changed.
+  float zoomed_scale = GetMagnificationController()->GetScale();
+  EXPECT_LT(2.0f, zoomed_scale);
+
+  // Confirms that zoom level has changed more than threshold to lock gesture
+  // type.
+  ASSERT_LT(0.2f, zoomed_scale - 2.0f);
+
+  gfx::Point initial_position =
+      GetMagnificationController()->GetWindowPosition();
+
+  // Perform scroll gesture.
+  DispatchTouchEvent(ui::ET_TOUCH_MOVED, gfx::Point(800, 100), time,
+                     pointer_details1);
+  DispatchTouchEvent(ui::ET_TOUCH_MOVED, gfx::Point(1200, 100), time,
+                     pointer_details2);
+
+  DispatchTouchEvent(ui::ET_TOUCH_RELEASED, gfx::Point(800, 100), time,
+                     pointer_details1);
+  DispatchTouchEvent(ui::ET_TOUCH_RELEASED, gfx::Point(1200, 100), time,
+                     pointer_details2);
+
+  // Confirm that nothing happens.
+  EXPECT_EQ(initial_position,
+            GetMagnificationController()->GetWindowPosition());
+  EXPECT_EQ(zoomed_scale, GetMagnificationController()->GetScale());
+}
+
 }  // namespace ash
diff --git a/ash/public/cpp/ash_switches.cc b/ash/public/cpp/ash_switches.cc
index 50875bd..f35169a9 100644
--- a/ash/public/cpp/ash_switches.cc
+++ b/ash/public/cpp/ash_switches.cc
@@ -126,6 +126,10 @@
 const char kAshHideNotificationsForFactory[] =
     "ash-hide-notifications-for-factory";
 
+// Enables new implementation of touch support for screen magnification.
+const char kAshNewTouchSupportForScreenMagnification[] =
+    "ash-new-touch-support-for-screen-magnification";
+
 // Enables the shelf color to be derived from the wallpaper.
 const char kAshShelfColor[] = "ash-shelf-color";
 const char kAshShelfColorEnabled[] = "enabled";
diff --git a/ash/public/cpp/ash_switches.h b/ash/public/cpp/ash_switches.h
index 395df8e..da36a97 100644
--- a/ash/public/cpp/ash_switches.h
+++ b/ash/public/cpp/ash_switches.h
@@ -45,6 +45,7 @@
 ASH_PUBLIC_EXPORT extern const char kAshUiModeClamshell[];
 ASH_PUBLIC_EXPORT extern const char kAshUiModeTablet[];
 ASH_PUBLIC_EXPORT extern const char kAshHideNotificationsForFactory[];
+ASH_PUBLIC_EXPORT extern const char kAshNewTouchSupportForScreenMagnification[];
 ASH_PUBLIC_EXPORT extern const char kAshShelfColor[];
 ASH_PUBLIC_EXPORT extern const char kAshShelfColorEnabled[];
 ASH_PUBLIC_EXPORT extern const char kAshShelfColorDisabled[];
diff --git a/base/lazy_instance.h b/base/lazy_instance.h
index 58f0e7a..36d31586 100644
--- a/base/lazy_instance.h
+++ b/base/lazy_instance.h
@@ -34,12 +34,11 @@
 // requires that Type be a complete type so we can determine the size.
 //
 // Example usage:
-//   // Does not generate a dynamic initializer.
-//   LazyInstance<MyClass>::Leaky my_lazy_instance;
+//   static LazyInstance<MyClass>::Leaky inst = LAZY_INSTANCE_INITIALIZER;
 //   void SomeMethod() {
-//     my_lazy_instance.Get().SomeMethod();  // MyClass::SomeMethod()
+//     inst.Get().SomeMethod();  // MyClass::SomeMethod()
 //
-//     MyClass* ptr = my_lazy_instance.Pointer();
+//     MyClass* ptr = inst.Pointer();
 //     ptr->DoDoDo();  // MyClass::DoDoDo
 //   }
 
@@ -53,11 +52,9 @@
 #include "base/lazy_instance_helpers.h"
 #include "base/logging.h"
 #include "base/threading/thread_restrictions.h"
-#include "build/build_config.h"
 
-// To support the old initialization pattern for LazyInstance, i.e.:
-// LazyInstance<MyClass>::Leaky my_lazy_instance = LAZY_INSTANCE_INITIALIZER;
-// TODO(gab): Remove this.
+// LazyInstance uses its own struct initializer-list style static
+// initialization, which does not require a constructor.
 #define LAZY_INSTANCE_INITIALIZER {0}
 
 namespace base {
@@ -134,10 +131,6 @@
         internal::ErrorMustSelectLazyOrDestructorAtExitForLazyInstance<Type>>
 class LazyInstance {
  public:
-  // kLazyInstanceInitializer shouldn't be used (it is there to absorb the
-  // LAZY_INSTANCE_INITIALIZER param when constructed with it).
-  constexpr LazyInstance(int kLazyInstanceInitializer = 0) {}
-
   // Do not define a destructor, as doing so makes LazyInstance a
   // non-POD-struct. We don't want that because then a static initializer will
   // be created to register the (empty) destructor with atexit() under MSVC, for
@@ -176,6 +169,26 @@
     return 0 != subtle::NoBarrier_Load(&private_instance_);
   }
 
+  // MSVC gives a warning that the alignment expands the size of the
+  // LazyInstance struct to make the size a multiple of the alignment. This
+  // is expected in this case.
+#if defined(OS_WIN)
+#pragma warning(push)
+#pragma warning(disable: 4324)
+#endif
+
+  // Effectively private: member data is only public to allow the linker to
+  // statically initialize it and to maintain a POD class. DO NOT USE FROM
+  // OUTSIDE THIS CLASS.
+  subtle::AtomicWord private_instance_;
+
+  // Preallocated space for the Type instance.
+  alignas(Type) char private_buf_[sizeof(Type)];
+
+#if defined(OS_WIN)
+#pragma warning(pop)
+#endif
+
  private:
   Type* instance() {
     return reinterpret_cast<Type*>(subtle::NoBarrier_Load(&private_instance_));
@@ -190,23 +203,6 @@
     Traits::Delete(me->instance());
     subtle::NoBarrier_Store(&me->private_instance_, 0);
   }
-
-// MSVC gives a warning that the alignment expands the size of the
-// LazyInstance struct to make the size a multiple of the alignment. This
-// is expected in this case.
-#if defined(COMPILER_MSVC)
-#pragma warning(push)
-#pragma warning(disable : 4324)
-#endif
-
-  subtle::AtomicWord private_instance_ = 0;
-
-  // Preallocated space for the Type instance.
-  alignas(Type) char private_buf_[sizeof(Type)] = {};
-
-#if defined(COMPILER_MSVC)
-#pragma warning(pop)
-#endif
 };
 
 }  // namespace base
diff --git a/base/lazy_instance_unittest.cc b/base/lazy_instance_unittest.cc
index 104f5f23..a5f024cf 100644
--- a/base/lazy_instance_unittest.cc
+++ b/base/lazy_instance_unittest.cc
@@ -320,17 +320,3 @@
   EXPECT_LT(base::TimeTicks::Now() - test_begin,
             base::TimeDelta::FromSeconds(5));
 }
-
-TEST(LazyInstanceTest, ConstExprConstructible) {
-  // Mostly just verifying that this compiles, the runtime test itself won't do
-  // much... Declaring the variable constexpr forces the compiler to verify that
-  // this is possible but renders the LazyInstance unusable as none of its
-  // methods are const.
-  static constexpr base::LazyInstance<SlowConstructor>
-      kTestConstExprConstructible;
-  static constexpr base::LazyInstance<SlowConstructor>
-      kTestConstExprConstructibleWithExplicitInitializer =
-          LAZY_INSTANCE_INITIALIZER;
-  ALLOW_UNUSED_LOCAL(kTestConstExprConstructible);
-  ALLOW_UNUSED_LOCAL(kTestConstExprConstructibleWithExplicitInitializer);
-}
diff --git a/base/memory/shared_memory_fuchsia.cc b/base/memory/shared_memory_fuchsia.cc
index 15211d9..a76f4f1 100644
--- a/base/memory/shared_memory_fuchsia.cc
+++ b/base/memory/shared_memory_fuchsia.cc
@@ -139,6 +139,12 @@
   SharedMemoryHandle handle(shm_);
   handle.SetOwnershipPassesToIPC(true);
   shm_ = SharedMemoryHandle();
+  // TODO(ssid): Find some way to track the shared memory in this case
+  // https://crbug/804399.
+  if (memory_) {
+    SharedMemoryTracker::GetInstance()->DecrementMemoryUsage(*this);
+    mapped_id_ = UnguessableToken();
+  }
   memory_ = nullptr;
   mapped_size_ = 0;
   return handle;
diff --git a/base/memory/shared_memory_nacl.cc b/base/memory/shared_memory_nacl.cc
index 442c0360..6ac0b3d 100644
--- a/base/memory/shared_memory_nacl.cc
+++ b/base/memory/shared_memory_nacl.cc
@@ -118,6 +118,12 @@
   SharedMemoryHandle handle_copy = shm_;
   handle_copy.SetOwnershipPassesToIPC(true);
   shm_ = SharedMemoryHandle();
+  // TODO(ssid): Find some way to track the shared memory in this case
+  // https://crbug/804399.
+  if (memory_) {
+    SharedMemoryTracker::GetInstance()->DecrementMemoryUsage(*this);
+    mapped_id_ = UnguessableToken();
+  }
   memory_ = nullptr;
   mapped_size_ = 0;
   return handle_copy;
diff --git a/base/memory/shared_memory_posix.cc b/base/memory/shared_memory_posix.cc
index f9d71f4..d9e03a0 100644
--- a/base/memory/shared_memory_posix.cc
+++ b/base/memory/shared_memory_posix.cc
@@ -336,6 +336,12 @@
 SharedMemoryHandle SharedMemory::TakeHandle() {
   SharedMemoryHandle handle_copy = shm_;
   handle_copy.SetOwnershipPassesToIPC(true);
+  // TODO(ssid): Find some way to track the shared memory in this case
+  // https://crbug/804399.
+  if (memory_) {
+    SharedMemoryTracker::GetInstance()->DecrementMemoryUsage(*this);
+    mapped_id_ = UnguessableToken();
+  }
   shm_ = SharedMemoryHandle();
   memory_ = nullptr;
   mapped_size_ = 0;
diff --git a/base/memory/shared_memory_win.cc b/base/memory/shared_memory_win.cc
index 5540004..2130218 100644
--- a/base/memory/shared_memory_win.cc
+++ b/base/memory/shared_memory_win.cc
@@ -374,6 +374,12 @@
   SharedMemoryHandle handle(shm_);
   handle.SetOwnershipPassesToIPC(true);
   shm_ = SharedMemoryHandle();
+  // TODO(ssid): Find some way to track the shared memory in this case
+  // https://crbug/804399.
+  if (memory_) {
+    SharedMemoryTracker::GetInstance()->DecrementMemoryUsage(*this);
+    mapped_id_ = UnguessableToken();
+  }
   memory_ = nullptr;
   mapped_size_ = 0;
   return handle;
diff --git a/base/trace_event/memory_infra_background_whitelist.cc b/base/trace_event/memory_infra_background_whitelist.cc
index 209eb9e..7d0ecb54 100644
--- a/base/trace_event/memory_infra_background_whitelist.cc
+++ b/base/trace_event/memory_infra_background_whitelist.cc
@@ -29,6 +29,7 @@
     "gpu::TextureManager",
     "HistoryReport",
     "IndexedDBBackingStore",
+    "InMemoryURLIndex",
     "JavaHeap",
     "LevelDB",
     "LeveldbValueStore",
@@ -164,6 +165,7 @@
     "net/url_request_context/unknown/0x?/http_cache/memory_backend",
     "net/url_request_context/unknown/0x?/http_cache/simple_backend",
     "net/url_request_context/unknown/0x?/http_network_session",
+    "omnibox/in_memory_url_index_0x?",
     "web_cache/Image_resources",
     "web_cache/CSS stylesheet_resources",
     "web_cache/Script_resources",
diff --git a/build/secondary/third_party/android_tools/BUILD.gn b/build/secondary/third_party/android_tools/BUILD.gn
index f748b40..a6246ef 100644
--- a/build/secondary/third_party/android_tools/BUILD.gn
+++ b/build/secondary/third_party/android_tools/BUILD.gn
@@ -64,38 +64,18 @@
 }
 support_lib_alias("android_support_design_java") {
 }
-support_lib_alias("android_support_fragment_java") {
-}
-support_lib_alias("android_support_media_compat_java") {
-}
-support_lib_alias("android_support_transition_java") {
-}
 support_lib_alias("android_support_v4_java") {
 }
 support_lib_alias("android_support_v7_appcompat_java") {
 }
-support_lib_alias("android_support_v7_appcompat_java_internal") {
-}
 support_lib_alias("android_support_v7_gridlayout_java") {
 }
 support_lib_alias("android_support_v7_mediarouter_java") {
 }
-support_lib_alias("android_support_v7_palette_java") {
-}
-support_lib_alias("android_support_v7_preference_java") {
-}
 support_lib_alias("android_support_v7_recyclerview_java") {
 }
 support_lib_alias("android_support_v13_java") {
 }
-support_lib_alias("android_support_v14_preference_java") {
-}
-support_lib_alias("android_support_v17_leanback_java") {
-}
-support_lib_alias("android_support_v17_preference_java") {
-}
-support_lib_alias("android_support_vector_drawable_java") {
-}
 
 # TODO(dgn): Use the POM files instead of hardcoding the dependencies.
 gms_path = "$default_extras_android_sdk_root/extras/google/m2repository/com/google/android/gms"
diff --git a/build/secondary/third_party/android_tools/support/BUILD.gn b/build/secondary/third_party/android_tools/support/BUILD.gn
index adcae68..2d8e676 100644
--- a/build/secondary/third_party/android_tools/support/BUILD.gn
+++ b/build/secondary/third_party/android_tools/support/BUILD.gn
@@ -4,10 +4,7 @@
 
 import("//build/config/android/rules.gni")
 
-visibility = [
-  ":*",
-  "//third_party/android_tools:*",
-]
+visibility = [ ":*" ]
 
 lib_version = "27.0.0"
 lib_path = "//third_party/android_tools/sdk/extras/android/m2repository/com/android/support"
@@ -19,15 +16,18 @@
 android_library("android_support_chromium_java") {
   testonly = true
   java_files = [ "//third_party/android_tools/sdk/extras/chromium/support/src/org/chromium/android/support/PackageManagerWrapper.java" ]
+  visibility += [ "//third_party/android_tools:*" ]
 }
 
 android_java_prebuilt("android_gcm_java") {
   jar_path = "//third_party/android_tools/sdk/extras/google/gcm/gcm-client/dist/gcm.jar"
+  visibility += [ "//third_party/android_tools:*" ]
 }
 
 android_java_prebuilt("emma_device_java") {
   jar_path = "//third_party/android_tools/sdk/tools/lib/emma_device.jar"
   include_java_resources = true
+  visibility += [ "//third_party/android_tools:*" ]
 }
 
 android_aar_prebuilt("android_support_design_java") {
@@ -40,6 +40,7 @@
   _lib_name = "design"
   aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar"
   info_path = "$build_file_dir/$target_name.info"
+  visibility += [ "//third_party/android_tools:*" ]
 }
 
 android_aar_prebuilt("android_support_transition_java") {
@@ -58,11 +59,13 @@
   _lib_name = "cardview-v7"
   aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar"
   info_path = "$build_file_dir/$target_name.info"
+  visibility += [ "//third_party/android_tools:*" ]
 }
 
 android_aar_prebuilt("android_support_multidex_java") {
   aar_path = "$lib_path/multidex/1.0.1/multidex-1.0.1.aar"
   info_path = "$build_file_dir/$target_name.info"
+  visibility += [ "//third_party/android_tools:*" ]
 }
 
 android_aar_prebuilt("android_arch_lifecycle_runtime_java") {
@@ -73,6 +76,7 @@
     ":android_arch_lifecycle_common_java",
     ":android_support_annotations_java",
   ]
+  visibility += [ "//third_party/android_tools:*" ]
 }
 
 android_java_prebuilt("android_arch_lifecycle_common_java") {
@@ -81,6 +85,7 @@
   deps = [
     ":android_support_annotations_java",
   ]
+  visibility += [ "//third_party/android_tools:*" ]
 }
 
 android_java_prebuilt("android_arch_core_common_java") {
@@ -94,6 +99,7 @@
 android_java_prebuilt("android_support_annotations_java") {
   _lib_name = "support-annotations"
   jar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.jar"
+  visibility += [ "//third_party/android_tools:*" ]
 }
 
 java_group("android_support_v4_java") {
@@ -104,6 +110,7 @@
     ":android_support_fragment_java",
     ":android_support_media_compat_java",
   ]
+  visibility += [ "//third_party/android_tools:*" ]
 }
 
 android_aar_prebuilt("android_support_compat_java") {
@@ -115,6 +122,7 @@
   aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar"
   info_path = "$build_file_dir/$target_name.info"
   ignore_aidl = true  # We don't appear to need these currently.
+  visibility += [ "//third_party/android_tools:*" ]
 }
 
 android_aar_prebuilt("android_support_core_ui_java") {
@@ -124,6 +132,7 @@
   _lib_name = "support-core-ui"
   aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar"
   info_path = "$build_file_dir/$target_name.info"
+  visibility += [ "//third_party/android_tools:*" ]
 }
 
 android_aar_prebuilt("android_support_core_utils_java") {
@@ -133,6 +142,7 @@
   _lib_name = "support-core-utils"
   aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar"
   info_path = "$build_file_dir/$target_name.info"
+  visibility += [ "//third_party/android_tools:*" ]
 }
 
 android_aar_prebuilt("android_support_fragment_java") {
@@ -164,6 +174,7 @@
   _lib_name = "support-v13"
   aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar"
   info_path = "$build_file_dir/$target_name.info"
+  visibility += [ "//third_party/android_tools:*" ]
 }
 
 android_aar_prebuilt("android_support_vector_drawable_java") {
@@ -201,6 +212,7 @@
     ":android_support_v7_appcompat_java_internal",
     ":android_support_vector_drawable_java",
   ]
+  visibility += [ "//third_party/android_tools:*" ]
 }
 
 android_aar_prebuilt("android_support_v7_gridlayout_java") {
@@ -211,6 +223,7 @@
   _lib_name = "gridlayout-v7"
   aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar"
   info_path = "$build_file_dir/$target_name.info"
+  visibility += [ "//third_party/android_tools:*" ]
 }
 
 android_aar_prebuilt("android_support_v7_mediarouter_java") {
@@ -221,6 +234,7 @@
   _lib_name = "mediarouter-v7"
   aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar"
   info_path = "$build_file_dir/$target_name.info"
+  visibility += [ "//third_party/android_tools:*" ]
 }
 
 android_aar_prebuilt("android_support_v7_recyclerview_java") {
@@ -232,6 +246,7 @@
   _lib_name = "recyclerview-v7"
   aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar"
   info_path = "$build_file_dir/$target_name.info"
+  visibility += [ "//third_party/android_tools:*" ]
 }
 
 android_aar_prebuilt("android_support_v7_palette_java") {
@@ -243,50 +258,3 @@
   aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar"
   info_path = "$build_file_dir/$target_name.info"
 }
-
-android_aar_prebuilt("android_support_v7_preference_java") {
-  deps = [
-    ":android_support_v4_java",
-    ":android_support_v7_appcompat_java",
-    ":android_support_v7_recyclerview_java",
-  ]
-  _lib_name = "preference-v7"
-  aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar"
-  info_path = "$build_file_dir/$target_name.info"
-}
-
-android_aar_prebuilt("android_support_v14_preference_java") {
-  deps = [
-    ":android_support_v4_java",
-    ":android_support_v7_appcompat_java",
-    ":android_support_v7_preference_java",
-    ":android_support_v7_recyclerview_java",
-  ]
-  _lib_name = "preference-v14"
-  aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar"
-  info_path = "$build_file_dir/$target_name.info"
-}
-
-android_aar_prebuilt("android_support_v17_leanback_java") {
-  deps = [
-    ":android_support_v4_java",
-    ":android_support_v7_recyclerview_java",
-  ]
-  _lib_name = "leanback-v17"
-  aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar"
-  info_path = "$build_file_dir/$target_name.info"
-}
-
-android_aar_prebuilt("android_support_v17_preference_java") {
-  deps = [
-    ":android_support_v14_preference_java",
-    ":android_support_v17_leanback_java",
-    ":android_support_v4_java",
-    ":android_support_v7_appcompat_java",
-    ":android_support_v7_preference_java",
-    ":android_support_v7_recyclerview_java",
-  ]
-  _lib_name = "preference-leanback-v17"
-  aar_path = "$lib_path/$_lib_name/$lib_version/$_lib_name-$lib_version.aar"
-  info_path = "$build_file_dir/$target_name.info"
-}
diff --git a/cc/scheduler/scheduler_state_machine.h b/cc/scheduler/scheduler_state_machine.h
index a408e30..3c763683 100644
--- a/cc/scheduler/scheduler_state_machine.h
+++ b/cc/scheduler/scheduler_state_machine.h
@@ -402,7 +402,7 @@
   bool did_submit_in_last_frame_ = false;
   bool needs_impl_side_invalidation_ = false;
   bool next_invalidation_needs_first_draw_on_activation_ = false;
-  bool should_defer_invalidation_for_fast_main_frame_ = false;
+  bool should_defer_invalidation_for_fast_main_frame_ = true;
 
   // Set to true if the main thread fails to respond with a commit or abort the
   // main frame before the draw deadline on the previous impl frame.
diff --git a/cc/scheduler/scheduler_state_machine_unittest.cc b/cc/scheduler/scheduler_state_machine_unittest.cc
index 8c4064c..aee47f6f 100644
--- a/cc/scheduler/scheduler_state_machine_unittest.cc
+++ b/cc/scheduler/scheduler_state_machine_unittest.cc
@@ -2359,6 +2359,7 @@
 
   // Since there is no main frame request, this should perform impl-side
   // invalidations.
+  state.set_should_defer_invalidation_for_fast_main_frame(false);
   state.IssueNextBeginImplFrame();
   EXPECT_ACTION_UPDATE_STATE(
       SchedulerStateMachine::Action::PERFORM_IMPL_SIDE_INVALIDATION);
diff --git a/cc/scheduler/scheduler_unittest.cc b/cc/scheduler/scheduler_unittest.cc
index d4beed80..eb35a1e 100644
--- a/cc/scheduler/scheduler_unittest.cc
+++ b/cc/scheduler/scheduler_unittest.cc
@@ -3941,5 +3941,21 @@
   EXPECT_ACTIONS("WillBeginImplFrame");
 }
 
+TEST_F(SchedulerTest, SynchronousCompositorImplSideInvalidation) {
+  // Synchronous compositor doesn't have a deadline and our heuristics can't
+  // work. We should never be prioritizing impl-side invalidations over main
+  // frames.
+  scheduler_settings_.using_synchronous_renderer_compositor = true;
+  SetUpScheduler(EXTERNAL_BFS);
+
+  fake_compositor_timing_history_->SetAllEstimatesTo(kSlowDuration);
+  scheduler_->SetNeedsBeginMainFrame();
+  const bool needs_first_draw_on_activation = true;
+  scheduler_->SetNeedsImplSideInvalidation(needs_first_draw_on_activation);
+  client_->Reset();
+  EXPECT_SCOPED(AdvanceFrame());
+  EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
+}
+
 }  // namespace
 }  // namespace cc
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/AppIndexingUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/AppIndexingUtil.java
index 41d286f..29460018 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/AppIndexingUtil.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/AppIndexingUtil.java
@@ -151,8 +151,7 @@
     }
 
     boolean isEnabledForDevice() {
-        return !SysUtils.isLowEndDevice()
-                && ChromeFeatureList.isEnabled(ChromeFeatureList.COPYLESS_PASTE);
+        return !SysUtils.isLowEndDevice();
     }
 
     private LruCache<String, CacheEntry> getPageCache() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
index 9e54027b..11f626f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
@@ -199,7 +199,6 @@
     public static final String CONTEXTUAL_SUGGESTIONS_ABOVE_ARTICLES =
             "ContextualSuggestionsAboveArticles";
     public static final String CONTEXTUAL_SUGGESTIONS_CAROUSEL = "ContextualSuggestionsCarousel";
-    public static final String COPYLESS_PASTE = "CopylessPaste";
     public static final String CUSTOM_CONTEXT_MENU = "CustomContextMenu";
     public static final String CUSTOM_FEEDBACK_UI = "CustomFeedbackUi";
     // Enables the Data Reduction Proxy menu item in the main menu rather than under Settings on
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/LocalStorageInfo.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/LocalStorageInfo.java
index 73ec1e127..5d2420a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/LocalStorageInfo.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/LocalStorageInfo.java
@@ -4,6 +4,8 @@
 
 package org.chromium.chrome.browser.preferences.website;
 
+import org.chromium.chrome.browser.preferences.website.WebsitePreferenceBridge.StorageInfoClearedCallback;
+
 import java.io.Serializable;
 
 /**
@@ -24,9 +26,10 @@
         return mOrigin;
     }
 
-    public void clear() {
+    public void clear(StorageInfoClearedCallback callback) {
+        // TODO(dullweber): Cookies should call a callback when cleared as well.
         WebsitePreferenceBridge.nativeClearCookieData(mOrigin);
-        WebsitePreferenceBridge.nativeClearLocalStorageData(mOrigin);
+        WebsitePreferenceBridge.nativeClearLocalStorageData(mOrigin, callback);
     }
 
     public long getSize() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/Website.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/Website.java
index e0a5a7d..644dd327 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/Website.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/Website.java
@@ -6,6 +6,7 @@
 
 import org.chromium.base.metrics.RecordUserAction;
 import org.chromium.chrome.browser.ContentSettingsType;
+import org.chromium.chrome.browser.preferences.website.WebsitePreferenceBridge.StorageInfoClearedCallback;
 import org.chromium.chrome.browser.util.MathUtils;
 
 import java.io.Serializable;
@@ -518,24 +519,21 @@
     }
 
     public void clearAllStoredData(final StoredDataClearedCallback callback) {
+        // Wait for callbacks from each mStorageInfo and another callback from mLocalStorageInfo.
+        mStorageInfoCallbacksLeft = mStorageInfo.size() + 1;
+        StorageInfoClearedCallback clearedCallback = () -> {
+            if (--mStorageInfoCallbacksLeft == 0) callback.onStoredDataCleared();
+        };
         if (mLocalStorageInfo != null) {
-            mLocalStorageInfo.clear();
+            mLocalStorageInfo.clear(clearedCallback);
             mLocalStorageInfo = null;
-        }
-        mStorageInfoCallbacksLeft = mStorageInfo.size();
-        if (mStorageInfoCallbacksLeft > 0) {
-            for (StorageInfo info : mStorageInfo) {
-                info.clear(new WebsitePreferenceBridge.StorageInfoClearedCallback() {
-                    @Override
-                    public void onStorageInfoCleared() {
-                        if (--mStorageInfoCallbacksLeft == 0) callback.onStoredDataCleared();
-                    }
-                });
-            }
-            mStorageInfo.clear();
         } else {
-            callback.onStoredDataCleared();
+            clearedCallback.onStorageInfoCleared();
         }
+        for (StorageInfo info : mStorageInfo) {
+            info.clear(clearedCallback);
+        }
+        mStorageInfo.clear();
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePreferenceBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePreferenceBridge.java
index 8229e379..7d28d7f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePreferenceBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePreferenceBridge.java
@@ -287,7 +287,7 @@
     static native void nativeSetCameraSettingForOrigin(
             String origin, int value, boolean isIncognito);
     static native void nativeClearCookieData(String path);
-    static native void nativeClearLocalStorageData(String path);
+    static native void nativeClearLocalStorageData(String path, Object callback);
     static native void nativeClearStorageData(String origin, int type, Object callback);
     private static native void nativeFetchLocalStorageInfo(
             Object callback, boolean includeImportant);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninView.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninView.java
index 60fc9e1..a6cc232e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninView.java
@@ -321,7 +321,7 @@
     @Override
     protected void onDetachedFromWindow() {
         if (mConfirmSyncDataStateMachine != null) {
-            mConfirmSyncDataStateMachine.cancel(false /* dismissDialogs */);
+            mConfirmSyncDataStateMachine.cancel(/* isBeingDestroyed = */ true);
             mConfirmSyncDataStateMachine = null;
         }
         mProfileDataCache.removeObserver(mProfileDataCacheObserver);
@@ -434,7 +434,7 @@
         if (selectedAccountChanged && mConfirmSyncDataStateMachine != null) {
             // Any dialogs that may have been showing are now invalid (they were created
             // for the previously selected account).
-            mConfirmSyncDataStateMachine.cancel(true /* dismissDialogs */);
+            mConfirmSyncDataStateMachine.cancel(/* isBeingDestroyed = */ false);
             mConfirmSyncDataStateMachine = null;
         }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachine.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachine.java
index 6f0150b..fc5178b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachine.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/ConfirmSyncDataStateMachine.java
@@ -112,17 +112,18 @@
 
     /**
      * Cancels this state machine, dismissing any dialogs being shown.
-     * @param dismissDialogs whether all shown dialogs should dismissed. Should be false if
-     *         enclosing activity is being destroyed (all dialogs will be dismissed anyway).
+     * @param isBeingDestroyed whether state machine is being cancelled because enclosing UI object
+     *         is being destroyed. This state machine will not invoke callbacks or dismiss dialogs
+     *         if isBeingDestroyed is true.
      */
-    public void cancel(boolean dismissDialogs) {
+    public void cancel(boolean isBeingDestroyed) {
         ThreadUtils.assertOnUiThread();
 
         cancelTimeout();
         mState = DONE;
-        mCallback.onCancel();
 
-        if (!dismissDialogs) return;
+        if (isBeingDestroyed) return;
+        mCallback.onCancel();
         mDelegate.dismissAllDialogs();
         dismissDialog(ConfirmImportSyncDataDialog.CONFIRM_IMPORT_SYNC_DATA_DIALOG_TAG);
         dismissDialog(ConfirmManagedSyncDataDialog.CONFIRM_IMPORT_SYNC_DATA_DIALOG_TAG);
@@ -272,7 +273,7 @@
     // ConfirmImportSyncDataDialog.Listener & ConfirmManagedSyncDataDialog.Listener implementation.
     @Override
     public void onCancel() {
-        cancel(true);
+        cancel(false);
     }
 }
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestExpiredLocalCardTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestExpiredLocalCardTest.java
index e3f3a54..1650dc2 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestExpiredLocalCardTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestExpiredLocalCardTest.java
@@ -15,6 +15,7 @@
 import org.junit.runner.RunWith;
 
 import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.ChromeSwitches;
@@ -137,8 +138,9 @@
     /**
      * Tests the different card unmask error messages for an expired card.
      */
-    @MediumTest
-    @Feature({"Payments"})
+    // @MediumTest
+    // @Feature({"Payments"})
+    @DisabledTest(message = "https://crbug.com/687438/")
     @Test
     public void testPromptErrorMessages()
             throws InterruptedException, ExecutionException, TimeoutException {
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index c3c9a93..49fb70c 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -4681,6 +4681,9 @@
         <message name="IDS_PASSWORD_MANAGER_ACCOUNT_CHOOSER_SIGN_IN" desc="In Title Case: The title of the Sign in button in the account chooser when there is one account.">
           Sign In
         </message>
+        <message name="IDS_PASSWORD_MANAGER_MANAGE_PASSWORDS_BUTTON" desc="In Title Case: The label of the 'Manage Passwords' button in the manage-passwords bubble.">
+          Manage Passwords
+        </message>
         <message name="IDS_PASSWORD_MANAGER_SIGNIN_PROMO_SIGN_IN" desc="In Title Case: The title of the Sign in button in the bubble promoting Chrome sign-in.">
           Sign In
         </message>
@@ -4710,6 +4713,9 @@
         <message name="IDS_PASSWORD_MANAGER_ACCOUNT_CHOOSER_SIGN_IN" desc="The title of the Sign in button in the account chooser when there is one account.">
           Sign in
         </message>
+        <message name="IDS_PASSWORD_MANAGER_MANAGE_PASSWORDS_BUTTON" desc="The label of the 'Manage passwords' link in the manage-passwords bubble.">
+          Manage passwords
+        </message>
         <message name="IDS_PASSWORD_MANAGER_SIGNIN_PROMO_SIGN_IN" desc="The title of the Sign in button in the bubble promoting Chrome sign-in.">
           Sign in
         </message>
@@ -5477,12 +5483,16 @@
         <message name="IDS_PASSWORD_MANAGER_SAVE_BUTTON" desc="Save button text for password manager">
           Save
         </message>
-        <message name="IDS_PASSWORD_MANAGER_UPDATE_BUTTON" desc="Update button text for password manager">
-          Update password
-        </message>
-        <message name="IDS_PASSWORD_MANAGER_BLACKLIST_BUTTON" desc="Button text for the 'Save Password' infobar's 'Never remember for this site' option">
-          Never for this site
-        </message>
+        <if expr="use_titlecase">
+          <message name="IDS_PASSWORD_MANAGER_UPDATE_BUTTON" desc="In Title Case: Update button text for password manager">
+            Update Password
+          </message>
+        </if>
+        <if expr="not use_titlecase">
+          <message name="IDS_PASSWORD_MANAGER_UPDATE_BUTTON" desc="Update button text for password manager">
+            Update password
+          </message>
+        </if>
         <message name="IDS_PASSWORD_MANAGER_BUBBLE_BLACKLIST_BUTTON" desc="Button text for the 'Save Password' bubble's 'Never remember for this site' option">
           Never
         </message>
@@ -9217,9 +9227,6 @@
           Password saved. View and manage saved passwords at <ph name="SAVED_PASSWORDS_LINK">$1<ex>passwords.google.com</ex></ph>
         </message>
       </if>
-      <message name="IDS_MANAGE_PASSWORDS_BUBBLE_LINK" desc="The label of the 'Manage passwords' link in the Manage Passwords bubble view">
-        Manage passwords
-      </message>
       <message name="IDS_MANAGE_PASSWORDS_LINK" desc="The text for a link to the user's saved passwords. This is inserted into an infobar or a bubble that the browser shows to the user. The infobar and the bubble use a separate string in the translation console that has a placeholder for this link title.">
         Google saved passwords
       </message>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index efac2a7e..0ec9e3de 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -3129,12 +3129,6 @@
          chromeos::switches::kDisableZipArchiverUnpacker)},
 #endif  // OS_CHROMEOS
 
-#if defined(OS_ANDROID)
-    {"enable-copyless-paste", flag_descriptions::kEnableCopylessPasteName,
-     flag_descriptions::kEnableCopylessPasteDescription, kOsAndroid,
-     FEATURE_VALUE_TYPE(features::kCopylessPaste)},
-#endif
-
     {"omnibox-display-title-for-current-url",
      flag_descriptions::kOmniboxDisplayTitleForCurrentUrlName,
      flag_descriptions::kOmniboxDisplayTitleForCurrentUrlDescription, kOsAll,
@@ -3697,6 +3691,13 @@
      flag_descriptions::kAshEnableNewOverviewUiName,
      flag_descriptions::kAshEnableNewOverviewUiDescription, kOsCrOS,
      SINGLE_VALUE_TYPE(ash::switches::kAshEnableNewOverviewUi)},
+
+    {"ash-new-touch-support-for-screen-magnification",
+     flag_descriptions::kAshNewTouchSupportForScreenMagnificationName,
+     flag_descriptions::kAshNewTouchSupportForScreenMagnificationDescription,
+     kOsCrOS,
+     SINGLE_VALUE_TYPE(
+         ash::switches::kAshNewTouchSupportForScreenMagnification)},
 #endif  // defined(OS_CHROMEOS)
 
     {"unified-consent", flag_descriptions::kUnifiedConsentName,
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc
index 83076e9..9ee9a98 100644
--- a/chrome/browser/android/chrome_feature_list.cc
+++ b/chrome/browser/android/chrome_feature_list.cc
@@ -43,7 +43,6 @@
     &autofill::kAutofillScanCardholderName,
     &features::kClearOldBrowsingData,
     &features::kClipboardContentSetting,
-    &features::kCopylessPaste,
     &features::kDownloadsForeground,
     &features::kDownloadsLocationChange,
     &features::kImportantSitesInCbd,
diff --git a/chrome/browser/android/preferences/website_preference_bridge.cc b/chrome/browser/android/preferences/website_preference_bridge.cc
index 944576f..4a41ebb3 100644
--- a/chrome/browser/android/preferences/website_preference_bridge.cc
+++ b/chrome/browser/android/preferences/website_preference_bridge.cc
@@ -707,6 +707,13 @@
   base::android::RunCallbackAndroid(java_callback, list);
 }
 
+void OnLocalStorageCleared(const ScopedJavaGlobalRef<jobject>& java_callback) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+  Java_StorageInfoClearedCallback_onStorageInfoCleared(
+      base::android::AttachCurrentThread(), java_callback);
+}
+
 void OnStorageInfoCleared(const ScopedJavaGlobalRef<jobject>& java_callback,
                           blink::mojom::QuotaStatusCode code) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -810,12 +817,15 @@
 static void JNI_WebsitePreferenceBridge_ClearLocalStorageData(
     JNIEnv* env,
     const JavaParamRef<jclass>& clazz,
-    const JavaParamRef<jstring>& jorigin) {
+    const JavaParamRef<jstring>& jorigin,
+    const JavaParamRef<jobject>& java_callback) {
   Profile* profile = ProfileManager::GetActiveUserProfile();
   auto local_storage_helper =
       base::MakeRefCounted<BrowsingDataLocalStorageHelper>(profile);
   GURL origin_url = GURL(ConvertJavaStringToUTF8(env, jorigin));
-  local_storage_helper->DeleteOrigin(origin_url);
+  local_storage_helper->DeleteOrigin(
+      origin_url, base::BindOnce(&OnLocalStorageCleared,
+                                 ScopedJavaGlobalRef<jobject>(java_callback)));
 }
 
 static void JNI_WebsitePreferenceBridge_ClearStorageData(
diff --git a/chrome/browser/banners/app_banner_settings_helper.cc b/chrome/browser/banners/app_banner_settings_helper.cc
index f500252..121152e 100644
--- a/chrome/browser/banners/app_banner_settings_helper.cc
+++ b/chrome/browser/banners/app_banner_settings_helper.cc
@@ -71,7 +71,7 @@
 unsigned int gDaysAfterDismissedToShow = kMinimumBannerBlockedToBannerShown;
 unsigned int gDaysAfterIgnoredToShow = kMinimumDaysBetweenBannerShows;
 
-std::unique_ptr<base::DictionaryValue> GetOriginDict(
+std::unique_ptr<base::DictionaryValue> GetOriginAppBannerData(
     HostContentSettingsMap* settings,
     const GURL& origin_url) {
   if (!settings)
@@ -223,7 +223,7 @@
   HostContentSettingsMap* settings =
       HostContentSettingsMapFactory::GetForProfile(profile);
   std::unique_ptr<base::DictionaryValue> origin_dict =
-      GetOriginDict(settings, origin_url);
+      GetOriginAppBannerData(settings, origin_url);
   if (!origin_dict)
     return;
 
@@ -306,7 +306,7 @@
   HostContentSettingsMap* settings =
       HostContentSettingsMapFactory::GetForProfile(profile);
   std::unique_ptr<base::DictionaryValue> origin_dict =
-      GetOriginDict(settings, origin_url);
+      GetOriginAppBannerData(settings, origin_url);
 
   if (!origin_dict)
     return base::Time();
@@ -352,7 +352,7 @@
   HostContentSettingsMap* settings =
       HostContentSettingsMapFactory::GetForProfile(profile);
   std::unique_ptr<base::DictionaryValue> origin_dict =
-      GetOriginDict(settings, origin_url);
+      GetOriginAppBannerData(settings, origin_url);
 
   if (!origin_dict)
     return false;
diff --git a/chrome/browser/browsing_data/browsing_data_local_storage_helper.cc b/chrome/browser/browsing_data/browsing_data_local_storage_helper.cc
index bcfe7614..ca7a7f5b 100644
--- a/chrome/browser/browsing_data/browsing_data_local_storage_helper.cc
+++ b/chrome/browser/browsing_data/browsing_data_local_storage_helper.cc
@@ -74,9 +74,11 @@
       base::Bind(&GetUsageInfoCallback, callback));
 }
 
-void BrowsingDataLocalStorageHelper::DeleteOrigin(const GURL& origin_url) {
+void BrowsingDataLocalStorageHelper::DeleteOrigin(const GURL& origin_url,
+                                                  base::OnceClosure callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  dom_storage_context_->DeleteLocalStorageForPhysicalOrigin(origin_url);
+  dom_storage_context_->DeleteLocalStorageForPhysicalOrigin(
+      origin_url, std::move(callback));
 }
 
 //---------------------------------------------------------
@@ -130,13 +132,14 @@
 }
 
 void CannedBrowsingDataLocalStorageHelper::DeleteOrigin(
-    const GURL& origin_url) {
+    const GURL& origin_url,
+    base::OnceClosure callback) {
   pending_local_storage_info_.erase(origin_url);
   // All suborigins associated with |origin_url| must be removed.
   // BrowsingDataLocalStorageHelper::DeleteOrigin takes care of doing that on
   // the backend so it's not necessary to call it for each suborigin, but it is
   // necessary to clear up the pending storage here.
-  BrowsingDataLocalStorageHelper::DeleteOrigin(origin_url);
+  BrowsingDataLocalStorageHelper::DeleteOrigin(origin_url, std::move(callback));
   if (pending_origins_to_pending_suborigins_.count(origin_url) > 0) {
     auto it = pending_origins_to_pending_suborigins_.find(origin_url);
     while (it != pending_origins_to_pending_suborigins_.end()) {
diff --git a/chrome/browser/browsing_data/browsing_data_local_storage_helper.h b/chrome/browser/browsing_data/browsing_data_local_storage_helper.h
index f9c976b..d8b3bdb5 100644
--- a/chrome/browser/browsing_data/browsing_data_local_storage_helper.h
+++ b/chrome/browser/browsing_data/browsing_data_local_storage_helper.h
@@ -48,8 +48,10 @@
   // callback. This must be called only in the UI thread.
   virtual void StartFetching(const FetchCallback& callback);
 
-  // Deletes the local storage for the |origin_url|.
-  virtual void DeleteOrigin(const GURL& origin_url);
+  // Deletes the local storage for the |origin_url|. |callback| is called when
+  // the deletion is sent to the database and |StartFetching()| doesn't return
+  // entries for |origin_url| anymore.
+  virtual void DeleteOrigin(const GURL& origin_url, base::OnceClosure callback);
 
  protected:
   friend class base::RefCounted<BrowsingDataLocalStorageHelper>;
@@ -87,7 +89,8 @@
 
   // BrowsingDataLocalStorageHelper implementation.
   void StartFetching(const FetchCallback& callback) override;
-  void DeleteOrigin(const GURL& origin_url) override;
+  void DeleteOrigin(const GURL& origin_url,
+                    base::OnceClosure callback) override;
 
  private:
   ~CannedBrowsingDataLocalStorageHelper() override;
diff --git a/chrome/browser/browsing_data/browsing_data_local_storage_helper_browsertest.cc b/chrome/browser/browsing_data/browsing_data_local_storage_helper_browsertest.cc
index e7dcdd1..df5a742 100644
--- a/chrome/browser/browsing_data/browsing_data_local_storage_helper_browsertest.cc
+++ b/chrome/browser/browsing_data/browsing_data_local_storage_helper_browsertest.cc
@@ -126,8 +126,10 @@
   scoped_refptr<BrowsingDataLocalStorageHelper> local_storage_helper(
       new BrowsingDataLocalStorageHelper(browser()->profile()));
   CreateLocalStorageFilesForTest();
-  local_storage_helper->DeleteOrigin(GURL(kOriginOfTestFile0));
-  content::RunAllTasksUntilIdle();
+  base::RunLoop run_loop;
+  local_storage_helper->DeleteOrigin(GURL(kOriginOfTestFile0),
+                                     run_loop.QuitClosure());
+  run_loop.Run();
 
   // Ensure the file has been deleted.
   base::ScopedAllowBlockingForTesting allow_blocking;
diff --git a/chrome/browser/browsing_data/browsing_data_local_storage_helper_unittest.cc b/chrome/browser/browsing_data/browsing_data_local_storage_helper_unittest.cc
index d5043e0..c97a526 100644
--- a/chrome/browser/browsing_data/browsing_data_local_storage_helper_unittest.cc
+++ b/chrome/browser/browsing_data/browsing_data_local_storage_helper_unittest.cc
@@ -44,9 +44,9 @@
   helper->AddLocalStorage(origin2);
   helper->AddLocalStorage(origin3);
   EXPECT_EQ(3u, helper->GetLocalStorageCount());
-  helper->DeleteOrigin(origin2);
+  helper->DeleteOrigin(origin2, base::BindOnce(&base::DoNothing));
   EXPECT_EQ(2u, helper->GetLocalStorageCount());
-  helper->DeleteOrigin(origin1);
+  helper->DeleteOrigin(origin1, base::BindOnce(&base::DoNothing));
   EXPECT_EQ(1u, helper->GetLocalStorageCount());
 
   // Local storage for a suborigin
@@ -55,11 +55,11 @@
   const GURL suborigin_on_origin_3("http-so://suborigin.foo.example.com");
   helper->AddLocalStorage(suborigin_on_origin_3);
   EXPECT_EQ(2u, helper->GetLocalStorageCount());
-  helper->DeleteOrigin(origin3);
+  helper->DeleteOrigin(origin3, base::BindOnce(&base::DoNothing));
   EXPECT_EQ(0u, helper->GetLocalStorageCount());
   helper->AddLocalStorage(suborigin_on_origin_3);
   EXPECT_EQ(1u, helper->GetLocalStorageCount());
-  helper->DeleteOrigin(origin3);
+  helper->DeleteOrigin(origin3, base::BindOnce(&base::DoNothing));
   EXPECT_EQ(0u, helper->GetLocalStorageCount());
 
   // Similarly, the suborigin should be deleted when the corresponding
@@ -67,7 +67,7 @@
   helper->AddLocalStorage(origin3);
   helper->AddLocalStorage(suborigin_on_origin_3);
   EXPECT_EQ(2u, helper->GetLocalStorageCount());
-  helper->DeleteOrigin(suborigin_on_origin_3);
+  helper->DeleteOrigin(suborigin_on_origin_3, base::BindOnce(&base::DoNothing));
   EXPECT_EQ(0u, helper->GetLocalStorageCount());
 }
 
diff --git a/chrome/browser/browsing_data/cookies_tree_model.cc b/chrome/browser/browsing_data/cookies_tree_model.cc
index 28041e4..0aad4e1 100644
--- a/chrome/browser/browsing_data/cookies_tree_model.cc
+++ b/chrome/browser/browsing_data/cookies_tree_model.cc
@@ -411,7 +411,7 @@
 
   if (container) {
     container->local_storage_helper_->DeleteOrigin(
-        local_storage_info_->origin_url);
+        local_storage_info_->origin_url, base::BindOnce(&base::DoNothing));
     container->local_storage_info_list_.erase(local_storage_info_);
   }
 }
diff --git a/chrome/browser/browsing_data/mock_browsing_data_local_storage_helper.cc b/chrome/browser/browsing_data/mock_browsing_data_local_storage_helper.cc
index e97a8ff3..c61b3a8 100644
--- a/chrome/browser/browsing_data/mock_browsing_data_local_storage_helper.cc
+++ b/chrome/browser/browsing_data/mock_browsing_data_local_storage_helper.cc
@@ -25,11 +25,13 @@
 }
 
 void MockBrowsingDataLocalStorageHelper::DeleteOrigin(
-    const GURL& origin) {
+    const GURL& origin,
+    base::OnceClosure callback) {
   ASSERT_FALSE(callback_.is_null());
   ASSERT_TRUE(base::ContainsKey(origins_, origin));
   last_deleted_origin_ = origin;
   origins_[origin] = false;
+  std::move(callback).Run();
 }
 
 void MockBrowsingDataLocalStorageHelper::AddLocalStorageSamples() {
diff --git a/chrome/browser/browsing_data/mock_browsing_data_local_storage_helper.h b/chrome/browser/browsing_data/mock_browsing_data_local_storage_helper.h
index 085fd7d..1c8d844 100644
--- a/chrome/browser/browsing_data/mock_browsing_data_local_storage_helper.h
+++ b/chrome/browser/browsing_data/mock_browsing_data_local_storage_helper.h
@@ -22,7 +22,7 @@
 
   // BrowsingDataLocalStorageHelper implementation.
   void StartFetching(const FetchCallback& callback) override;
-  void DeleteOrigin(const GURL& origin) override;
+  void DeleteOrigin(const GURL& origin, base::OnceClosure callback) override;
 
   // Adds some LocalStorageInfo samples.
   void AddLocalStorageSamples();
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index 179ee010..6f49f98 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -648,6 +648,18 @@
   }
 };
 
+// Check if the policy to allow WebDriver to override Site Isolation is set and
+// if the user actually wants to use WebDriver which will cause us to skip
+// even checking if Site Isolation should be turned on by policy.
+bool IsWebDriverOverridingPolicy(PrefService* local_state) {
+  auto* command_line = base::CommandLine::ForCurrentProcess();
+  return (!command_line->HasSwitch(switches::kEnableAutomation) ||
+          !(local_state->IsManagedPreference(
+                prefs::kWebDriverOverridesIncompatiblePolicies) &&
+            local_state->GetBoolean(
+                prefs::kWebDriverOverridesIncompatiblePolicies)));
+}
+
 }  // namespace
 
 namespace chrome_browser {
@@ -1194,19 +1206,21 @@
   // tasks.
   SetupFieldTrials();
 
-  // Add Site Isolation switches as dictated by policy.
-  auto* command_line = base::CommandLine::ForCurrentProcess();
-  if (local_state->GetBoolean(prefs::kSitePerProcess) &&
-      !command_line->HasSwitch(switches::kSitePerProcess)) {
-    command_line->AppendSwitch(switches::kSitePerProcess);
-  }
-  // We don't check for `HasSwitch` here, because we don't want the command-line
-  // switch to take precedence over enterprise policy. (This behavior is in
-  // harmony with other enterprise policy settings.)
-  if (local_state->HasPrefPath(prefs::kIsolateOrigins)) {
-    command_line->AppendSwitchASCII(
-        switches::kIsolateOrigins,
-        local_state->GetString(prefs::kIsolateOrigins));
+  if (IsWebDriverOverridingPolicy(local_state)) {
+    auto* command_line = base::CommandLine::ForCurrentProcess();
+    // Add Site Isolation switches as dictated by policy.
+    if (local_state->GetBoolean(prefs::kSitePerProcess) &&
+        !command_line->HasSwitch(switches::kSitePerProcess)) {
+      command_line->AppendSwitch(switches::kSitePerProcess);
+    }
+    // We don't check for `HasSwitch` here, because we don't want the command-
+    // line switch to take precedence over enterprise policy. (This behavior is
+    // in harmony with other enterprise policy settings.)
+    if (local_state->HasPrefPath(prefs::kIsolateOrigins)) {
+      command_line->AppendSwitchASCII(
+          switches::kIsolateOrigins,
+          local_state->GetString(prefs::kIsolateOrigins));
+    }
   }
 
   // ChromeOS needs ui::ResourceBundle::InitSharedInstance to be called before
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 9ecce3f7..2fb552e 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -848,6 +848,8 @@
     PrefRegistrySimple* registry) {
   registry->RegisterStringPref(prefs::kIsolateOrigins, std::string());
   registry->RegisterBooleanPref(prefs::kSitePerProcess, false);
+  registry->RegisterBooleanPref(prefs::kWebDriverOverridesIncompatiblePolicies,
+                                false);
 #if defined(OS_WIN)
   // TODO(chrisha): Move this to chrome/browser/conflicts as we build the
   // logic that responds to this pref.
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index a3488af964..ac6a401 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -1098,8 +1098,6 @@
     "login/ui/login_display.h",
     "login/ui/login_display_host.cc",
     "login/ui/login_display_host.h",
-    "login/ui/login_display_host_common.cc",
-    "login/ui/login_display_host_common.h",
     "login/ui/login_display_host_views.cc",
     "login/ui/login_display_host_views.h",
     "login/ui/login_display_host_webui.cc",
diff --git a/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc b/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc
index 94e54d4..8fddb4d 100644
--- a/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc
+++ b/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc
@@ -114,32 +114,17 @@
   chromeos::WizardController* GetWizardController() override {
     return wizard_controller_.get();
   }
-  chromeos::AppLaunchController* GetAppLaunchController() override {
-    return nullptr;
-  }
   void StartUserAdding(base::OnceClosure completion_callback) override {}
   void CancelUserAdding() override {}
-  void StartSignInScreen(const chromeos::LoginScreenContext& context) override {
-  }
+  void OnStartSignInScreen(
+      const chromeos::LoginScreenContext& context) override {}
   void OnPreferencesChanged() override {}
-  void PrewarmAuthentication() override {}
-  void StartAppLaunch(const std::string& app_id,
-                      bool diagnostic_mode,
-                      bool is_auto_launch) override {}
-  void StartDemoAppLaunch() override {}
-  void StartArcKiosk(const AccountId& account_id) override {}
+  void OnStartAppLaunch() override {}
+  void OnStartArcKiosk() override {}
   void StartVoiceInteractionOobe() override {
     is_voice_interaction_oobe_ = true;
   }
   bool IsVoiceInteractionOobe() override { return is_voice_interaction_oobe_; }
-  void CompleteLogin(const chromeos::UserContext& user_context) override {}
-  void OnGaiaScreenReady() override {}
-  void SetDisplayEmail(const std::string& email) override {}
-  void SetDisplayAndGivenName(const std::string& display_name,
-                              const std::string& given_name) override {}
-  void LoadWallpaper(const AccountId& account_id) override {}
-  void LoadSigninWallpaper() override {}
-  bool IsUserWhitelisted(const AccountId& account_id) override { return false; }
 
  private:
   bool is_voice_interaction_oobe_ = false;
diff --git a/chrome/browser/chromeos/login/ui/login_display_host.cc b/chrome/browser/chromeos/login/ui/login_display_host.cc
index ad99f23..daeb633 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host.cc
+++ b/chrome/browser/chromeos/login/ui/login_display_host.cc
@@ -16,11 +16,19 @@
 #include "chrome/browser/chromeos/system/device_disabling_manager.h"
 
 namespace chromeos {
+namespace {
+
+// The delay of triggering initialization of the device policy subsystem
+// after the login screen is initialized. This makes sure that device policy
+// network requests are made while the system is idle waiting for user input.
+constexpr int64_t kPolicyServiceInitializationDelayMilliseconds = 100;
+
+}  // namespace
 
 // static
 LoginDisplayHost* LoginDisplayHost::default_host_ = nullptr;
 
-LoginDisplayHost::LoginDisplayHost() {
+LoginDisplayHost::LoginDisplayHost() : weak_factory_(this) {
   DCHECK(default_host() == nullptr);
   default_host_ = this;
 }
@@ -29,4 +37,150 @@
   default_host_ = nullptr;
 }
 
+AppLaunchController* LoginDisplayHost::GetAppLaunchController() {
+  return app_launch_controller_.get();
+}
+
+void LoginDisplayHost::StartSignInScreen(const LoginScreenContext& context) {
+  PrewarmAuthentication();
+
+  const user_manager::UserList& users =
+      user_manager::UserManager::Get()->GetUsers();
+
+  // Fix for users who updated device and thus never passed register screen.
+  // If we already have users, we assume that it is not a second part of
+  // OOBE. See http://crosbug.com/6289
+  if (!StartupUtils::IsDeviceRegistered() && !users.empty()) {
+    VLOG(1) << "Mark device registered because there are remembered users: "
+            << users.size();
+    StartupUtils::MarkDeviceRegistered(base::OnceClosure());
+  }
+
+  // Initiate mobile config load.
+  MobileConfig::GetInstance();
+
+  // Initiate device policy fetching.
+  policy::BrowserPolicyConnectorChromeOS* connector =
+      g_browser_process->platform_part()->browser_policy_connector_chromeos();
+  connector->ScheduleServiceInitialization(
+      kPolicyServiceInitializationDelayMilliseconds);
+
+  // Run UI-specific logic.
+  OnStartSignInScreen(context);
+
+  // Enable status area after starting sign-in screen, as it may depend on the
+  // UI being visible.
+  SetStatusAreaVisible(true);
+}
+
+void LoginDisplayHost::PrewarmAuthentication() {
+  auth_prewarmer_ = std::make_unique<AuthPrewarmer>();
+  auth_prewarmer_->PrewarmAuthentication(base::BindOnce(
+      &LoginDisplayHost::OnAuthPrewarmDone, weak_factory_.GetWeakPtr()));
+}
+
+void LoginDisplayHost::StartAppLaunch(const std::string& app_id,
+                                      bool diagnostic_mode,
+                                      bool is_auto_launch) {
+  VLOG(1) << "Login >> start app launch.";
+  SetStatusAreaVisible(false);
+
+  // Wait for the |CrosSettings| to become either trusted or permanently
+  // untrusted.
+  const CrosSettingsProvider::TrustedStatus status =
+      CrosSettings::Get()->PrepareTrustedValues(base::Bind(
+          &LoginDisplayHost::StartAppLaunch, weak_factory_.GetWeakPtr(), app_id,
+          diagnostic_mode, is_auto_launch));
+  if (status == CrosSettingsProvider::TEMPORARILY_UNTRUSTED)
+    return;
+
+  if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
+    // If the |CrosSettings| are permanently untrusted, refuse to launch a
+    // single-app kiosk mode session.
+    LOG(ERROR) << "Login >> Refusing to launch single-app kiosk mode.";
+    SetStatusAreaVisible(true);
+    return;
+  }
+
+  if (system::DeviceDisablingManager::IsDeviceDisabledDuringNormalOperation()) {
+    // If the device is disabled, bail out. A device disabled screen will be
+    // shown by the DeviceDisablingManager.
+    return;
+  }
+
+  OnStartAppLaunch();
+
+  app_launch_controller_ = std::make_unique<AppLaunchController>(
+      app_id, diagnostic_mode, this, GetOobeUI());
+
+  app_launch_controller_->StartAppLaunch(is_auto_launch);
+}
+
+void LoginDisplayHost::StartDemoAppLaunch() {
+  VLOG(1) << "Login >> starting demo app.";
+  SetStatusAreaVisible(false);
+
+  demo_app_launcher_ = std::make_unique<DemoAppLauncher>();
+  demo_app_launcher_->StartDemoAppLaunch();
+}
+
+void LoginDisplayHost::StartArcKiosk(const AccountId& account_id) {
+  VLOG(1) << "Login >> start ARC kiosk.";
+  SetStatusAreaVisible(false);
+  arc_kiosk_controller_ =
+      std::make_unique<ArcKioskController>(this, GetOobeUI());
+  arc_kiosk_controller_->StartArcKiosk(account_id);
+
+  OnStartArcKiosk();
+}
+
+void LoginDisplayHost::OnAuthPrewarmDone() {
+  auth_prewarmer_.reset();
+}
+
+void LoginDisplayHost::CompleteLogin(const UserContext& user_context) {
+  ExistingUserController* controller =
+      ExistingUserController::current_controller();
+  if (controller)
+    controller->CompleteLogin(user_context);
+}
+
+void LoginDisplayHost::OnGaiaScreenReady() {
+  ExistingUserController* controller =
+      ExistingUserController::current_controller();
+  if (controller)
+    controller->OnGaiaScreenReady();
+}
+
+void LoginDisplayHost::SetDisplayEmail(const std::string& email) {
+  ExistingUserController* controller =
+      ExistingUserController::current_controller();
+  if (controller)
+    controller->SetDisplayEmail(email);
+}
+
+void LoginDisplayHost::SetDisplayAndGivenName(const std::string& display_name,
+                                              const std::string& given_name) {
+  ExistingUserController* controller =
+      ExistingUserController::current_controller();
+  if (controller)
+    controller->SetDisplayAndGivenName(display_name, given_name);
+}
+
+void LoginDisplayHost::LoadWallpaper(const AccountId& account_id) {
+  WallpaperManager::Get()->ShowUserWallpaper(account_id);
+}
+
+void LoginDisplayHost::LoadSigninWallpaper() {
+  WallpaperManager::Get()->ShowSigninWallpaper();
+}
+
+bool LoginDisplayHost::IsUserWhitelisted(const AccountId& account_id) {
+  ExistingUserController* controller =
+      ExistingUserController::current_controller();
+  if (!controller)
+    return true;
+  return controller->IsUserWhitelisted(account_id);
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/ui/login_display_host.h b/chrome/browser/chromeos/login/ui/login_display_host.h
index 98446cb..154655d 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host.h
+++ b/chrome/browser/chromeos/login/ui/login_display_host.h
@@ -20,35 +20,25 @@
 
 namespace chromeos {
 
+class ArcKioskController;
 class AppLaunchController;
+class DemoAppLauncher;
 class LoginScreenContext;
 class OobeUI;
 class WebUILoginView;
 class WizardController;
 
-// An interface that defines an out-of-box-experience (OOBE) or login screen
-// host. It contains code specific to the login UI implementation.
-//
-// The inheritance graph is as folllows:
-//
-//                               LoginDisplayHost
-//                                   /       |
-//                LoginDisplayHostCommon   MockLoginDisplayHost
-//                      /      |
-//   LoginDisplayHostViews   LoginDisplayHostWebUI
-//
-//
-// - LoginDisplayHost defines the generic interface.
-// - LoginDisplayHostCommon is UI-agnostic code shared between the views and
-//   webui hosts.
-// - MockLoginDisplayHost is for tests.
-// - LoginDisplayHostViews is for the login screen, which is written in views.
-// - LoginDisplayHostWebUI is for OOBE, which is written in HTML/JS/CSS.
+// An interface that defines OOBE/login screen host.
+// Host encapsulates WebUI window OOBE/login controllers,
+// UI implementation (such as LoginDisplay).
 class LoginDisplayHost {
  public:
   // Returns the default LoginDisplayHost instance if it has been created.
   static LoginDisplayHost* default_host() { return default_host_; }
 
+  LoginDisplayHost();
+  virtual ~LoginDisplayHost();
+
   // Creates UI implementation specific login display instance (views/WebUI).
   // The caller takes ownership of the returned value.
   virtual LoginDisplay* CreateLoginDisplay(
@@ -85,7 +75,7 @@
 
   // Returns current AppLaunchController, if it exists.
   // Result should not be stored.
-  virtual AppLaunchController* GetAppLaunchController() = 0;
+  AppLaunchController* GetAppLaunchController();
 
   // Starts screen for adding user into session.
   // |completion_callback| is invoked after login display host shutdown.
@@ -96,25 +86,25 @@
   virtual void CancelUserAdding() = 0;
 
   // Starts sign in screen.
-  virtual void StartSignInScreen(const LoginScreenContext& context) = 0;
+  void StartSignInScreen(const LoginScreenContext& context);
 
   // Invoked when system preferences that affect the signin screen have changed.
   virtual void OnPreferencesChanged() = 0;
 
   // Initiates authentication network prewarming.
-  virtual void PrewarmAuthentication() = 0;
+  void PrewarmAuthentication();
 
   // Starts app launch splash screen. If |is_auto_launch| is true, the app is
   // being auto-launched with no delay.
-  virtual void StartAppLaunch(const std::string& app_id,
-                              bool diagnostic_mode,
-                              bool is_auto_launch) = 0;
+  void StartAppLaunch(const std::string& app_id,
+                      bool diagnostic_mode,
+                      bool is_auto_launch);
 
   // Starts the demo app launch.
-  virtual void StartDemoAppLaunch() = 0;
+  void StartDemoAppLaunch();
 
   // Starts ARC kiosk splash screen.
-  virtual void StartArcKiosk(const AccountId& account_id) = 0;
+  void StartArcKiosk(const AccountId& account_id);
 
   // Start voice interaction OOBE.
   virtual void StartVoiceInteractionOobe() = 0;
@@ -124,38 +114,56 @@
 
   // Confirms sign in by provided credentials in |user_context|.
   // Used for new user login via GAIA extension.
-  virtual void CompleteLogin(const UserContext& user_context) = 0;
+  void CompleteLogin(const UserContext& user_context);
 
   // Notify the backend controller when the GAIA UI is finished loading.
-  virtual void OnGaiaScreenReady() = 0;
+  void OnGaiaScreenReady();
 
   // Sets the displayed email for the next login attempt. If it succeeds,
   // user's displayed email value will be updated to |email|.
-  virtual void SetDisplayEmail(const std::string& email) = 0;
+  void SetDisplayEmail(const std::string& email);
 
   // Sets the displayed name and given name for the next login attempt. If it
   // succeeds, user's displayed name and give name values will be updated to
   // |display_name| and |given_name|.
-  virtual void SetDisplayAndGivenName(const std::string& display_name,
-                                      const std::string& given_name) = 0;
+  void SetDisplayAndGivenName(const std::string& display_name,
+                              const std::string& given_name);
 
   // Load wallpaper for given |account_id|.
-  virtual void LoadWallpaper(const AccountId& account_id) = 0;
+  void LoadWallpaper(const AccountId& account_id);
 
   // Loads the default sign-in wallpaper.
-  virtual void LoadSigninWallpaper() = 0;
+  void LoadSigninWallpaper();
 
   // Returns true if user is allowed to log in by domain policy.
-  virtual bool IsUserWhitelisted(const AccountId& account_id) = 0;
+  bool IsUserWhitelisted(const AccountId& account_id);
 
  protected:
-  LoginDisplayHost();
-  virtual ~LoginDisplayHost();
+  virtual void OnStartSignInScreen(const LoginScreenContext& context) = 0;
+  virtual void OnStartAppLaunch() = 0;
+  virtual void OnStartArcKiosk() = 0;
+
+  // Deletes |auth_prewarmer_|.
+  void OnAuthPrewarmDone();
+
+  // Active instance of authentication prewarmer.
+  std::unique_ptr<AuthPrewarmer> auth_prewarmer_;
+
+  // App launch controller.
+  std::unique_ptr<AppLaunchController> app_launch_controller_;
+
+  // Demo app launcher.
+  std::unique_ptr<DemoAppLauncher> demo_app_launcher_;
+
+  // ARC kiosk controller.
+  std::unique_ptr<ArcKioskController> arc_kiosk_controller_;
 
  private:
   // Global LoginDisplayHost instance.
   static LoginDisplayHost* default_host_;
 
+  base::WeakPtrFactory<LoginDisplayHost> weak_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(LoginDisplayHost);
 };
 
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_common.cc b/chrome/browser/chromeos/login/ui/login_display_host_common.cc
deleted file mode 100644
index 3f3f3a0..0000000
--- a/chrome/browser/chromeos/login/ui/login_display_host_common.cc
+++ /dev/null
@@ -1,180 +0,0 @@
-// 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 "chrome/browser/chromeos/login/ui/login_display_host_common.h"
-
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/chromeos/login/app_launch_controller.h"
-#include "chrome/browser/chromeos/login/arc_kiosk_controller.h"
-#include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
-#include "chrome/browser/chromeos/login/existing_user_controller.h"
-#include "chrome/browser/chromeos/login/startup_utils.h"
-#include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h"
-#include "chrome/browser/chromeos/mobile_config.h"
-#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
-#include "chrome/browser/chromeos/system/device_disabling_manager.h"
-
-namespace chromeos {
-namespace {
-
-// The delay of triggering initialization of the device policy subsystem
-// after the login screen is initialized. This makes sure that device policy
-// network requests are made while the system is idle waiting for user input.
-constexpr int64_t kPolicyServiceInitializationDelayMilliseconds = 100;
-
-}  // namespace
-
-LoginDisplayHostCommon::LoginDisplayHostCommon() : weak_factory_(this) {}
-
-LoginDisplayHostCommon::~LoginDisplayHostCommon() {}
-
-AppLaunchController* LoginDisplayHostCommon::GetAppLaunchController() {
-  return app_launch_controller_.get();
-}
-
-void LoginDisplayHostCommon::StartSignInScreen(
-    const LoginScreenContext& context) {
-  PrewarmAuthentication();
-
-  const user_manager::UserList& users =
-      user_manager::UserManager::Get()->GetUsers();
-
-  // Fix for users who updated device and thus never passed register screen.
-  // If we already have users, we assume that it is not a second part of
-  // OOBE. See http://crosbug.com/6289
-  if (!StartupUtils::IsDeviceRegistered() && !users.empty()) {
-    VLOG(1) << "Mark device registered because there are remembered users: "
-            << users.size();
-    StartupUtils::MarkDeviceRegistered(base::OnceClosure());
-  }
-
-  // Initiate mobile config load.
-  MobileConfig::GetInstance();
-
-  // Initiate device policy fetching.
-  policy::BrowserPolicyConnectorChromeOS* connector =
-      g_browser_process->platform_part()->browser_policy_connector_chromeos();
-  connector->ScheduleServiceInitialization(
-      kPolicyServiceInitializationDelayMilliseconds);
-
-  // Run UI-specific logic.
-  OnStartSignInScreen(context);
-
-  // Enable status area after starting sign-in screen, as it may depend on the
-  // UI being visible.
-  SetStatusAreaVisible(true);
-}
-
-void LoginDisplayHostCommon::PrewarmAuthentication() {
-  auth_prewarmer_ = std::make_unique<AuthPrewarmer>();
-  auth_prewarmer_->PrewarmAuthentication(base::BindOnce(
-      &LoginDisplayHostCommon::OnAuthPrewarmDone, weak_factory_.GetWeakPtr()));
-}
-
-void LoginDisplayHostCommon::StartAppLaunch(const std::string& app_id,
-                                            bool diagnostic_mode,
-                                            bool is_auto_launch) {
-  VLOG(1) << "Login >> start app launch.";
-  SetStatusAreaVisible(false);
-
-  // Wait for the |CrosSettings| to become either trusted or permanently
-  // untrusted.
-  const CrosSettingsProvider::TrustedStatus status =
-      CrosSettings::Get()->PrepareTrustedValues(base::Bind(
-          &LoginDisplayHostCommon::StartAppLaunch, weak_factory_.GetWeakPtr(),
-          app_id, diagnostic_mode, is_auto_launch));
-  if (status == CrosSettingsProvider::TEMPORARILY_UNTRUSTED)
-    return;
-
-  if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
-    // If the |CrosSettings| are permanently untrusted, refuse to launch a
-    // single-app kiosk mode session.
-    LOG(ERROR) << "Login >> Refusing to launch single-app kiosk mode.";
-    SetStatusAreaVisible(true);
-    return;
-  }
-
-  if (system::DeviceDisablingManager::IsDeviceDisabledDuringNormalOperation()) {
-    // If the device is disabled, bail out. A device disabled screen will be
-    // shown by the DeviceDisablingManager.
-    return;
-  }
-
-  OnStartAppLaunch();
-
-  app_launch_controller_ = std::make_unique<AppLaunchController>(
-      app_id, diagnostic_mode, this, GetOobeUI());
-
-  app_launch_controller_->StartAppLaunch(is_auto_launch);
-}
-
-void LoginDisplayHostCommon::StartDemoAppLaunch() {
-  VLOG(1) << "Login >> starting demo app.";
-  SetStatusAreaVisible(false);
-
-  demo_app_launcher_ = std::make_unique<DemoAppLauncher>();
-  demo_app_launcher_->StartDemoAppLaunch();
-}
-
-void LoginDisplayHostCommon::StartArcKiosk(const AccountId& account_id) {
-  VLOG(1) << "Login >> start ARC kiosk.";
-  SetStatusAreaVisible(false);
-  arc_kiosk_controller_ =
-      std::make_unique<ArcKioskController>(this, GetOobeUI());
-  arc_kiosk_controller_->StartArcKiosk(account_id);
-
-  OnStartArcKiosk();
-}
-
-void LoginDisplayHostCommon::OnAuthPrewarmDone() {
-  auth_prewarmer_.reset();
-}
-
-void LoginDisplayHostCommon::CompleteLogin(const UserContext& user_context) {
-  ExistingUserController* controller =
-      ExistingUserController::current_controller();
-  if (controller)
-    controller->CompleteLogin(user_context);
-}
-
-void LoginDisplayHostCommon::OnGaiaScreenReady() {
-  ExistingUserController* controller =
-      ExistingUserController::current_controller();
-  if (controller)
-    controller->OnGaiaScreenReady();
-}
-
-void LoginDisplayHostCommon::SetDisplayEmail(const std::string& email) {
-  ExistingUserController* controller =
-      ExistingUserController::current_controller();
-  if (controller)
-    controller->SetDisplayEmail(email);
-}
-
-void LoginDisplayHostCommon::SetDisplayAndGivenName(
-    const std::string& display_name,
-    const std::string& given_name) {
-  ExistingUserController* controller =
-      ExistingUserController::current_controller();
-  if (controller)
-    controller->SetDisplayAndGivenName(display_name, given_name);
-}
-
-void LoginDisplayHostCommon::LoadWallpaper(const AccountId& account_id) {
-  WallpaperManager::Get()->ShowUserWallpaper(account_id);
-}
-
-void LoginDisplayHostCommon::LoadSigninWallpaper() {
-  WallpaperManager::Get()->ShowSigninWallpaper();
-}
-
-bool LoginDisplayHostCommon::IsUserWhitelisted(const AccountId& account_id) {
-  ExistingUserController* controller =
-      ExistingUserController::current_controller();
-  if (!controller)
-    return true;
-  return controller->IsUserWhitelisted(account_id);
-}
-
-}  // namespace chromeos
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_common.h b/chrome/browser/chromeos/login/ui/login_display_host_common.h
deleted file mode 100644
index 6a27a6e..0000000
--- a/chrome/browser/chromeos/login/ui/login_display_host_common.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// 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 CHROME_BROWSER_CHROMEOS_LOGIN_UI_LOGIN_DISPLAY_HOST_COMMON_H_
-#define CHROME_BROWSER_CHROMEOS_LOGIN_UI_LOGIN_DISPLAY_HOST_COMMON_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "chrome/browser/chromeos/login/ui/login_display_host.h"
-
-class AccountId;
-
-namespace chromeos {
-
-class ArcKioskController;
-class DemoAppLauncher;
-
-// LoginDisplayHostCommon contains code which is not specific to a particular UI
-// implementation - the goal is to reduce code duplication between
-// LoginDisplayHostViews and LoginDisplayHostWebUI.
-class LoginDisplayHostCommon : public LoginDisplayHost {
- public:
-  LoginDisplayHostCommon();
-  ~LoginDisplayHostCommon() override;
-
-  // LoginDisplayHost:
-  AppLaunchController* GetAppLaunchController() final;
-  void StartSignInScreen(const LoginScreenContext& context) final;
-  void PrewarmAuthentication() final;
-  void StartAppLaunch(const std::string& app_id,
-                      bool diagnostic_mode,
-                      bool is_auto_launch) final;
-  void StartDemoAppLaunch() final;
-  void StartArcKiosk(const AccountId& account_id) final;
-  void CompleteLogin(const UserContext& user_context) final;
-  void OnGaiaScreenReady() final;
-  void SetDisplayEmail(const std::string& email) final;
-  void SetDisplayAndGivenName(const std::string& display_name,
-                              const std::string& given_name) final;
-  void LoadWallpaper(const AccountId& account_id) final;
-  void LoadSigninWallpaper() final;
-  bool IsUserWhitelisted(const AccountId& account_id) final;
-
- protected:
-  virtual void OnStartSignInScreen(const LoginScreenContext& context) = 0;
-  virtual void OnStartAppLaunch() = 0;
-  virtual void OnStartArcKiosk() = 0;
-
-  // Deletes |auth_prewarmer_|.
-  void OnAuthPrewarmDone();
-
-  // Active instance of authentication prewarmer.
-  std::unique_ptr<AuthPrewarmer> auth_prewarmer_;
-
-  // App launch controller.
-  std::unique_ptr<AppLaunchController> app_launch_controller_;
-
-  // Demo app launcher.
-  std::unique_ptr<DemoAppLauncher> demo_app_launcher_;
-
-  // ARC kiosk controller.
-  std::unique_ptr<ArcKioskController> arc_kiosk_controller_;
-
- private:
-  base::WeakPtrFactory<LoginDisplayHostCommon> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(LoginDisplayHostCommon);
-};
-
-}  // namespace chromeos
-
-#endif  // CHROME_BROWSER_CHROMEOS_LOGIN_UI_LOGIN_DISPLAY_HOST_COMMON_H_
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_views.h b/chrome/browser/chromeos/login/ui/login_display_host_views.h
index df1b6b62..5518867 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_views.h
+++ b/chrome/browser/chromeos/login/ui/login_display_host_views.h
@@ -7,11 +7,10 @@
 
 #include <memory>
 #include <string>
-#include <vector>
 
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
-#include "chrome/browser/chromeos/login/ui/login_display_host_common.h"
+#include "chrome/browser/chromeos/login/ui/login_display_host.h"
 #include "chrome/browser/ui/ash/login_screen_client.h"
 #include "chromeos/login/auth/auth_status_consumer.h"
 
@@ -21,7 +20,7 @@
 
 // A LoginDisplayHost instance that sends requests to the views-based signin
 // screen.
-class LoginDisplayHostViews : public LoginDisplayHostCommon,
+class LoginDisplayHostViews : public LoginDisplayHost,
                               public LoginScreenClient::Delegate,
                               public AuthStatusConsumer {
  public:
diff --git a/chrome/browser/chromeos/login/ui/login_display_host_webui.h b/chrome/browser/chromeos/login/ui/login_display_host_webui.h
index bcd0a3a..4fa54d95 100644
--- a/chrome/browser/chromeos/login/ui/login_display_host_webui.h
+++ b/chrome/browser/chromeos/login/ui/login_display_host_webui.h
@@ -16,7 +16,7 @@
 #include "chrome/browser/chromeos/login/existing_user_controller.h"
 #include "chrome/browser/chromeos/login/signin_screen_controller.h"
 #include "chrome/browser/chromeos/login/ui/login_display.h"
-#include "chrome/browser/chromeos/login/ui/login_display_host_common.h"
+#include "chrome/browser/chromeos/login/ui/login_display_host.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
 #include "chrome/browser/chromeos/settings/device_settings_service.h"
 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
@@ -44,7 +44,7 @@
 
 // An implementation class for OOBE/login WebUI screen host.
 // It encapsulates controllers, wallpaper integration and flow.
-class LoginDisplayHostWebUI : public LoginDisplayHostCommon,
+class LoginDisplayHostWebUI : public LoginDisplayHost,
                               public content::NotificationObserver,
                               public content::WebContentsObserver,
                               public chromeos::SessionManagerClient::Observer,
@@ -57,7 +57,7 @@
   explicit LoginDisplayHostWebUI(const gfx::Rect& wallpaper_bounds);
   ~LoginDisplayHostWebUI() override;
 
-  // LoginDisplayHost:
+  // LoginDisplayHost implementation:
   LoginDisplay* CreateLoginDisplay(LoginDisplay::Delegate* delegate) override;
   gfx::NativeWindow GetNativeWindow() const override;
   OobeUI* GetOobeUI() const override;
diff --git a/chrome/browser/chromeos/login/ui/mock_login_display_host.h b/chrome/browser/chromeos/login/ui/mock_login_display_host.h
index ceea6c3..e161644 100644
--- a/chrome/browser/chromeos/login/ui/mock_login_display_host.h
+++ b/chrome/browser/chromeos/login/ui/mock_login_display_host.h
@@ -5,8 +5,6 @@
 #ifndef CHROME_BROWSER_CHROMEOS_LOGIN_UI_MOCK_LOGIN_DISPLAY_HOST_H_
 #define CHROME_BROWSER_CHROMEOS_LOGIN_UI_MOCK_LOGIN_DISPLAY_HOST_H_
 
-#include <string>
-
 #include "base/macros.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
@@ -32,9 +30,9 @@
   }
 
   MOCK_METHOD1(SetStatusAreaVisible, void(bool));
+  MOCK_METHOD0(ShowBackground, void(void));
   MOCK_METHOD1(StartWizard, void(OobeScreen));
   MOCK_METHOD0(GetWizardController, WizardController*(void));
-  MOCK_METHOD0(GetAppLaunchController, AppLaunchController*(void));
 
   // Workaround for move-only args in GMock.
   MOCK_METHOD1(MockStartUserAdding, void(base::OnceClosure*));
@@ -43,24 +41,16 @@
   }
 
   MOCK_METHOD0(CancelUserAdding, void(void));
-  MOCK_METHOD1(StartSignInScreen, void(const LoginScreenContext&));
+  MOCK_METHOD1(OnStartSignInScreen, void(const LoginScreenContext&));
+  MOCK_METHOD0(ResumeSignInScreen, void(void));
   MOCK_METHOD0(OnPreferencesChanged, void(void));
   MOCK_METHOD0(PrewarmAuthentication, void(void));
-  MOCK_METHOD3(StartAppLaunch, void(const std::string&, bool, bool));
+  MOCK_METHOD0(OnStartAppLaunch, void());
   MOCK_METHOD0(StartDemoAppLaunch, void(void));
-  MOCK_METHOD1(StartArcKiosk, void(const AccountId&));
+  MOCK_METHOD0(OnStartArcKiosk, void());
   MOCK_METHOD0(StartVoiceInteractionOobe, void(void));
   MOCK_METHOD0(IsVoiceInteractionOobe, bool(void));
 
-  MOCK_METHOD1(CompleteLogin, void(const UserContext&));
-  MOCK_METHOD0(OnGaiaScreenReady, void());
-  MOCK_METHOD1(SetDisplayEmail, void(const std::string&));
-  MOCK_METHOD2(SetDisplayAndGivenName,
-               void(const std::string&, const std::string&));
-  MOCK_METHOD1(LoadWallpaper, void(const AccountId&));
-  MOCK_METHOD0(LoadSigninWallpaper, void());
-  MOCK_METHOD1(IsUserWhitelisted, bool(const AccountId&));
-
  private:
   DISALLOW_COPY_AND_ASSIGN(MockLoginDisplayHost);
 };
diff --git a/chrome/browser/devtools/device/android_device_manager.cc b/chrome/browser/devtools/device/android_device_manager.cc
index 18327ea7..b36258d5 100644
--- a/chrome/browser/devtools/device/android_device_manager.cc
+++ b/chrome/browser/devtools/device/android_device_manager.cc
@@ -35,7 +35,7 @@
 
 static const char kRequestLineFormat[] = "GET %s HTTP/1.1";
 
-net::NetworkTrafficAnnotationTag kTrafficAnnotation =
+net::NetworkTrafficAnnotationTag kAndroidDeviceManagerTrafficAnnotation =
     net::DefineNetworkTrafficAnnotation("android_device_manager_socket", R"(
         semantics {
           sender: "Android Device Manager"
@@ -167,7 +167,7 @@
       result = socket_->Write(
           request_.get(), request_->BytesRemaining(),
           base::Bind(&HttpRequest::DoSendRequest, base::Unretained(this)),
-          kTrafficAnnotation);
+          kAndroidDeviceManagerTrafficAnnotation);
     }
   }
 
diff --git a/chrome/browser/devtools/device/android_web_socket.cc b/chrome/browser/devtools/device/android_web_socket.cc
index 3130eb5..bc307ab2 100644
--- a/chrome/browser/devtools/device/android_web_socket.cc
+++ b/chrome/browser/devtools/device/android_web_socket.cc
@@ -26,7 +26,7 @@
 const int kBufferSize = 16 * 1024;
 const char kCloseResponse[] = "\x88\x80\x2D\x0E\x1E\xFA";
 
-net::NetworkTrafficAnnotationTag kTrafficAnnotation =
+net::NetworkTrafficAnnotationTag kAndroidWebSocketTrafficAnnotation =
     net::DefineNetworkTrafficAnnotation("android_web_socket", R"(
         semantics {
           sender: "Android Web Socket"
@@ -160,7 +160,7 @@
     result = socket_->Write(buffer.get(), buffer->size(),
                             base::Bind(&WebSocketImpl::SendPendingRequests,
                                        weak_factory_.GetWeakPtr()),
-                            kTrafficAnnotation);
+                            kAndroidWebSocketTrafficAnnotation);
     if (result != net::ERR_IO_PENDING)
       SendPendingRequests(result);
   }
diff --git a/chrome/browser/devtools/device/port_forwarding_controller.cc b/chrome/browser/devtools/device/port_forwarding_controller.cc
index 6fa683b86..55e64f29 100644
--- a/chrome/browser/devtools/device/port_forwarding_controller.cc
+++ b/chrome/browser/devtools/device/port_forwarding_controller.cc
@@ -45,7 +45,7 @@
   kStatusOK = 0,
 };
 
-net::NetworkTrafficAnnotationTag kTrafficAnnotation =
+net::NetworkTrafficAnnotationTag kPortForwardingControllerTrafficAnnotation =
     net::DefineNetworkTrafficAnnotation("port_forwarding_controller_socket",
                                         R"(
         semantics {
@@ -162,7 +162,7 @@
     result = to->Write(drainable.get(), total,
                        base::Bind(&SocketTunnel::OnWritten,
                                   base::Unretained(this), drainable, from, to),
-                       kTrafficAnnotation);
+                       kPortForwardingControllerTrafficAnnotation);
     if (result != net::ERR_IO_PENDING)
       OnWritten(drainable, from, to, result);
   }
@@ -184,7 +184,7 @@
           to->Write(drainable.get(), drainable->BytesRemaining(),
                     base::Bind(&SocketTunnel::OnWritten, base::Unretained(this),
                                drainable, from, to),
-                    kTrafficAnnotation);
+                    kPortForwardingControllerTrafficAnnotation);
       if (result != net::ERR_IO_PENDING)
         OnWritten(drainable, from, to, result);
       return;
diff --git a/chrome/browser/extensions/api/tabs/app_window_controller.cc b/chrome/browser/extensions/api/tabs/app_window_controller.cc
index 3d0bd3e..fb9f4f1 100644
--- a/chrome/browser/extensions/api/tabs/app_window_controller.cc
+++ b/chrome/browser/extensions/api/tabs/app_window_controller.cc
@@ -121,8 +121,9 @@
   return nullptr;
 }
 
-bool AppWindowController::IsVisibleToExtension(
-    const Extension* extension) const {
+bool AppWindowController::IsVisibleToTabsAPIForExtension(
+    const Extension* extension,
+    bool allow_dev_tools_windows) const {
   DCHECK(extension);
   return extension->id() == app_window_->extension_id();
 }
diff --git a/chrome/browser/extensions/api/tabs/app_window_controller.h b/chrome/browser/extensions/api/tabs/app_window_controller.h
index 8b8511a7..848739f 100644
--- a/chrome/browser/extensions/api/tabs/app_window_controller.h
+++ b/chrome/browser/extensions/api/tabs/app_window_controller.h
@@ -38,7 +38,9 @@
   void SetFullscreenMode(bool is_fullscreen,
                          const GURL& extension_url) const override;
   Browser* GetBrowser() const override;
-  bool IsVisibleToExtension(const Extension* extension) const override;
+  bool IsVisibleToTabsAPIForExtension(
+      const Extension* extension,
+      bool allow_dev_tools_windows) const override;
 
  private:
   AppWindow* app_window_;  // Owns us.
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc
index 173a98d..bfdb046 100644
--- a/chrome/browser/extensions/api/tabs/tabs_api.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_api.cc
@@ -928,8 +928,8 @@
     if (!include_incognito() && profile != browser->profile())
       continue;
 
-    if (!browser->extension_window_controller()->IsVisibleToExtension(
-            extension())) {
+    if (!browser->extension_window_controller()->IsVisibleToTabsAPIForExtension(
+            extension(), false /*allow_dev_tools_windows*/)) {
       continue;
     }
 
diff --git a/chrome/browser/extensions/api/tabs/tabs_test.cc b/chrome/browser/extensions/api/tabs/tabs_test.cc
index 01abcd1..d76a315 100644
--- a/chrome/browser/extensions/api/tabs/tabs_test.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_test.cc
@@ -301,12 +301,12 @@
     window_ids.insert(ExtensionTabUtil::GetWindowId(new_browser));
   }
 
-  // Application windows should not be accessible, unless allWindowTypes is set
-  // to true.
+  // Application windows should not be accessible to extensions (app windows are
+  // only accessible to the owning item).
   AppWindow* app_window = CreateTestAppWindow("{}");
 
-  // Undocked DevTools window should not be accessible, unless allWindowTypes is
-  // set to true.
+  // Undocked DevTools window should not be accessible, unless included in the
+  // type filter mask.
   DevToolsWindow* devtools = DevToolsWindowTesting::OpenDevToolsWindowSync(
       browser()->tab_strip_model()->GetWebContentsAt(0), false /* is_docked */);
 
@@ -370,11 +370,12 @@
     window_ids.insert(ExtensionTabUtil::GetWindowId(new_browser));
   }
 
-  // Application windows should be accessible.
+  // Application windows should not be accessible to extensions (app windows are
+  // only accessible to the owning item).
   AppWindow* app_window = CreateTestAppWindow("{}");
-  window_ids.insert(app_window->session_id().id());
 
-  // Undocked DevTools window should be accessible too.
+  // Undocked DevTools window should be accessible too, since they have been
+  // explicitly requested as part of the type filter mask.
   DevToolsWindow* devtools = DevToolsWindowTesting::OpenDevToolsWindowSync(
       browser()->tab_strip_model()->GetWebContentsAt(0), false /* is_docked */);
   window_ids.insert(ExtensionTabUtil::GetWindowId(
@@ -401,8 +402,7 @@
     base::ListValue* tabs = nullptr;
     EXPECT_FALSE(result_window->GetList(keys::kTabsKey, &tabs));
   }
-  // The returned ids should contain all the current app, browser and
-  // devtools instance ids.
+  // The returned ids should contain all the browser and devtools instance ids.
   EXPECT_EQ(window_ids, result_ids);
 
   result_ids.clear();
@@ -425,8 +425,7 @@
     base::ListValue* tabs = nullptr;
     EXPECT_TRUE(result_window->GetList(keys::kTabsKey, &tabs));
   }
-  // The returned ids should contain all the current app, browser and
-  // devtools instance ids.
+  // The returned ids should contain all the browser and devtools instance ids.
   EXPECT_EQ(window_ids, result_ids);
 
   DevToolsWindowTesting::CloseDevToolsWindowSync(devtools);
@@ -762,55 +761,6 @@
       keys::kInvalidWindowStateError));
 }
 
-IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, UpdateAppWindowSizeConstraint) {
-  AppWindow* app_window = CreateTestAppWindow(
-      "{\"outerBounds\": "
-      "{\"width\": 300, \"height\": 300,"
-      " \"minWidth\": 200, \"minHeight\": 200,"
-      " \"maxWidth\": 400, \"maxHeight\": 400}}");
-
-  scoped_refptr<WindowsGetFunction> get_function = new WindowsGetFunction();
-  scoped_refptr<Extension> extension(ExtensionBuilder("Test").Build().get());
-  get_function->set_extension(extension.get());
-  std::unique_ptr<base::DictionaryValue> result(
-      utils::ToDictionary(utils::RunFunctionAndReturnSingleResult(
-          get_function.get(),
-          base::StringPrintf("[%u, {\"windowTypes\": [\"app\"]}]",
-                             app_window->session_id().id()),
-          browser())));
-
-  EXPECT_EQ(300, api_test_utils::GetInteger(result.get(), "width"));
-  EXPECT_EQ(300, api_test_utils::GetInteger(result.get(), "height"));
-
-  // Verify the min width/height of the application window are
-  // respected.
-  scoped_refptr<WindowsUpdateFunction> update_min_function =
-      new WindowsUpdateFunction();
-  result.reset(utils::ToDictionary(utils::RunFunctionAndReturnSingleResult(
-      update_min_function.get(),
-      base::StringPrintf("[%u, {\"width\": 100, \"height\": 100}]",
-                         app_window->session_id().id()),
-      browser())));
-
-  EXPECT_EQ(200, api_test_utils::GetInteger(result.get(), "width"));
-  EXPECT_EQ(200, api_test_utils::GetInteger(result.get(), "height"));
-
-  // Verify the max width/height of the application window are
-  // respected.
-  scoped_refptr<WindowsUpdateFunction> update_max_function =
-      new WindowsUpdateFunction();
-  result.reset(utils::ToDictionary(utils::RunFunctionAndReturnSingleResult(
-      update_max_function.get(),
-      base::StringPrintf("[%u, {\"width\": 500, \"height\": 500}]",
-                         app_window->session_id().id()),
-      browser())));
-
-  EXPECT_EQ(400, api_test_utils::GetInteger(result.get(), "width"));
-  EXPECT_EQ(400, api_test_utils::GetInteger(result.get(), "height"));
-
-  CloseAppWindow(app_window);
-}
-
 IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, UpdateDevToolsWindow) {
   DevToolsWindow* devtools = DevToolsWindowTesting::OpenDevToolsWindowSync(
       browser()->tab_strip_model()->GetWebContentsAt(0), false /* is_docked */);
@@ -866,6 +816,8 @@
   base::Value* RunFunction(UIThreadExtensionFunction* function,
                            const std::string& params);
 
+  const Extension* extension() { return extension_.get(); }
+
  private:
   // A helper class to wait for an views::Widget to become activated.
   class WidgetActivatedWaiter : public views::WidgetObserver {
@@ -1083,13 +1035,12 @@
 
     scoped_refptr<WindowsGetLastFocusedFunction> get_current_app_function =
         new WindowsGetLastFocusedFunction();
-    std::unique_ptr<base::DictionaryValue> result(utils::ToDictionary(
-        RunFunction(get_current_app_function.get(),
-                    "[{\"populate\": true, \"windowTypes\": [ \"app\" ]}]")));
-    int app_window_id = app_window->session_id().id();
-    EXPECT_EQ(app_window_id, api_test_utils::GetInteger(result.get(), "id"));
-    EXPECT_EQ(-1, GetTabId(result.get()));
-    EXPECT_EQ("app", api_test_utils::GetString(result.get(), "type"));
+    get_current_app_function->set_extension(extension());
+    EXPECT_EQ(
+        tabs_constants::kNoLastFocusedWindowError,
+        extension_function_test_utils::RunFunctionAndReturnError(
+            get_current_app_function.get(),
+            "[{\"populate\": true, \"windowTypes\": [ \"app\" ]}]", browser()));
   }
 
   chrome::CloseWindow(normal_browser);
diff --git a/chrome/browser/extensions/api/tabs/windows_event_router.cc b/chrome/browser/extensions/api/tabs/windows_event_router.cc
index 0ef3e6f9..98df5ae 100644
--- a/chrome/browser/extensions/api/tabs/windows_event_router.cc
+++ b/chrome/browser/extensions/api/tabs/windows_event_router.cc
@@ -42,14 +42,19 @@
 
   // If there is no filter the visibility is based on the extension.
   const base::ListValue* filter_value = nullptr;
-  if (!listener_filter ||
-      !listener_filter->GetList(keys::kWindowTypesKey, &filter_value))
-    return window_controller->IsVisibleToExtension(extension);
+  if (listener_filter)
+    listener_filter->GetList(keys::kWindowTypesKey, &filter_value);
 
-  // Otherwise it's based on the type filter.
-  WindowController::TypeFilter filter =
-      WindowController::GetFilterFromWindowTypesValues(filter_value);
-  return window_controller->MatchesFilter(filter);
+  // TODO(https://crbug.com/807313): Remove this.
+  bool allow_dev_tools_windows = !!filter_value;
+  if (!window_controller->IsVisibleToTabsAPIForExtension(
+          extension, allow_dev_tools_windows)) {
+    return false;
+  }
+
+  return !filter_value ||
+         window_controller->MatchesFilter(
+             WindowController::GetFilterFromWindowTypesValues(filter_value));
 }
 
 bool WillDispatchWindowEvent(WindowController* window_controller,
@@ -59,6 +64,13 @@
                              const base::DictionaryValue* listener_filter) {
   bool has_filter =
       listener_filter && listener_filter->HasKey(keys::kWindowTypesKey);
+  // TODO(https://crbug.com/807313): Remove this.
+  bool allow_dev_tools_windows = has_filter;
+  if (!window_controller->IsVisibleToTabsAPIForExtension(
+          extension, allow_dev_tools_windows)) {
+    return false;
+  }
+
   // Cleanup previous values.
   event->filter_info = EventFilteringInfo();
   // Only set the window type if the listener has set a filter.
@@ -66,8 +78,7 @@
   if (has_filter) {
     event->filter_info.window_type = window_controller->GetWindowTypeText();
   } else {
-    event->filter_info.window_exposed_by_default =
-        window_controller->IsVisibleToExtension(extension);
+    event->filter_info.window_exposed_by_default = true;
   }
   return true;
 }
diff --git a/chrome/browser/extensions/api/tabs/windows_util.cc b/chrome/browser/extensions/api/tabs/windows_util.cc
index e7179e6..1b8a467 100644
--- a/chrome/browser/extensions/api/tabs/windows_util.cc
+++ b/chrome/browser/extensions/api/tabs/windows_util.cc
@@ -64,9 +64,13 @@
   if (filter && !controller->MatchesFilter(filter))
     return false;
 
-  if (!filter && function->extension() &&
-      !controller->IsVisibleToExtension(function->extension()))
+  // TODO(https://crbug.com/807313): Remove this.
+  bool allow_dev_tools_windows = !!filter;
+  if (function->extension() &&
+      !controller->IsVisibleToTabsAPIForExtension(function->extension(),
+                                                  allow_dev_tools_windows)) {
     return false;
+  }
 
   if (function->browser_context() == controller->profile())
     return true;
diff --git a/chrome/browser/extensions/browser_extension_window_controller.cc b/chrome/browser/extensions/browser_extension_window_controller.cc
index 64e08983..e635289 100644
--- a/chrome/browser/extensions/browser_extension_window_controller.cc
+++ b/chrome/browser/extensions/browser_extension_window_controller.cc
@@ -82,9 +82,13 @@
   return browser_;
 }
 
-bool BrowserExtensionWindowController::IsVisibleToExtension(
-    const extensions::Extension* extension) const {
+bool BrowserExtensionWindowController::IsVisibleToTabsAPIForExtension(
+    const extensions::Extension* extension,
+    bool allow_dev_tools_windows) const {
   DCHECK(extension);
   // Platform apps can only see their own windows.
-  return !browser_->is_devtools() && !extension->is_platform_app();
+  if (extension->is_platform_app())
+    return false;
+
+  return !browser_->is_devtools() || allow_dev_tools_windows;
 }
diff --git a/chrome/browser/extensions/browser_extension_window_controller.h b/chrome/browser/extensions/browser_extension_window_controller.h
index 7f12097..593f119d 100644
--- a/chrome/browser/extensions/browser_extension_window_controller.h
+++ b/chrome/browser/extensions/browser_extension_window_controller.h
@@ -31,8 +31,9 @@
   void SetFullscreenMode(bool is_fullscreen,
                          const GURL& extension_url) const override;
   Browser* GetBrowser() const override;
-  bool IsVisibleToExtension(
-      const extensions::Extension* extension) const override;
+  bool IsVisibleToTabsAPIForExtension(
+      const extensions::Extension* extension,
+      bool allow_dev_tools_windows) const override;
 
  private:
   Browser* const browser_;
diff --git a/chrome/browser/extensions/extension_tab_util.cc b/chrome/browser/extensions/extension_tab_util.cc
index 75e8419..96cc226 100644
--- a/chrome/browser/extensions/extension_tab_util.cc
+++ b/chrome/browser/extensions/extension_tab_util.cc
@@ -336,8 +336,9 @@
   // If we have a matching AppWindow with a controller, get the tab value
   // from its controller instead.
   WindowController* controller = GetAppWindowController(contents);
-  if (controller &&
-      (!extension || controller->IsVisibleToExtension(extension))) {
+  if (controller) {
+    DCHECK(!extension || controller->IsVisibleToTabsAPIForExtension(
+                             extension, false /*allow_dev_tools_windows*/));
     return controller->CreateTabObject(extension, tab_index);
   }
   std::unique_ptr<api::tabs::Tab> result =
diff --git a/chrome/browser/extensions/updater/extension_updater.cc b/chrome/browser/extensions/updater/extension_updater.cc
index fa7113d..473bb5a 100644
--- a/chrome/browser/extensions/updater/extension_updater.cc
+++ b/chrome/browser/extensions/updater/extension_updater.cc
@@ -35,6 +35,7 @@
 #include "extensions/common/constants.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/extension_set.h"
+#include "extensions/common/extension_updater_uma.h"
 #include "extensions/common/manifest.h"
 #include "extensions/common/manifest_constants.h"
 
@@ -412,6 +413,31 @@
     const PingResult& ping,
     const std::set<int>& request_ids) {
   DCHECK(alive_);
+
+  switch (error) {
+    case Error::CRX_FETCH_FAILED:
+    case Error::MANIFEST_FETCH_FAILED:
+    case Error::MANIFEST_INVALID:
+      UMA_HISTOGRAM_ENUMERATION(
+          "Extensions.ExtensionUpdaterUpdateResults",
+          ExtensionUpdaterUpdateResult::UPDATE_ERROR,
+          ExtensionUpdaterUpdateResult::UPDATE_RESULT_COUNT);
+      break;
+    case Error::NO_UPDATE_AVAILABLE:
+      UMA_HISTOGRAM_ENUMERATION(
+          "Extensions.ExtensionUpdaterUpdateResults",
+          ExtensionUpdaterUpdateResult::NO_UPDATE,
+          ExtensionUpdaterUpdateResult::UPDATE_RESULT_COUNT);
+      break;
+    case Error::DISABLED:
+      // Error::DISABLED corresponds to the browser having disabled extension
+      // updates, the extension updater does not actually run when this error
+      // code is emitted. For this reason, Error::DISABLED is not included in
+      // Extensions.ExtensionUpdaterUpdateResults UMA; we are only interested
+      // in the update results when the extension updater runs.
+      break;
+  }
+
   UpdatePingData(id, ping);
   bool install_immediately = false;
   for (std::set<int>::const_iterator it = request_ids.begin();
@@ -564,6 +590,13 @@
 
   // If installing this file didn't succeed, we may need to re-download it.
   const Extension* extension = content::Details<const Extension>(details).ptr();
+
+  UMA_HISTOGRAM_ENUMERATION("Extensions.ExtensionUpdaterUpdateResults",
+                            extension
+                                ? ExtensionUpdaterUpdateResult::UPDATE_SUCCESS
+                                : ExtensionUpdaterUpdateResult::UPDATE_ERROR,
+                            ExtensionUpdaterUpdateResult::UPDATE_RESULT_COUNT);
+
   extensions::CrxInstaller* installer =
       content::Source<extensions::CrxInstaller>(source).ptr();
   const FetchedCRXFile& crx_file = current_crx_file_;
diff --git a/chrome/browser/extensions/window_controller.h b/chrome/browser/extensions/window_controller.h
index 691c246..941d8f65 100644
--- a/chrome/browser/extensions/window_controller.h
+++ b/chrome/browser/extensions/window_controller.h
@@ -98,9 +98,14 @@
   // TODO(stevenjb): Temporary workaround. Eliminate this.
   virtual Browser* GetBrowser() const;
 
-  // Extension/window visibility and ownership is window-specific, subclasses
-  // need to define this behavior.
-  virtual bool IsVisibleToExtension(const Extension* extension) const = 0;
+  // Returns true if the window is visible to the tabs API, when used by the
+  // given |extension|.
+  // |allow_dev_tools_windows| indicates whether dev tools windows should be
+  // treated as visible.
+  // TODO(devlin): Remove include_dev_tools_windows.
+  virtual bool IsVisibleToTabsAPIForExtension(
+      const Extension* extension,
+      bool include_dev_tools_windows) const = 0;
 
   // Returns true if the window type of the controller matches the |filter|.
   bool MatchesFilter(TypeFilter filter) const;
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 9d4068f7..3045934 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -1885,14 +1885,6 @@
     "Use content suggestions thumbnail dominant color as a placeholder before "
     "the real thumbnail is fetched (requires Chrome Home).";
 
-const char kEnableCopylessPasteName[] = "App Indexing (Copyless Paste)";
-const char kEnableCopylessPasteDescription[] =
-    "Provide suggestions for text input, based on your recent context. For "
-    "example, if you looked at a restaurant website and switched to the Maps "
-    "app, the keyboard would offer the name of that restaurant as a suggestion "
-    "to enter into the search bar. The data is indexed locally, and never sent "
-    "to the server. It's disabled in incognito mode.";
-
 const char kEnableCustomContextMenuName[] = "Enable custom context menu";
 const char kEnableCustomContextMenuDescription[] =
     "Enables a new context menu when a link, image, or video is pressed within "
@@ -2492,6 +2484,11 @@
     "Enable unified desktop mode which allows a window to span multiple "
     "displays.";
 
+const char kAshNewTouchSupportForScreenMagnificationName[] =
+    "New touch support for screen magnification";
+const char kAshNewTouchSupportForScreenMagnificationDescription[] =
+    "Enable new implementation of touch support for screen magnification";
+
 const char kBulkPrintersName[] = "Bulk Printers Policy";
 const char kBulkPrintersDescription[] = "Enables the new bulk printers policy";
 
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index a9da806..f460df5 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -1153,9 +1153,6 @@
 extern const char kEnableContentSuggestionsThumbnailDominantColorName[];
 extern const char kEnableContentSuggestionsThumbnailDominantColorDescription[];
 
-extern const char kEnableCopylessPasteName[];
-extern const char kEnableCopylessPasteDescription[];
-
 extern const char kEnableCustomContextMenuName[];
 extern const char kEnableCustomContextMenuDescription[];
 
@@ -1534,6 +1531,9 @@
 extern const char kAshEnableUnifiedDesktopName[];
 extern const char kAshEnableUnifiedDesktopDescription[];
 
+extern const char kAshNewTouchSupportForScreenMagnificationName[];
+extern const char kAshNewTouchSupportForScreenMagnificationDescription[];
+
 extern const char kBulkPrintersName[];
 extern const char kBulkPrintersDescription[];
 
diff --git a/chrome/browser/metrics/thread_watcher_report_hang.cc b/chrome/browser/metrics/thread_watcher_report_hang.cc
index 7bae67a..5385f87 100644
--- a/chrome/browser/metrics/thread_watcher_report_hang.cc
+++ b/chrome/browser/metrics/thread_watcher_report_hang.cc
@@ -72,11 +72,6 @@
     case content::BrowserThread::IO:
       return ThreadUnresponsive_IO();
     case content::BrowserThread::ID_COUNT:
-    // TODO(gab): Get rid of deprecated BrowserThread IDs.
-    case content::BrowserThread::DB:
-    case content::BrowserThread::FILE:
-    case content::BrowserThread::FILE_USER_BLOCKING:
-    case content::BrowserThread::CACHE:
       NOTREACHED();
       break;
   }
diff --git a/chrome/browser/permissions/permission_decision_auto_blocker.cc b/chrome/browser/permissions/permission_decision_auto_blocker.cc
index 8df324d..282183d 100644
--- a/chrome/browser/permissions/permission_decision_auto_blocker.cc
+++ b/chrome/browser/permissions/permission_decision_auto_blocker.cc
@@ -57,7 +57,7 @@
 // TODO(meredithl): Revisit this once UMA metrics have data about request time.
 const int kCheckUrlTimeoutMs = 2000;
 
-std::unique_ptr<base::DictionaryValue> GetOriginDict(
+std::unique_ptr<base::DictionaryValue> GetOriginAutoBlockerData(
     HostContentSettingsMap* settings,
     const GURL& origin_url) {
   std::unique_ptr<base::DictionaryValue> dict =
@@ -86,7 +86,8 @@
                                   Profile* profile) {
   HostContentSettingsMap* map =
       HostContentSettingsMapFactory::GetForProfile(profile);
-  std::unique_ptr<base::DictionaryValue> dict = GetOriginDict(map, url);
+  std::unique_ptr<base::DictionaryValue> dict =
+      GetOriginAutoBlockerData(map, url);
 
   base::Value* permission_dict = GetOrCreatePermissionDict(
       dict.get(), PermissionUtil::GetPermissionString(permission));
@@ -109,7 +110,8 @@
                    Profile* profile) {
   HostContentSettingsMap* map =
       HostContentSettingsMapFactory::GetForProfile(profile);
-  std::unique_ptr<base::DictionaryValue> dict = GetOriginDict(map, url);
+  std::unique_ptr<base::DictionaryValue> dict =
+      GetOriginAutoBlockerData(map, url);
   base::Value* permission_dict = GetOrCreatePermissionDict(
       dict.get(), PermissionUtil::GetPermissionString(permission));
 
@@ -216,7 +218,7 @@
     base::Time current_time) {
   DCHECK(settings_map);
   std::unique_ptr<base::DictionaryValue> dict =
-      GetOriginDict(settings_map, request_origin);
+      GetOriginAutoBlockerData(settings_map, request_origin);
   base::Value* permission_dict = GetOrCreatePermissionDict(
       dict.get(), PermissionUtil::GetPermissionString(permission));
 
@@ -377,7 +379,8 @@
 
   HostContentSettingsMap* map =
       HostContentSettingsMapFactory::GetForProfile(profile_);
-  std::unique_ptr<base::DictionaryValue> dict = GetOriginDict(map, url);
+  std::unique_ptr<base::DictionaryValue> dict =
+      GetOriginAutoBlockerData(map, url);
   base::Value* permission_dict = GetOrCreatePermissionDict(
       dict.get(), PermissionUtil::GetPermissionString(permission));
 
@@ -450,7 +453,7 @@
   HostContentSettingsMap* map =
       HostContentSettingsMapFactory::GetForProfile(profile_);
   std::unique_ptr<base::DictionaryValue> dict =
-      GetOriginDict(map, request_origin);
+      GetOriginAutoBlockerData(map, request_origin);
   base::Value* permission_dict = GetOrCreatePermissionDict(
       dict.get(), PermissionUtil::GetPermissionString(permission));
   permission_dict->SetKey(
diff --git a/chrome/browser/plugins/plugins_resource_service.cc b/chrome/browser/plugins/plugins_resource_service.cc
index baa01b6..029123d 100644
--- a/chrome/browser/plugins/plugins_resource_service.cc
+++ b/chrome/browser/plugins/plugins_resource_service.cc
@@ -19,8 +19,9 @@
 #include "url/gurl.h"
 
 namespace {
-constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
-    net::DefineNetworkTrafficAnnotation("plugins_resource_service", R"(
+constexpr net::NetworkTrafficAnnotationTag
+    kPluginResourceServiceTrafficAnnotation =
+        net::DefineNetworkTrafficAnnotation("plugins_resource_service", R"(
         semantics {
           sender: "Plugins Resource Service"
           description:
@@ -86,7 +87,7 @@
           base::Bind(data_decoder::SafeJsonParser::Parse,
                      content::ServiceManagerConnection::GetForProcess()
                          ->GetConnector()),
-          kTrafficAnnotation) {}
+          kPluginResourceServiceTrafficAnnotation) {}
 
 void PluginsResourceService::Init() {
   const base::DictionaryValue* metadata =
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
index ca02a989..d7c39c6 100644
--- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc
+++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -738,6 +738,9 @@
   { key::kSitePerProcess,
     prefs::kSitePerProcess,
     base::Value::Type::BOOLEAN },
+  { key::kWebDriverOverridesIncompatiblePolicies,
+    prefs::kWebDriverOverridesIncompatiblePolicies,
+    base::Value::Type::BOOLEAN },
 
   { key::kAbusiveExperienceInterventionEnforce,
     prefs::kAbusiveExperienceInterventionEnforce,
diff --git a/chrome/browser/policy/site_isolation_policy_browsertest.cc b/chrome/browser/policy/site_isolation_policy_browsertest.cc
index 7b2dd24..911056d 100644
--- a/chrome/browser/policy/site_isolation_policy_browsertest.cc
+++ b/chrome/browser/policy/site_isolation_policy_browsertest.cc
@@ -17,6 +17,7 @@
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/site_instance.h"
 #include "content/public/common/content_client.h"
+#include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test_utils.h"
 #include "url/gurl.h"
 
@@ -63,6 +64,14 @@
                policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
                std::make_unique<base::Value>(true), nullptr);
     provider_.UpdateChromePolicy(values);
+
+    // Append the automation switch which should disable Site Isolation when the
+    // "WebDriverOverridesIncompatiblePolicies" is set. This is tested in the
+    // WebDriverSitePerProcessPolicyBrowserTest class below.
+    // NOTE: This flag is on for some tests per default but we still force it
+    // it here to make sure to avoid possible regressions being missed
+    base::CommandLine::ForCurrentProcess()->AppendSwitch(
+        switches::kEnableAutomation);
   }
 
  private:
@@ -96,6 +105,41 @@
   DISALLOW_COPY_AND_ASSIGN(IsolateOriginsPolicyBrowserTest);
 };
 
+class WebDriverSitePerProcessPolicyBrowserTest
+    : public SitePerProcessPolicyBrowserTest {
+ protected:
+  WebDriverSitePerProcessPolicyBrowserTest()
+      : are_sites_isolated_for_testing_(false) {}
+
+  void SetUpInProcessBrowserTestFixture() override {
+    // First take note if tests are running in site isolated environment as this
+    // will change the outcome of the test. We can't just call this method after
+    // the call to the base setup method because setting the Site Isolation
+    // policy is indistinguishable from setting the the command line flag
+    // directly.
+    are_sites_isolated_for_testing_ = content::AreAllSitesIsolatedForTesting();
+
+    // We setup the policy here, because the policy must be 'live' before the
+    // renderer is created, since the value for this policy is passed to the
+    // renderer via a command-line. Setting the policy in the test itself or in
+    // SetUpOnMainThread works for update-able policies, but is too late for
+    // this one.
+    SitePerProcessPolicyBrowserTest::SetUpInProcessBrowserTestFixture();
+
+    policy::PolicyMap values;
+    values.Set(policy::key::kWebDriverOverridesIncompatiblePolicies,
+               policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
+               policy::POLICY_SOURCE_CLOUD, std::make_unique<base::Value>(true),
+               nullptr);
+    provider_.UpdateChromePolicy(values);
+  }
+
+  bool are_sites_isolated_for_testing_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(WebDriverSitePerProcessPolicyBrowserTest);
+};
+
 IN_PROC_BROWSER_TEST_F(SitePerProcessPolicyBrowserTest, Simple) {
   Expectations expectations[] = {
       {"https://foo.com/noodles.html", true},
@@ -118,3 +162,11 @@
   };
   CheckExpectations(expectations, arraysize(expectations));
 }
+
+IN_PROC_BROWSER_TEST_F(WebDriverSitePerProcessPolicyBrowserTest, Simple) {
+  Expectations expectations[] = {
+      {"https://foo.com/noodles.html", are_sites_isolated_for_testing_},
+      {"http://example.org/pumpkins.html", are_sites_isolated_for_testing_},
+  };
+  CheckExpectations(expectations, arraysize(expectations));
+}
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc
index 1aa31660..49767e80 100644
--- a/chrome/browser/prerender/prerender_browsertest.cc
+++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -2033,7 +2033,13 @@
 }
 
 // Checks that scripts can retrieve the correct window size while prerendering.
-IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, PrerenderWindowSize) {
+// Disabled on ChromeOS. See https://crbug.com/807821.
+#if defined(OS_CHROMEOS)
+#define MAYBE_PrerenderWindowSize DISABLED_PrerenderWindowSize
+#else
+#define MAYBE_PrerenderWindowSize PrerenderWindowSize
+#endif
+IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, MAYBE_PrerenderWindowSize) {
   PrerenderTestURL("/prerender/prerender_size.html", FINAL_STATUS_USED, 1);
   NavigateToDestURL();
 }
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc
index c847e4c8..c5ab3d4 100644
--- a/chrome/browser/profiles/profile_manager.cc
+++ b/chrome/browser/profiles/profile_manager.cc
@@ -725,10 +725,6 @@
 
 Profile* ProfileManager::GetProfileByPath(const base::FilePath& path) const {
   TRACE_EVENT0("browser", "ProfileManager::GetProfileByPath");
-  if (IsProfileDirectoryMarkedForDeletion(path)) {
-    LOG(ERROR) << "Tried to get deleted profile: " << path.value();
-    return nullptr;
-  }
   ProfileInfo* profile_info = GetProfileInfoByPath(path);
   return (profile_info && profile_info->created) ? profile_info->profile.get()
                                                  : nullptr;
diff --git a/chrome/browser/resources/media/media_engagement.html b/chrome/browser/resources/media/media_engagement.html
index c0d8827..065d3bf 100644
--- a/chrome/browser/resources/media/media_engagement.html
+++ b/chrome/browser/resources/media/media_engagement.html
@@ -131,7 +131,7 @@
           Sessions
         </th>
         <th sort-key="mediaPlaybacks" sort-reverse>
-          Playbacks per session
+          Sessions with playback
         </th>
         <th sort-key="audiblePlaybacks" sort-reverse>
           Audible Playbacks*
diff --git a/chrome/browser/resources/print_preview/new/compiled_resources2.gyp b/chrome/browser/resources/print_preview/new/compiled_resources2.gyp
index 65b2149..f396191 100644
--- a/chrome/browser/resources/print_preview/new/compiled_resources2.gyp
+++ b/chrome/browser/resources/print_preview/new/compiled_resources2.gyp
@@ -193,11 +193,20 @@
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior',
         '../compiled_resources2.gyp:native_layer',
         '../data/compiled_resources2.gyp:destination',
+        'destination_list_item',
         'print_preview_search_box',
       ],
       'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
     {
+      'target_name': 'destination_list_item',
+      'dependencies': [
+        '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:search_highlight_utils',
+        '../data/compiled_resources2.gyp:destination',
+      ],
+      'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
+    },
+    {
       'target_name': 'print_preview_search_box',
       'dependencies': [
         '<(DEPTH)/ui/webui/resources/cr_elements/cr_search_field/compiled_resources2.gyp:cr_search_field_behavior',
diff --git a/chrome/browser/resources/print_preview/new/destination_list.html b/chrome/browser/resources/print_preview/new/destination_list.html
index b541772..0cedc78e 100644
--- a/chrome/browser/resources/print_preview/new/destination_list.html
+++ b/chrome/browser/resources/print_preview/new/destination_list.html
@@ -5,6 +5,7 @@
 <link rel="import" href="chrome://resources/html/i18n_behavior.html">
 <link rel="import" href="../native_layer.html">
 <link rel="import" href="../data/destination.html">
+<link rel="import" href="destination_list_item.html">
 <link rel="import" href="print_preview_shared_css.html">
 <link rel="import" href="throbber_css.html">
 
@@ -63,12 +64,6 @@
         padding-top: 6px;
       }
 
-      :host ul {
-        list-style-type: none;
-        margin: 0;
-        padding: 0;
-      }
-
       :host .list-item {
         -webkit-padding-end: 2px;
         -webkit-padding-start: 18px;
@@ -90,95 +85,6 @@
       .list-item:focus {
         outline: none;
       }
-
-      .list-item.stale :-webkit-any(.destination-list-item-icon,
-                                    .destination-list-item-name,
-                                    .connection-status) {
-        opacity: 0.4;
-      }
-
-      .destination-list-item-icon {
-        -webkit-margin-end: 8px;
-        display: inline-block;
-        flex: 0 0 auto;
-        height: 24px;
-        transition: opacity 150ms;
-        vertical-align: middle;
-        width: 24px;
-      }
-
-      .destination-list-item-name,
-      .search-hint {
-        flex: 0 1 auto;
-        line-height: 24px;
-        overflow: hidden;
-        text-overflow: ellipsis;
-        vertical-align: middle;
-        white-space: nowrap;
-      }
-
-      .list-item .search-hint {
-        -webkit-margin-start: 1em;
-        color: #999;
-        font-size: 75%;
-      }
-
-      .list-item .connection-status,
-      .list-item .learn-more-link {
-        -webkit-margin-start: 1em;
-        flex: 0 0 auto;
-        font-size: 75%;
-        line-height: 24px;
-        vertical-align: middle;
-      }
-
-      .list-item .learn-more-link {
-        color: rgb(51, 103, 214);
-      }
-
-      .register-promo {
-        -webkit-margin-start: 1em;
-        flex: 0 0 auto;
-      }
-
-      .extension-controlled-indicator {
-        display: flex;
-        flex: 1;
-        justify-content: flex-end;
-        min-width: 150px;
-      }
-
-      .extension-name {
-        -webkit-margin-start: 1em;
-        color: #777;
-        line-height: 24px;
-        overflow: hidden;
-        text-overflow: ellipsis;
-        white-space: nowrap;
-      }
-
-      .extension-icon {
-        background-position: center;
-        background-repeat: no-repeat;
-        cursor: pointer;
-        flex: 0 0 auto;
-        height: 24px;
-        margin: 0 3px;
-        width: 24px;
-      }
-
-      .configuring-in-progress-text,
-      .configuring-failed-text {
-        -webkit-margin-start: 1em;
-        flex: 0 1 auto;
-        line-height: 24px;
-        vertical-align: middle;
-      }
-
-      .configuring-failed-text {
-        color: red;
-        font-style: italic;
-      }
     </style>
     <header>
       <h4 class="title">[[title]]</h4>
@@ -190,48 +96,12 @@
         <div class="throbber"></div>
       </div>
     </header>
-    <ul>
-      <template is="dom-repeat" items="[[displayedDestinations_]]">
-        <li class$="list-item [[getStaleCssClass_(item.isOfflineOrInvalid)]]"
-             title="[[item.displayName]]"
-             hidden$="[[isDestinationHidden_(index, showAll_)]]"
-             on-tap="onDestinationSelected_">
-          <img class="destination-list-item-icon"
-              src="[[item.iconUrl]]" srcset="[[item.srcSet]]">
-          <span class="destination-list-item-name">[[item.displayName]]</span>
-          <span class="search-hint">[[getSearchHint_(item, searchQuery)]]</span>
-          <span class="connection-status"
-              hidden$="[[!item.isOfflineOrInvalid]]">
-            [[item.connectionStatusText]]
-          </span>
-          <a is="action-link" class="learn-more-link"
-              hidden$="[[!item.shouldShowInvalidCertificateError]]">
-            $i18n{learnMore}
-          </a>
-          <span class="register-promo" hidden$="[[!item.isUnregistered]]">
-            <button class="register-promo-button">
-              $i18n{registerPromoButtonText}
-            </button>
-          </span>
-          <span class="extension-controlled-indicator"
-              hidden$="[[!item.isExtension]]">
-            <span class="extension-name">[[item.extensionName]]</span>
-            <span class="extension-icon" role="button" tabindex="0"></span>
-          </span>
-<if expr="chromeos">
-          <span class="configuring-in-progress-text" hidden>
-            $i18n{configuringInProgressText}
-            <span class="configuring-text-jumping-dots">
-              <span>.</span><span>.</span><span>.</span>
-            </span>
-          </span>
-          <span class="configuring-failed-text" hidden>
-            $i18n{configuringFailedText}
-          </span>
-</if>
-        </li>
-      </template>
-    </ul>
+    <template is="dom-repeat" items="[[destinations]]" notify-dom-change
+        filter="[[computeFilter_(searchQuery, showAll_, destinations)]]">
+      <print-preview-destination-list-item class="list-item"
+          on-tap="onDestinationSelected_" destination="[[item]]">
+      </print-preview-destination-list-item>
+    </template>
     <div class="no-destinations-message" hidden$="[[hasDestinations_]]">
       $i18n{noDestinationsMessage}
     </div>
@@ -240,7 +110,7 @@
         $i18n{showAllButtonText}
       </button>
       <span class="total">
-        [[i18n('destinationCount', displayedDestinations_.length)]]
+        [[i18n('destinationCount', matchingDestinationsCount_)]]
       </span>
     </footer>
   </template>
diff --git a/chrome/browser/resources/print_preview/new/destination_list.js b/chrome/browser/resources/print_preview/new/destination_list.js
index 29bbaa4e..42550f4 100644
--- a/chrome/browser/resources/print_preview/new/destination_list.js
+++ b/chrome/browser/resources/print_preview/new/destination_list.js
@@ -5,6 +5,8 @@
 (function() {
 'use strict';
 
+// TODO (rbpotter): Adjust the short list size based on the dialog height
+// instead of always using this constant.
 /** @type {number} */
 const SHORT_DESTINATION_LIST_SIZE = 4;
 
@@ -41,52 +43,65 @@
       value: false,
     },
 
-    /** @private {!Array<!print_preview.Destination>} */
-    displayedDestinations_: {
-      type: Array,
-      computed: 'computeDisplayedDestinations_(destinations, searchQuery)',
+    /** @private {number} */
+    matchingDestinationsCount_: {
+      type: Number,
+      computed: 'computeMatchingDestinationsCount_(destinations, searchQuery)',
     },
 
     /** @type {boolean} */
     footerHidden_: {
       type: Boolean,
-      computed: 'computeFooterHidden_(displayedDestinations_, showAll_)',
+      computed: 'computeFooterHidden_(matchingDestinationsCount_, showAll_)',
     },
 
     /** @private {boolean} */
     hasDestinations_: {
       type: Boolean,
-      computed: 'computeHasDestinations_(displayedDestinations_)',
+      computed: 'computeHasDestinations_(matchingDestinationsCount_)',
     },
   },
 
-  /**
-   * @return {!Array<!print_preview.Destination>}
-   * @private
-   */
-  computeDisplayedDestinations_: function() {
-    if (!this.searchQuery)
-      return assert(this.destinations);
-    return this.destinations.filter(destination => {
-      return destination.matches(assert(this.searchQuery));
-    });
+  listeners: {
+    'dom-change': 'updateListItems_',
+  },
+
+  /** @private {number} */
+  shownCount_: 0,
+
+  /** @private */
+  updateListItems_: function() {
+    this.shadowRoot
+        .querySelectorAll('print-preview-destination-list-item:not([hidden])')
+        .forEach(item => item.update(this.searchQuery));
   },
 
   /**
-   * @param {!print_preview.Destination} destination The destination to get the
-   *     search hint for.
-   * @return {string} The property or properties matching the search query.
+   * @return {Function}
    * @private
    */
-  getSearchHint_: function(destination) {
-    if (!this.searchQuery)
-      return '';
-    let hint = '';
-    destination.extraPropertiesToMatch.some(property => {
-      if (property.match(this.searchQuery))
-        hint += property;
-    });
-    return hint;
+  computeFilter_: function() {
+    this.shownCount_ = 0;
+    return destination => {
+      const isShown =
+          (!this.searchQuery || destination.matches(this.searchQuery)) &&
+          (this.shownCount_ < SHORT_DESTINATION_LIST_SIZE || this.showAll_);
+      if (isShown)
+        this.shownCount_++;
+      return isShown;
+    };
+  },
+
+  /**
+   * @return {number}
+   * @private
+   */
+  computeMatchingDestinationsCount_: function() {
+    return this.destinations
+        .filter(destination => {
+          return !this.searchQuery || destination.matches(this.searchQuery);
+        })
+        .length;
   },
 
   /**
@@ -94,7 +109,7 @@
    * @private
    */
   computeFooterHidden_: function() {
-    return this.displayedDestinations_.length < SHORT_DESTINATION_LIST_SIZE ||
+    return this.matchingDestinationsCount_ < SHORT_DESTINATION_LIST_SIZE ||
         this.showAll_;
   },
 
@@ -103,26 +118,7 @@
    * @private
    */
   computeHasDestinations_: function() {
-    return this.displayedDestinations_.length > 0;
-  },
-
-  /**
-   * @param {number} index The index of the destination in the list.
-   * @return {boolean}
-   * @private
-   */
-  isDestinationHidden_: function(index) {
-    return index >= SHORT_DESTINATION_LIST_SIZE && !this.showAll_;
-  },
-
-  /**
-   * @param {boolean} offlineOrInvalid Whether the destination is offline or
-   *     invalid
-   * @return {string} An empty string or 'stale'.
-   * @private
-   */
-  getStaleCssClass_: function(offlineOrInvalid) {
-    return offlineOrInvalid ? 'stale' : '';
+    return this.matchingDestinationsCount_ > 0;
   },
 
   /** @private */
diff --git a/chrome/browser/resources/print_preview/new/destination_list_item.html b/chrome/browser/resources/print_preview/new/destination_list_item.html
new file mode 100644
index 0000000..28fec4d
--- /dev/null
+++ b/chrome/browser/resources/print_preview/new/destination_list_item.html
@@ -0,0 +1,136 @@
+<link rel="import" href="chrome://resources/html/polymer.html">
+
+<link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html">
+<link rel="import" href="chrome://resources/html/search_highlight_utils.html">
+<link rel="import" href="../native_layer.html">
+<link rel="import" href="../data/destination.html">
+<link rel="import" href="print_preview_shared_css.html">
+
+<dom-module id="print-preview-destination-list-item">
+  <template>
+    <style include="print-preview-shared action-link cr-hidden-style">
+      :host .icon {
+        -webkit-margin-end: 8px;
+        display: inline-block;
+        flex: 0 0 auto;
+        height: 24px;
+        transition: opacity 150ms;
+        vertical-align: middle;
+        width: 24px;
+      }
+
+      :host .name,
+      :host .search-hint {
+        flex: 0 1 auto;
+        line-height: 24px;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        vertical-align: middle;
+        white-space: nowrap;
+      }
+
+      :host .search-hint {
+        -webkit-margin-start: 1em;
+        color: #999;
+        font-size: 75%;
+      }
+
+      :host .connection-status,
+      :host .learn-more-link {
+        -webkit-margin-start: 1em;
+        flex: 0 0 auto;
+        font-size: 75%;
+        line-height: 24px;
+        vertical-align: middle;
+      }
+
+      :host .learn-more-link {
+        color: rgb(51, 103, 214);
+      }
+
+      :host .register-promo {
+        -webkit-margin-start: 1em;
+        flex: 0 0 auto;
+      }
+
+      :host .extension-controlled-indicator {
+        display: flex;
+        flex: 1;
+        justify-content: flex-end;
+        min-width: 150px;
+      }
+
+      :host .extension-name {
+        -webkit-margin-start: 1em;
+        color: #777;
+        line-height: 24px;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+      }
+
+      :host .extension-icon {
+        background-position: center;
+        background-repeat: no-repeat;
+        cursor: pointer;
+        flex: 0 0 auto;
+        height: 24px;
+        margin: 0 3px;
+        width: 24px;
+      }
+
+      :host .configuring-in-progress-text,
+      :host .configuring-failed-text {
+        -webkit-margin-start: 1em;
+        flex: 0 1 auto;
+        line-height: 24px;
+        vertical-align: middle;
+      }
+
+      :host .configuring-failed-text {
+        color: red;
+        font-style: italic;
+      }
+
+      :host([stale]) :-webkit-any(.icon, .name, .connection-status) {
+        opacity: 0.4;
+      }
+    </style>
+    <img class="icon" src="[[destination.iconUrl]]"
+        srcset="[[destination.srcSet]]">
+    <span class="name searchable">[[destination.displayName]]</span>
+    <span class="search-hint searchable">[[searchHint_]]</span>
+    <span class="connection-status"
+        hidden$="[[!destination.isOfflineOrInvalid]]">
+      [[destination.connectionStatusText]]
+    </span>
+    <a is="action-link" class="learn-more-link"
+        hidden$="[[!destination.shouldShowInvalidCertificateError]]">
+      $i18n{learnMore}
+    </a>
+    <span class="register-promo" hidden$="[[!destination.isUnregistered]]">
+      <button class="register-promo-button">
+        $i18n{registerPromoButtonText}
+      </button>
+    </span>
+    <span class="extension-controlled-indicator"
+        hidden$="[[!destination.isExtension]]">
+      <span class="extension-name searchable">
+        [[destination.extensionName]]
+      </span>
+      <span class="extension-icon" role="button" tabindex="0"></span>
+    </span>
+<if expr="chromeos">
+    <span class="configuring-in-progress-text" hidden>
+      $i18n{configuringInProgressText}
+      <span class="configuring-text-jumping-dots">
+        <span>.</span><span>.</span><span>.</span>
+      </span>
+    </span>
+    <span class="configuring-failed-text" hidden>
+      $i18n{configuringFailedText}
+    </span>
+</if>
+  </template>
+  <script src="destination_list_item.js"></script>
+</dom-module>
diff --git a/chrome/browser/resources/print_preview/new/destination_list_item.js b/chrome/browser/resources/print_preview/new/destination_list_item.js
new file mode 100644
index 0000000..9cb057b
--- /dev/null
+++ b/chrome/browser/resources/print_preview/new/destination_list_item.js
@@ -0,0 +1,98 @@
+// 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.
+
+Polymer({
+  is: 'print-preview-destination-list-item',
+
+  properties: {
+    /** @type {!print_preview.Destination} */
+    destination: Object,
+
+    /** @private {string} */
+    searchHint_: {
+      type: String,
+      notify: true,
+    },
+
+    /** @type {boolean} */
+    stale: {
+      type: Boolean,
+      notify: true,
+      reflectToAttribute: true,
+    },
+  },
+
+  observers: [
+    'onDestinationPropertiesChange_(' +
+        'destination.displayName, destination.isOfflineOrInvalid)',
+  ],
+
+  /** @private {boolean} */
+  highlighted_: false,
+
+  /** @private */
+  onDestinationPropertiesChange_: function() {
+    this.title = this.destination.displayName;
+    this.stale = this.destination.isOfflineOrInvalid;
+  },
+
+  /** @param {?RegExp} searchQuery The search query to update for. */
+  update: function(searchQuery) {
+    this.updateSearchHint_(searchQuery);
+    this.updateHighlighting_(searchQuery);
+  },
+
+  /**
+   * @param {?RegExp} searchQuery The search query to update the hint for.
+   * @private
+   */
+  updateSearchHint_: function(searchQuery) {
+    if (!searchQuery) {
+      this.searchHint_ = '';
+      return;
+    }
+    this.searchHint_ = this.destination.extraPropertiesToMatch
+                           .filter(p => p.match(searchQuery))
+                           .join(' ');
+  },
+
+  /**
+   * @param {?RegExp} searchQuery The search query to update the hint for.
+   * @private
+   */
+  updateHighlighting_: function(searchQuery) {
+    if (this.highlighted_) {
+      cr.search_highlight_utils.findAndRemoveHighlights(this);
+      this.highlighted_ = false;
+    }
+
+    if (!searchQuery)
+      return;
+
+    this.shadowRoot.querySelectorAll('.searchable').forEach(element => {
+      element.childNodes.forEach(node => {
+        if (node.nodeType != Node.TEXT_NODE)
+          return;
+
+        const textContent = node.nodeValue.trim();
+        if (textContent.length == 0)
+          return;
+
+        if (searchQuery.test(textContent)) {
+          // Don't highlight <select> nodes, yellow rectangles can't be
+          // displayed within an <option>.
+          // TODO(rbpotter): solve issue below before adding advanced
+          // settings so that this function can be re-used.
+          // TODO(dpapad): highlight <select> controls with a search bubble
+          // instead.
+          if (node.parentNode.nodeName != 'OPTION') {
+            cr.search_highlight_utils.highlight(
+                node, textContent.split(searchQuery));
+            this.highlighted_ = true;
+          }
+        }
+      });
+    });
+  },
+});
diff --git a/chrome/browser/resources/print_preview/new/print_preview_search_box.js b/chrome/browser/resources/print_preview/new/print_preview_search_box.js
index f1928a1b..c8890137 100644
--- a/chrome/browser/resources/print_preview/new/print_preview_search_box.js
+++ b/chrome/browser/resources/print_preview/new/print_preview_search_box.js
@@ -36,7 +36,7 @@
   onSearchChanged_: function(e) {
     const safeQuery = e.detail.trim().replace(SANITIZE_REGEX, '\\$&');
     this.searchQuery =
-        safeQuery.length > 0 ? new RegExp(`(${safeQuery})`, 'ig') : null;
+        safeQuery.length > 0 ? new RegExp(`(${safeQuery})`, 'i') : null;
   },
 });
 })();
diff --git a/chrome/browser/resources/print_preview/print_preview_resources.grd b/chrome/browser/resources/print_preview/print_preview_resources.grd
index 2feb6bd..44b52b9b 100644
--- a/chrome/browser/resources/print_preview/print_preview_resources.grd
+++ b/chrome/browser/resources/print_preview/print_preview_resources.grd
@@ -226,11 +226,17 @@
                  type="chrome_html" />
       <structure name="IDR_PRINT_PREVIEW_NEW_DESTINATION_LIST_HTML"
                  file="new/destination_list.html"
-                 type="chrome_html"
-                 preprocess="true" />
+                 type="chrome_html" />
       <structure name="IDR_PRINT_PREVIEW_NEW_DESTINATION_LIST_JS"
                  file="new/destination_list.js"
                  type="chrome_html" />
+      <structure name="IDR_PRINT_PREVIEW_NEW_DESTINATION_LIST_ITEM_HTML"
+                 file="new/destination_list_item.html"
+                 type="chrome_html"
+                 preprocess="true" />
+      <structure name="IDR_PRINT_PREVIEW_NEW_DESTINATION_LIST_ITEM_JS"
+                 file="new/destination_list_item.js"
+                 type="chrome_html" />
       <structure name="IDR_PRINT_PREVIEW_NEW_PRINT_PREVIEW_SEARCH_BOX_HTML"
                  file="new/print_preview_search_box.html"
                  type="chrome_html"
diff --git a/chrome/browser/resources/settings/compiled_resources2.gyp b/chrome/browser/resources/settings/compiled_resources2.gyp
index a0f14ce..11bf999 100644
--- a/chrome/browser/resources/settings/compiled_resources2.gyp
+++ b/chrome/browser/resources/settings/compiled_resources2.gyp
@@ -57,6 +57,7 @@
       'target_name': 'search_settings',
       'dependencies': [
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr',
+        '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:search_highlight_utils',
       ],
       'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
diff --git a/chrome/browser/resources/settings/search_settings.js b/chrome/browser/resources/settings/search_settings.js
index 684aed6..1db1d43 100644
--- a/chrome/browser/resources/settings/search_settings.js
+++ b/chrome/browser/resources/settings/search_settings.js
@@ -18,15 +18,6 @@
 
 cr.define('settings', function() {
   /** @type {string} */
-  const WRAPPER_CSS_CLASS = 'search-highlight-wrapper';
-
-  /** @type {string} */
-  const ORIGINAL_CONTENT_CSS_CLASS = 'search-highlight-original-content';
-
-  /** @type {string} */
-  const HIT_CSS_CLASS = 'search-highlight-hit';
-
-  /** @type {string} */
   const SEARCH_BUBBLE_CSS_CLASS = 'search-bubble';
 
   /**
@@ -65,14 +56,7 @@
    * @private
    */
   function findAndRemoveHighlights_(node) {
-    const wrappers = node.querySelectorAll('* /deep/ .' + WRAPPER_CSS_CLASS);
-
-    for (let i = 0; i < wrappers.length; i++) {
-      const wrapper = wrappers[i];
-      const originalNode =
-          wrapper.querySelector('.' + ORIGINAL_CONTENT_CSS_CLASS);
-      wrapper.parentElement.replaceChild(originalNode.firstChild, wrapper);
-    }
+    cr.search_highlight_utils.findAndRemoveHighlights(node);
 
     const searchBubbles =
         node.querySelectorAll('* /deep/ .' + SEARCH_BUBBLE_CSS_CLASS);
@@ -81,46 +65,6 @@
   }
 
   /**
-   * Applies the highlight UI (yellow rectangle) around all matches in |node|.
-   * @param {!Node} node The text node to be highlighted. |node| ends up
-   *     being removed from the DOM tree.
-   * @param {!Array<string>} tokens The string tokens after splitting on the
-   *     relevant regExp. Even indices hold text that doesn't need highlighting,
-   *     odd indices hold the text to be highlighted. For example:
-   *     const r = new RegExp('(foo)', 'i');
-   *     'barfoobar foo bar'.split(r) => ['bar', 'foo', 'bar ', 'foo', ' bar']
-   * @private
-   */
-  function highlight_(node, tokens) {
-    const wrapper = document.createElement('span');
-    wrapper.classList.add(WRAPPER_CSS_CLASS);
-    // Use existing node as placeholder to determine where to insert the
-    // replacement content.
-    node.parentNode.replaceChild(wrapper, node);
-
-    // Keep the existing node around for when the highlights are removed. The
-    // existing text node might be involved in data-binding and therefore should
-    // not be discarded.
-    const span = document.createElement('span');
-    span.classList.add(ORIGINAL_CONTENT_CSS_CLASS);
-    span.style.display = 'none';
-    span.appendChild(node);
-    wrapper.appendChild(span);
-
-    for (let i = 0; i < tokens.length; ++i) {
-      if (i % 2 == 0) {
-        wrapper.appendChild(document.createTextNode(tokens[i]));
-      } else {
-        const hitSpan = document.createElement('span');
-        hitSpan.classList.add(HIT_CSS_CLASS);
-        hitSpan.style.backgroundColor = '#ffeb3b';  // --var(--paper-yellow-500)
-        hitSpan.textContent = tokens[i];
-        wrapper.appendChild(hitSpan);
-      }
-    }
-  }
-
-  /**
    * Traverses the entire DOM (including Shadow DOM), finds text nodes that
    * match the given regular expression and applies the highlight UI. It also
    * ensures that <settings-section> instances become visible if any matches
@@ -163,8 +107,10 @@
           // displayed within an <option>.
           // TODO(dpapad): highlight <select> controls with a search bubble
           // instead.
-          if (node.parentNode.nodeName != 'OPTION')
-            highlight_(node, textContent.split(request.regExp));
+          if (node.parentNode.nodeName != 'OPTION') {
+            cr.search_highlight_utils.highlight(
+                node, textContent.split(request.regExp));
+          }
         }
         // Returning early since TEXT_NODE nodes never have children.
         return;
diff --git a/chrome/browser/resources/settings/settings_main/settings_main.html b/chrome/browser/resources/settings/settings_main/settings_main.html
index fcbd637..31e3040 100644
--- a/chrome/browser/resources/settings/settings_main/settings_main.html
+++ b/chrome/browser/resources/settings/settings_main/settings_main.html
@@ -2,6 +2,7 @@
 
 <link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html">
 <link rel="import" href="chrome://resources/cr_elements/icons.html">
+<link rel="import" href="chrome://resources/html/search_highlight_utils.html">
 <link rel="import" href="chrome://resources/html/promise_resolver.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-a11y-announcer/iron-a11y-announcer.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_fetcher_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_fetcher_win.cc
index 4f7d227..dddd0694 100644
--- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_fetcher_win.cc
+++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_fetcher_win.cc
@@ -82,7 +82,7 @@
   CLEANER_DOWNLOAD_STATUS_MAX,
 };
 
-net::NetworkTrafficAnnotationTag kTrafficAnnotation =
+net::NetworkTrafficAnnotationTag kChromeCleanerTrafficAnnotation =
     net::DefineNetworkTrafficAnnotation("chrome_cleaner", R"(
       semantics {
         sender: "Chrome Cleaner"
@@ -165,7 +165,7 @@
                                            GetSRTDownloadURL(),
                                            net::URLFetcher::GET,
                                            this,
-                                           kTrafficAnnotation)),
+                                           kChromeCleanerTrafficAnnotation)),
       blocking_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
           {base::MayBlock(), base::TaskPriority::BACKGROUND,
            base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})),
diff --git a/chrome/browser/safe_browsing/incident_reporting/incident_report_uploader_impl.cc b/chrome/browser/safe_browsing/incident_reporting/incident_report_uploader_impl.cc
index 5b344d2..097f6689 100644
--- a/chrome/browser/safe_browsing/incident_reporting/incident_report_uploader_impl.cc
+++ b/chrome/browser/safe_browsing/incident_reporting/incident_report_uploader_impl.cc
@@ -23,8 +23,9 @@
 const char kSbIncidentReportUrl[] =
     "https://sb-ssl.google.com/safebrowsing/clientreport/incident";
 
-constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
-    net::DefineNetworkTrafficAnnotation("safe_browsing_incident", R"(
+constexpr net::NetworkTrafficAnnotationTag
+    kSafeBrowsingIncidentTrafficAnnotation =
+        net::DefineNetworkTrafficAnnotation("safe_browsing_incident", R"(
     semantics {
       sender: "Safe Browsing Incident Reporting"
       description:
@@ -81,11 +82,12 @@
     const scoped_refptr<net::URLRequestContextGetter>& request_context_getter,
     const std::string& post_data)
     : IncidentReportUploader(callback),
-      url_fetcher_(net::URLFetcher::Create(kTestUrlFetcherId,
-                                           GetIncidentReportUrl(),
-                                           net::URLFetcher::POST,
-                                           this,
-                                           kTrafficAnnotation)),
+      url_fetcher_(
+          net::URLFetcher::Create(kTestUrlFetcherId,
+                                  GetIncidentReportUrl(),
+                                  net::URLFetcher::POST,
+                                  this,
+                                  kSafeBrowsingIncidentTrafficAnnotation)),
       time_begin_(base::TimeTicks::Now()) {
   data_use_measurement::DataUseUserData::AttachToFetcher(
       url_fetcher_.get(), data_use_measurement::DataUseUserData::SAFE_BROWSING);
diff --git a/chrome/browser/safe_browsing/notification_image_reporter.cc b/chrome/browser/safe_browsing/notification_image_reporter.cc
index 1a853c2..6ab0479 100644
--- a/chrome/browser/safe_browsing/notification_image_reporter.cc
+++ b/chrome/browser/safe_browsing/notification_image_reporter.cc
@@ -52,8 +52,9 @@
                            net_error);
 }
 
-constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
-    net::DefineNetworkTrafficAnnotation("notification_image_reporter", R"(
+constexpr net::NetworkTrafficAnnotationTag
+    kNotificationImageReporterTrafficAnnotation =
+        net::DefineNetworkTrafficAnnotation("notification_image_reporter", R"(
         semantics {
           sender: "Safe Browsing"
           description:
@@ -91,9 +92,9 @@
 
 NotificationImageReporter::NotificationImageReporter(
     net::URLRequestContext* request_context)
-    : NotificationImageReporter(
-          std::make_unique<net::ReportSender>(request_context,
-                                              kTrafficAnnotation)) {}
+    : NotificationImageReporter(std::make_unique<net::ReportSender>(
+          request_context,
+          kNotificationImageReporterTrafficAnnotation)) {}
 
 NotificationImageReporter::NotificationImageReporter(
     std::unique_ptr<net::ReportSender> report_sender)
diff --git a/chrome/browser/safe_browsing/permission_reporter.cc b/chrome/browser/safe_browsing/permission_reporter.cc
index 6be42a12..518a45e 100644
--- a/chrome/browser/safe_browsing/permission_reporter.cc
+++ b/chrome/browser/safe_browsing/permission_reporter.cc
@@ -112,8 +112,9 @@
   return PermissionReport::GESTURE_TYPE_UNSPECIFIED;
 }
 
-constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
-    net::DefineNetworkTrafficAnnotation("permission_reporting", R"(
+constexpr net::NetworkTrafficAnnotationTag
+    kPermissionReportingTrafficAnnotation =
+        net::DefineNetworkTrafficAnnotation("permission_reporting", R"(
         semantics {
           sender: "Safe Browsing"
           description:
@@ -174,10 +175,10 @@
 }
 
 PermissionReporter::PermissionReporter(net::URLRequestContext* request_context)
-    : PermissionReporter(
-          std::make_unique<net::ReportSender>(request_context,
-                                              kTrafficAnnotation),
-          base::WrapUnique(new base::DefaultClock)) {}
+    : PermissionReporter(std::make_unique<net::ReportSender>(
+                             request_context,
+                             kPermissionReportingTrafficAnnotation),
+                         base::WrapUnique(new base::DefaultClock)) {}
 
 PermissionReporter::PermissionReporter(
     std::unique_ptr<net::ReportSender> report_sender,
diff --git a/chrome/browser/sessions/session_data_deleter.cc b/chrome/browser/sessions/session_data_deleter.cc
index 445445ca..622f0b1 100644
--- a/chrome/browser/sessions/session_data_deleter.cc
+++ b/chrome/browser/sessions/session_data_deleter.cc
@@ -135,7 +135,8 @@
     const content::LocalStorageUsageInfo& usage = usages[i];
     if (!storage_policy_->IsStorageSessionOnly(usage.origin))
       continue;
-    storage_partition->GetDOMStorageContext()->DeleteLocalStorage(usage.origin);
+    storage_partition->GetDOMStorageContext()->DeleteLocalStorage(
+        usage.origin, base::BindOnce(&base::DoNothing));
   }
 }
 
diff --git a/chrome/browser/spellchecker/spell_check_host_chrome_impl.cc b/chrome/browser/spellchecker/spell_check_host_chrome_impl.cc
index 0aafa6a..94fdcfd 100644
--- a/chrome/browser/spellchecker/spell_check_host_chrome_impl.cc
+++ b/chrome/browser/spellchecker/spell_check_host_chrome_impl.cc
@@ -18,7 +18,7 @@
 
 SpellCheckHostChromeImpl::SpellCheckHostChromeImpl(
     const service_manager::Identity& renderer_identity)
-    : renderer_identity_(renderer_identity) {}
+    : renderer_identity_(renderer_identity), weak_factory_(this) {}
 
 SpellCheckHostChromeImpl::~SpellCheckHostChromeImpl() = default;
 
@@ -83,7 +83,7 @@
   client_.RequestTextCheck(
       context, SpellingServiceClient::SPELLCHECK, text,
       base::BindOnce(&SpellCheckHostChromeImpl::CallSpellingServiceDone,
-                     base::Unretained(this), base::Passed(&callback)));
+                     weak_factory_.GetWeakPtr(), base::Passed(&callback)));
 #else
   std::move(callback).Run(false, std::vector<SpellCheckResult>());
 #endif
diff --git a/chrome/browser/spellchecker/spell_check_host_chrome_impl.h b/chrome/browser/spellchecker/spell_check_host_chrome_impl.h
index 1e712fc..a2466f1 100644
--- a/chrome/browser/spellchecker/spell_check_host_chrome_impl.h
+++ b/chrome/browser/spellchecker/spell_check_host_chrome_impl.h
@@ -65,6 +65,8 @@
   // A JSON-RPC client that calls the remote Spelling service.
   SpellingServiceClient client_;
 
+  base::WeakPtrFactory<SpellCheckHostChromeImpl> weak_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(SpellCheckHostChromeImpl);
 };
 
diff --git a/chrome/browser/ssl/bad_clock_blocking_page.cc b/chrome/browser/ssl/bad_clock_blocking_page.cc
index c00ef64..1893aa3 100644
--- a/chrome/browser/ssl/bad_clock_blocking_page.cc
+++ b/chrome/browser/ssl/bad_clock_blocking_page.cc
@@ -34,17 +34,17 @@
 
 namespace {
 
-const char kMetricsName[] = "bad_clock";
+const char kBadClockMetricsName[] = "bad_clock";
 
-std::unique_ptr<ChromeMetricsHelper> CreateMetricsHelper(
+std::unique_ptr<ChromeMetricsHelper> CreateBadClockMetricsHelper(
     content::WebContents* web_contents,
     const GURL& request_url) {
   // Set up the metrics helper for the BadClockUI.
   security_interstitials::MetricsHelper::ReportDetails reporting_info;
-  reporting_info.metric_prefix = kMetricsName;
+  reporting_info.metric_prefix = kBadClockMetricsName;
   std::unique_ptr<ChromeMetricsHelper> metrics_helper =
-      std::make_unique<ChromeMetricsHelper>(web_contents, request_url,
-                                            reporting_info, kMetricsName);
+      std::make_unique<ChromeMetricsHelper>(
+          web_contents, request_url, reporting_info, kBadClockMetricsName);
   metrics_helper.get()->StartRecordingCaptivePortalMetrics(false);
   return metrics_helper;
 }
@@ -80,7 +80,7 @@
               web_contents,
               ssl_info,
               request_url,
-              CreateMetricsHelper(web_contents, request_url))),
+              CreateBadClockMetricsHelper(web_contents, request_url))),
       callback_(callback),
       ssl_info_(ssl_info),
       bad_clock_ui_(new security_interstitials::BadClockUI(request_url,
diff --git a/chrome/browser/ssl/captive_portal_blocking_page.cc b/chrome/browser/ssl/captive_portal_blocking_page.cc
index fbc321e..52785d67 100644
--- a/chrome/browser/ssl/captive_portal_blocking_page.cc
+++ b/chrome/browser/ssl/captive_portal_blocking_page.cc
@@ -46,16 +46,16 @@
 
 namespace {
 
-const char kMetricsName[] = "captive_portal";
+const char kCaptivePortalMetricsName[] = "captive_portal";
 
-std::unique_ptr<ChromeMetricsHelper> CreateMetricsHelper(
+std::unique_ptr<ChromeMetricsHelper> CreateCaptivePortalMetricsHelper(
     content::WebContents* web_contents,
     const GURL& request_url) {
   security_interstitials::MetricsHelper::ReportDetails reporting_info;
-  reporting_info.metric_prefix = kMetricsName;
+  reporting_info.metric_prefix = kCaptivePortalMetricsName;
   std::unique_ptr<ChromeMetricsHelper> metrics_helper =
-      std::make_unique<ChromeMetricsHelper>(web_contents, request_url,
-                                            reporting_info, kMetricsName);
+      std::make_unique<ChromeMetricsHelper>(
+          web_contents, request_url, reporting_info, kCaptivePortalMetricsName);
   metrics_helper.get()->StartRecordingCaptivePortalMetrics(false);
   return metrics_helper;
 }
@@ -85,7 +85,7 @@
               web_contents,
               ssl_info,
               request_url,
-              CreateMetricsHelper(web_contents, request_url))),
+              CreateCaptivePortalMetricsHelper(web_contents, request_url))),
       login_url_(login_url),
       ssl_info_(ssl_info),
       callback_(callback) {
diff --git a/chrome/browser/ssl/chrome_expect_ct_reporter.cc b/chrome/browser/ssl/chrome_expect_ct_reporter.cc
index e03ecc7..f2a223c 100644
--- a/chrome/browser/ssl/chrome_expect_ct_reporter.cc
+++ b/chrome/browser/ssl/chrome_expect_ct_reporter.cc
@@ -115,8 +115,9 @@
   list->Append(std::move(list_item));
 }
 
-constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
-    net::DefineNetworkTrafficAnnotation("chrome_expect_ct_reporter", R"(
+constexpr net::NetworkTrafficAnnotationTag
+    kChromeExpectCtReporterTrafficAnnotation =
+        net::DefineNetworkTrafficAnnotation("chrome_expect_ct_reporter", R"(
         semantics {
           sender: "Expect-CT reporting for Certificate Transparency reporting"
           description:
@@ -147,7 +148,8 @@
     const base::Closure& success_callback,
     const base::Closure& failure_callback)
     : report_sender_(
-          new net::ReportSender(request_context, kTrafficAnnotation)),
+          new net::ReportSender(request_context,
+                                kChromeExpectCtReporterTrafficAnnotation)),
       request_context_(request_context),
       success_callback_(success_callback),
       failure_callback_(failure_callback) {}
@@ -262,7 +264,7 @@
     const std::string& serialized_report) {
   std::unique_ptr<net::URLRequest> url_request =
       request_context_->CreateRequest(report_uri, net::DEFAULT_PRIORITY, this,
-                                      kTrafficAnnotation);
+                                      kChromeExpectCtReporterTrafficAnnotation);
   url_request->SetLoadFlags(net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE |
                             net::LOAD_DO_NOT_SEND_AUTH_DATA |
                             net::LOAD_DO_NOT_SEND_COOKIES |
diff --git a/chrome/browser/ssl/mitm_software_blocking_page.cc b/chrome/browser/ssl/mitm_software_blocking_page.cc
index 2b12a5fc..458d355 100644
--- a/chrome/browser/ssl/mitm_software_blocking_page.cc
+++ b/chrome/browser/ssl/mitm_software_blocking_page.cc
@@ -33,17 +33,17 @@
 
 namespace {
 
-const char kMetricsName[] = "mitm_software";
+const char kMitmSoftwareMetricsName[] = "mitm_software";
 
-std::unique_ptr<ChromeMetricsHelper> CreateMetricsHelper(
+std::unique_ptr<ChromeMetricsHelper> CreateMitmSoftwareMetricsHelper(
     content::WebContents* web_contents,
     const GURL& request_url) {
   // Set up the metrics helper for the MITMSoftwareUI.
   security_interstitials::MetricsHelper::ReportDetails reporting_info;
-  reporting_info.metric_prefix = kMetricsName;
+  reporting_info.metric_prefix = kMitmSoftwareMetricsName;
   std::unique_ptr<ChromeMetricsHelper> metrics_helper =
-      std::make_unique<ChromeMetricsHelper>(web_contents, request_url,
-                                            reporting_info, kMetricsName);
+      std::make_unique<ChromeMetricsHelper>(
+          web_contents, request_url, reporting_info, kMitmSoftwareMetricsName);
   metrics_helper.get()->StartRecordingCaptivePortalMetrics(false);
   return metrics_helper;
 }
@@ -80,7 +80,7 @@
               web_contents,
               ssl_info,
               request_url,
-              CreateMetricsHelper(web_contents, request_url))),
+              CreateMitmSoftwareMetricsHelper(web_contents, request_url))),
       callback_(callback),
       ssl_info_(ssl_info),
       mitm_software_ui_(
diff --git a/chrome/browser/ssl/ssl_blocking_page.cc b/chrome/browser/ssl/ssl_blocking_page.cc
index ee75c49..d5cbe31 100644
--- a/chrome/browser/ssl/ssl_blocking_page.cc
+++ b/chrome/browser/ssl/ssl_blocking_page.cc
@@ -58,7 +58,7 @@
   return event_name;
 }
 
-std::unique_ptr<ChromeMetricsHelper> CreateMetricsHelper(
+std::unique_ptr<ChromeMetricsHelper> CreateSslProblemMetricsHelper(
     content::WebContents* web_contents,
     int cert_error,
     const GURL& request_url,
@@ -96,8 +96,9 @@
     const base::Callback<void(content::CertificateRequestResultType)>&
         callback) {
   bool overridable = IsOverridable(options_mask);
-  std::unique_ptr<ChromeMetricsHelper> metrics_helper(CreateMetricsHelper(
-      web_contents, cert_error, request_url, overridable, is_superfish));
+  std::unique_ptr<ChromeMetricsHelper> metrics_helper(
+      CreateSslProblemMetricsHelper(web_contents, cert_error, request_url,
+                                    overridable, is_superfish));
   metrics_helper.get()->StartRecordingCaptivePortalMetrics(overridable);
 
   return new SSLBlockingPage(web_contents, cert_error, ssl_info, request_url,
diff --git a/chrome/browser/ssl/ssl_error_tab_helper_unittest.cc b/chrome/browser/ssl/ssl_error_tab_helper_unittest.cc
index c30fe6d0..0a5a3f09 100644
--- a/chrome/browser/ssl/ssl_error_tab_helper_unittest.cc
+++ b/chrome/browser/ssl/ssl_error_tab_helper_unittest.cc
@@ -21,14 +21,14 @@
 
 namespace {
 
-const char kMetricsName[] = "test_ssl_blocking_page";
+const char kTestSslMetricsName[] = "test_ssl_blocking_page";
 
-std::unique_ptr<ChromeMetricsHelper> CreateMetricsHelper(
+std::unique_ptr<ChromeMetricsHelper> CreateTestSslMetricsHelper(
     content::WebContents* web_contents) {
   security_interstitials::MetricsHelper::ReportDetails report_details;
-  report_details.metric_prefix = kMetricsName;
-  return std::make_unique<ChromeMetricsHelper>(web_contents, GURL(),
-                                               report_details, kMetricsName);
+  report_details.metric_prefix = kTestSslMetricsName;
+  return std::make_unique<ChromeMetricsHelper>(
+      web_contents, GURL(), report_details, kTestSslMetricsName);
 }
 
 class TestSSLBlockingPage : public SSLBlockingPage {
@@ -47,7 +47,7 @@
             GURL(),
             nullptr /* ssl_cert_reporter */,
             true /* overridable */,
-            CreateMetricsHelper(web_contents),
+            CreateTestSslMetricsHelper(web_contents),
             false /* is_superfish */,
             base::Callback<void(content::CertificateRequestResultType)>()),
         destroyed_tracker_(destroyed_tracker) {}
diff --git a/chrome/browser/sync_file_system/drive_backend/sync_engine.cc b/chrome/browser/sync_file_system/drive_backend/sync_engine.cc
index 1cad396..afc34f48 100644
--- a/chrome/browser/sync_file_system/drive_backend/sync_engine.cc
+++ b/chrome/browser/sync_file_system/drive_backend/sync_engine.cc
@@ -72,7 +72,7 @@
 
 namespace drive_backend {
 
-constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
+constexpr net::NetworkTrafficAnnotationTag kSyncFileSystemTrafficAnnotation =
     net::DefineNetworkTrafficAnnotation("sync_file_system", R"(
         semantics {
           sender: "Sync FileSystem Chrome API"
@@ -106,7 +106,7 @@
       GURL(google_apis::DriveApiUrlGenerator::kBaseUrlForProduction),
       GURL(google_apis::DriveApiUrlGenerator::kBaseThumbnailUrlForProduction),
       std::string(), /* custom_user_agent */
-      kTrafficAnnotation));
+      kSyncFileSystemTrafficAnnotation));
 }
 
 class SyncEngine::WorkerObserver : public SyncWorkerInterface::Observer {
diff --git a/chrome/browser/ui/passwords/account_avatar_fetcher.cc b/chrome/browser/ui/passwords/account_avatar_fetcher.cc
index bb515fc..9ddb45c 100644
--- a/chrome/browser/ui/passwords/account_avatar_fetcher.cc
+++ b/chrome/browser/ui/passwords/account_avatar_fetcher.cc
@@ -12,7 +12,7 @@
 
 namespace {
 
-constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
+constexpr net::NetworkTrafficAnnotationTag kAccountAvatarTrafficAnnotation =
     net::DefineNetworkTrafficAnnotation("credenential_avatar", R"(
         semantics {
           sender: "Chrome Password Manager"
@@ -48,7 +48,8 @@
 AccountAvatarFetcher::AccountAvatarFetcher(
     const GURL& url,
     const base::WeakPtr<AccountAvatarFetcherDelegate>& delegate)
-    : fetcher_(url, this, kTrafficAnnotation), delegate_(delegate) {}
+    : fetcher_(url, this, kAccountAvatarTrafficAnnotation),
+      delegate_(delegate) {}
 
 AccountAvatarFetcher::~AccountAvatarFetcher() = default;
 
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc b/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc
index 95fbb2a..54ad8f06 100644
--- a/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc
@@ -312,7 +312,11 @@
   } else if (state_ == password_manager::ui::MANAGE_STATE) {
     local_credentials_ = DeepCopyForms(delegate_->GetCurrentForms());
     UpdateManageStateTitle();
-    manage_link_ = l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_BUBBLE_LINK);
+    // TODO(pbos): Remove manage_link_ + accessors when the cocoa dialog goes
+    // away. This temporarily uses the button label which is equivalent with
+    // the previous link.
+    manage_link_ =
+        l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_MANAGE_PASSWORDS_BUTTON);
   }
 
   if (state_ == password_manager::ui::CONFIRMATION_STATE) {
diff --git a/chrome/browser/ui/views/passwords/password_items_view.cc b/chrome/browser/ui/views/passwords/password_items_view.cc
index 464c1e8e..8c428a8 100644
--- a/chrome/browser/ui/views/passwords/password_items_view.cc
+++ b/chrome/browser/ui/views/passwords/password_items_view.cc
@@ -269,7 +269,8 @@
 
 views::View* PasswordItemsView::CreateExtraView() {
   return views::MdTextButton::CreateSecondaryUiButton(
-      this, l10n_util::GetStringUTF16(IDS_MANAGE_PASSWORDS_BUBBLE_LINK));
+      this,
+      l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_MANAGE_PASSWORDS_BUTTON));
 }
 
 int PasswordItemsView::GetDialogButtons() const {
diff --git a/chrome/browser/ui/views/sync/OWNERS b/chrome/browser/ui/views/sync/OWNERS
new file mode 100644
index 0000000..21cdbb2
--- /dev/null
+++ b/chrome/browser/ui/views/sync/OWNERS
@@ -0,0 +1,4 @@
+msarda@chromium.org
+
+# TEAM: chrome-signin@chromium.org
+# COMPONENT: Services>SignIn
diff --git a/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.cc
index 409c352..f2b9c87 100644
--- a/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/encryption_migration_screen_handler.cc
@@ -573,8 +573,8 @@
     auth_request = CreateAuthorizationRequest();
   }
   DBusThreadManager::Get()->GetCryptohomeClient()->MountEx(
-      cryptohome::Identification(user_context_.GetAccountId()),
-      cryptohome::AuthorizationRequest(), mount,
+      cryptohome::Identification(user_context_.GetAccountId()), auth_request,
+      mount,
       base::BindOnce(&EncryptionMigrationScreenHandler::OnMountExistingVault,
                      weak_ptr_factory_.GetWeakPtr()));
 }
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
index 8b809eb..41d6a2e 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -1485,7 +1485,7 @@
     lock_screen_utils::SetUserInputMethod(account_id.GetUserEmail(),
                                           ime_state_.get());
     lock_screen_utils::SetKeyboardSettings(account_id);
-    if (LoginDisplayHost::default_host() && load_wallpaper)
+    if (delegate_ && load_wallpaper)
       LoginDisplayHost::default_host()->LoadWallpaper(account_id);
 
     bool use_24hour_clock = false;
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.cc b/chrome/browser/ui/webui/settings/site_settings_handler.cc
index d02fe762..52841b9 100644
--- a/chrome/browser/ui/webui/settings/site_settings_handler.cc
+++ b/chrome/browser/ui/webui/settings/site_settings_handler.cc
@@ -9,6 +9,7 @@
 #include <string>
 #include <utility>
 
+#include "base/barrier_closure.h"
 #include "base/bind.h"
 #include "base/i18n/number_formatting.h"
 #include "base/macros.h"
@@ -251,14 +252,18 @@
   }
 }
 
-void SiteSettingsHandler::OnUsageInfoCleared(
-    blink::mojom::QuotaStatusCode code) {
+void SiteSettingsHandler::OnStorageCleared(base::OnceClosure callback,
+                                           blink::mojom::QuotaStatusCode code) {
   if (code == blink::mojom::QuotaStatusCode::kOk) {
-    CallJavascriptFunction("settings.WebsiteUsagePrivateApi.onUsageCleared",
-                           base::Value(clearing_origin_));
+    std::move(callback).Run();
   }
 }
 
+void SiteSettingsHandler::OnUsageCleared() {
+  CallJavascriptFunction("settings.WebsiteUsagePrivateApi.onUsageCleared",
+                         base::Value(clearing_origin_));
+}
+
 #if defined(OS_CHROMEOS)
 void SiteSettingsHandler::OnPrefEnableDrmChanged() {
   CallJavascriptFunction("cr.webUIListenerCallback",
@@ -358,19 +363,25 @@
   if (url.is_valid()) {
     clearing_origin_ = origin;
 
+    // Call OnUsageCleared when StorageInfoFetcher::ClearStorage and
+    // BrowsingDataLocalStorageHelper::DeleteOrigin are done.
+    base::RepeatingClosure barrier = base::BarrierClosure(
+        2, base::BindOnce(&SiteSettingsHandler::OnUsageCleared,
+                          base::Unretained(this)));
+
     // Start by clearing the storage data asynchronously.
     scoped_refptr<StorageInfoFetcher> storage_info_fetcher
         = new StorageInfoFetcher(profile_);
     storage_info_fetcher->ClearStorage(
         url.host(),
         static_cast<blink::mojom::StorageType>(static_cast<int>(storage_type)),
-        base::Bind(&SiteSettingsHandler::OnUsageInfoCleared,
-                   base::Unretained(this)));
+        base::BindRepeating(&SiteSettingsHandler::OnStorageCleared,
+                            base::Unretained(this), barrier));
 
     // Also clear the *local* storage data.
     scoped_refptr<BrowsingDataLocalStorageHelper> local_storage_helper =
         new BrowsingDataLocalStorageHelper(profile_);
-    local_storage_helper->DeleteOrigin(url);
+    local_storage_helper->DeleteOrigin(url, barrier);
   }
 }
 
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.h b/chrome/browser/ui/webui/settings/site_settings_handler.h
index 9761de8..005a682 100644
--- a/chrome/browser/ui/webui/settings/site_settings_handler.h
+++ b/chrome/browser/ui/webui/settings/site_settings_handler.h
@@ -47,7 +47,9 @@
 
   // Usage info.
   void OnGetUsageInfo(const storage::UsageInfoEntries& entries);
-  void OnUsageInfoCleared(blink::mojom::QuotaStatusCode code);
+  void OnStorageCleared(base::OnceClosure callback,
+                        blink::mojom::QuotaStatusCode code);
+  void OnUsageCleared();
 
 #if defined(OS_CHROMEOS)
   // Alert the Javascript that the |kEnableDRM| pref has changed.
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index 9d137c4..9f82f3b 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -184,12 +184,6 @@
 const base::Feature kClipboardContentSetting{"ClipboardContentSetting",
                                              base::FEATURE_DISABLED_BY_DEFAULT};
 
-#if defined(OS_ANDROID)
-// Experiment to extract structured metadata for app indexing.
-const base::Feature kCopylessPaste{"CopylessPaste",
-                                   base::FEATURE_ENABLED_BY_DEFAULT};
-#endif
-
 #if defined(OS_CHROMEOS)
 // Enable project Crostini, Linux VMs on Chrome OS.
 const base::Feature kCrostini{"Crostini", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h
index f7610f7..f404e9b6 100644
--- a/chrome/common/chrome_features.h
+++ b/chrome/common/chrome_features.h
@@ -95,10 +95,6 @@
 extern const base::Feature kContentFullscreen;
 #endif
 
-#if defined(OS_ANDROID)
-extern const base::Feature kCopylessPaste;
-#endif
-
 #if defined(OS_CHROMEOS)
 extern const base::Feature kCrostini;
 #endif
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 5aa0d5c..959b767 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -2546,6 +2546,11 @@
 // Boolean that specifies opting into --site-per-process (full Site Isolation).
 const char kSitePerProcess[] = "site_isolation.site_per_process";
 
+// Boolean that specifies if the web driver flag is allowed to override policies
+// which prevent it from operating normally. (e.g. SitePerProcess.)
+const char kWebDriverOverridesIncompatiblePolicies[] =
+    "webdriver.override_incompatible_policy";
+
 #if defined(OS_WIN)
 // A boolean value, controlling whether third party software is allowed to
 // inject into Chrome's processes.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 972bd800..d2ea385a 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -913,6 +913,7 @@
 
 extern const char kIsolateOrigins[];
 extern const char kSitePerProcess[];
+extern const char kWebDriverOverridesIncompatiblePolicies[];
 
 #if defined(OS_WIN)
 // Preference for controlling whether or not third party blocking is enabled on
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 59799f2..fb817a83 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -283,6 +283,7 @@
     "//testing/scripts/common.py",
     "//testing/xvfb.py",
     "//testing/scripts/run_gpu_integration_test_as_googletest.py",
+    "//testing/trigger_scripts/trigger_multiple_dimensions.py",
 
     "//content/test/gpu/",
     "//content/test/data/gpu/",
diff --git a/chrome/test/data/extensions/api_test/windows/events/test.js b/chrome/test/data/extensions/api_test/windows/events/test.js
index a10aaf72..e8e9841 100644
--- a/chrome/test/data/extensions/api_test/windows/events/test.js
+++ b/chrome/test/data/extensions/api_test/windows/events/test.js
@@ -73,8 +73,11 @@
         chrome.test.assertTrue(win.focus == true,
                                'Missing focus event for ' + win.type);
     }
-    chrome.test.assertEq(3, unfilteredCount);
-    chrome.test.assertTrue(includes_app && includes_devtools,
+    chrome.test.assertEq(2, unfilteredCount);
+    chrome.test.assertFalse(
+        includes_app,
+        'Should not include windows for a separate platform app.');
+    chrome.test.assertTrue(includes_devtools,
                            'Could not find app or devtools windows');
 
     chrome.test.notifyPass();
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json
index ffa06370..cb9ec79 100644
--- a/chrome/test/data/policy/policy_test_cases.json
+++ b/chrome/test/data/policy/policy_test_cases.json
@@ -1,5 +1,6 @@
 {
   "-- Template --": {
+    "intro": "Tests that policies map to prefs properly and whether the corresponding Chrome settings UI behaves properly, e.g. if a policy is managed, the UI should be readonly and an icon with a properly worded tooltip should show up.",
     "intro": "Top-level entries map a policy name to its test parameters, described below. The name of the top level entry should be of the form <policy name>[.suffix]. The optional suffix is used for defining multiple test cases for a single policy.",
 
     "os": ["List of operating systems that support this policy. Valid values:", "win", "linux", "mac", "chromeos", "android", "Defaults to empty if not specified."],
@@ -874,6 +875,16 @@
     "note": "There is a pref behind this setting, but due to the fact that tests override the default with a command-line flag on some trybots, this setting cannot be verified with the common test."
   },
 
+  "WebDriverOverridesIncompatiblePolicies": {
+    "os": ["win", "linux", "mac"],
+    "test_policy": { "WebDriverOverridesIncompatiblePolicies": true },
+    "pref_mappings": [
+      { "pref": "webdriver.override_incompatible_policy",
+        "local_state": true
+      }
+    ]
+  },
+
   "DefaultDownloadDirectory": {
     "os": ["win", "linux", "mac", "chromeos"],
     "test_policy": { "DefaultDownloadDirectory": "${user_home}/test-downloads" },
@@ -3486,6 +3497,16 @@
     ]
   },
 
+  "DeviceOffHours": {
+    "os": ["chromeos"],
+    "test_policy": {"DeviceOffHours": {"intervals": [{"start" : {"day_of_week" : 1, "time": 12840000}, "end": {"day_of_week" : 1, "time": 21720000}}], "timezone" : "GMT", "ignored_policy_proto_tags": [8, 3]}}
+  },
+
+  "DeviceKerberosEncryptionTypes": {
+    "os": ["chromeos"],
+    "note": "Chrome OS device policy used by authpolicyd only, not used in Chrome"
+  },
+
   "----- Chrome Frame policies -------------------------------------------": {},
 
   "ChromeFrameRendererSettings": {
@@ -3510,10 +3531,5 @@
   },
 
   "SkipMetadataCheck": {
-  },
-
-  "DeviceOffHours": {
-    "os": ["chromeos"],
-    "test_policy": {"DeviceOffHours": {"intervals": [{"start" : {"day_of_week" : 1, "time": 12840000}, "end": {"day_of_week" : 1, "time": 21720000}}], "timezone" : "GMT", "ignored_policy_proto_tags": [8, 3]}}
   }
 }
diff --git a/chrome/test/data/webrtc/adapter.js b/chrome/test/data/webrtc/adapter.js
deleted file mode 100644
index 4aac6ea..0000000
--- a/chrome/test/data/webrtc/adapter.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-var getUserMedia = null;
-var attachMediaStream = null;
-
-function trace(text) {
-  // This function is used for logging.
-  if (text[text.length - 1] == '\n') {
-    text = text.substring(0, text.length - 1);
-  }
-  console.log((performance.now() / 1000).toFixed(3) + ": " + text);
-}
-
-getUserMedia = navigator.getUserMedia.bind(navigator);
-
-// Attach a media stream to an element.
-attachMediaStream = function(element, stream) {
-  element.srcObject = stream;
-}
diff --git a/chrome/test/data/webrtc/getusermedia.js b/chrome/test/data/webrtc/getusermedia.js
index 64edac63..00a0f568 100644
--- a/chrome/test/data/webrtc/getusermedia.js
+++ b/chrome/test/data/webrtc/getusermedia.js
@@ -50,13 +50,13 @@
  *     on the WebRTC version.
  */
 function doGetUserMedia(constraints) {
-  if (!getUserMedia) {
+  if (!navigator.getUserMedia) {
     returnToTest('Browser does not support WebRTC.');
     return;
   }
   debug('Requesting doGetUserMedia: constraints: ' +
         JSON.stringify(constraints, null, 0).replace(/[\r\n]/g, ''));
-  getUserMedia(constraints,
+  navigator.getUserMedia(constraints,
                function(stream) {
                  ensureGotAllExpectedStreams_(stream, constraints);
                  getUserMediaOkCallback_(stream);
@@ -154,7 +154,7 @@
   gLocalStream = stream;
   gRequestWebcamAndMicrophoneResult = 'ok-got-stream';
 
-  attachMediaStream($('local-view'), stream);
+  $('local-view').srcObject = stream;
 
   returnToTest('request-callback-granted');
 }
diff --git a/chrome/test/data/webrtc/peerconnection.js b/chrome/test/data/webrtc/peerconnection.js
index 7046120..7d921f2 100644
--- a/chrome/test/data/webrtc/peerconnection.js
+++ b/chrome/test/data/webrtc/peerconnection.js
@@ -568,7 +568,7 @@
 function addStreamCallback_(event) {
   debug('Receiving remote stream...');
   var videoTag = document.getElementById('remote-view');
-  attachMediaStream(videoTag, event.stream);
+  videoTag.srcObject = event.stream;
 }
 
 /** @private */
diff --git a/chrome/test/data/webrtc/peerconnection_rtp.js b/chrome/test/data/webrtc/peerconnection_rtp.js
index eefc96e77..2b90098 100644
--- a/chrome/test/data/webrtc/peerconnection_rtp.js
+++ b/chrome/test/data/webrtc/peerconnection_rtp.js
@@ -16,7 +16,7 @@
  */
 function createAndAddStreams(count) {
   if (count > 0) {
-    getUserMedia({ audio: true, video: true },
+    navigator.getUserMedia({ audio: true, video: true },
         function(stream) {
           peerConnection_().addStream(stream);
           createAndAddStreams(count - 1);
@@ -117,7 +117,7 @@
       streamArgumentType !== 'shared-stream' &&
       streamArgumentType !== 'individual-streams')
     throw failTest('Unsupported streamArgumentType.');
-  getUserMedia({ audio: true, video: true },
+  navigator.getUserMedia({ audio: true, video: true },
       function(stream) {
         let audioStream = undefined;
         if (streamArgumentType !== 'no-stream')
diff --git a/chrome/test/data/webrtc/webrtc_audio_quality_test.html b/chrome/test/data/webrtc/webrtc_audio_quality_test.html
index 3601a23c..83cdf6f 100644
--- a/chrome/test/data/webrtc/webrtc_audio_quality_test.html
+++ b/chrome/test/data/webrtc/webrtc_audio_quality_test.html
@@ -2,7 +2,6 @@
 <html>
 <head>
   <title>WebRTC Automated Test</title>
-  <script type="text/javascript" src="adapter.js"></script>
   <script type="text/javascript" src="test_functions.js"></script>
   <script type="text/javascript" src="peerconnection.js"></script>
   <script type="text/javascript" src="munge_sdp.js"></script>
diff --git a/chrome/test/data/webrtc/webrtc_jsep01_test.html b/chrome/test/data/webrtc/webrtc_jsep01_test.html
index 4b087180..400356c 100644
--- a/chrome/test/data/webrtc/webrtc_jsep01_test.html
+++ b/chrome/test/data/webrtc/webrtc_jsep01_test.html
@@ -2,7 +2,6 @@
 <html>
 <head>
   <title>WebRTC Automated Test</title>
-  <script type="text/javascript" src="adapter.js"></script>
   <script type="text/javascript" src="test_functions.js"></script>
   <script type="text/javascript" src="peerconnection.js"></script>
   <script type="text/javascript" src="munge_sdp.js"></script>
diff --git a/chrome/test/data/webrtc/webrtc_video_quality_test.html b/chrome/test/data/webrtc/webrtc_video_quality_test.html
index 06404ba..2b467967 100644
--- a/chrome/test/data/webrtc/webrtc_video_quality_test.html
+++ b/chrome/test/data/webrtc/webrtc_video_quality_test.html
@@ -2,7 +2,6 @@
 <html>
 <head>
   <title>WebRTC Automated Test</title>
-  <script type="text/javascript" src="adapter.js"></script>
   <script type="text/javascript" src="test_functions.js"></script>
   <script type="text/javascript" src="peerconnection.js"></script>
   <script type="text/javascript" src="munge_sdp.js"></script>
diff --git a/chrome/test/data/webui/settings/search_settings_test.js b/chrome/test/data/webui/settings/search_settings_test.js
index 6dd6f14..6a5fe1e0 100644
--- a/chrome/test/data/webui/settings/search_settings_test.js
+++ b/chrome/test/data/webui/settings/search_settings_test.js
@@ -10,7 +10,9 @@
     // Don't import script if already imported (happens in Vulcanized mode).
     suiteSetup(function() {
       if (!window.settings || !settings.getSearchManager) {
-        return PolymerTest.loadScript('chrome://settings/search_settings.js');
+        return PolymerTest.loadScript(
+                   'chrome://resources/js/search_highlight_utils.js') &&
+            PolymerTest.loadScript('chrome://settings/search_settings.js');
       }
     });
 
diff --git a/chromecast/media/cma/pipeline/audio_decoder_software_wrapper.cc b/chromecast/media/cma/pipeline/audio_decoder_software_wrapper.cc
index 08870d7..5cdbc15f 100644
--- a/chromecast/media/cma/pipeline/audio_decoder_software_wrapper.cc
+++ b/chromecast/media/cma/pipeline/audio_decoder_software_wrapper.cc
@@ -8,6 +8,7 @@
 
 #include "base/bind.h"
 #include "base/logging.h"
+#include "base/stl_util.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chromecast/media/cma/base/decoder_buffer_base.h"
 #include "chromecast/media/cma/base/decoder_config_logging.h"
@@ -33,12 +34,18 @@
   return false;
 }
 
+// Codecs that cannot be decoded on the device and must be passed through.
+constexpr media::AudioCodec kPassthroughCodecs[] = {
+    kCodecEAC3, kCodecAC3, kCodecDTS,
+};
+
 } // namespace
 
 AudioDecoderSoftwareWrapper::AudioDecoderSoftwareWrapper(
     MediaPipelineBackend::AudioDecoder* backend_decoder)
     : backend_decoder_(backend_decoder),
       delegate_(nullptr),
+      decoder_error_(false),
       weak_factory_(this) {
   DCHECK(backend_decoder_);
   backend_decoder_->SetDelegate(this);
@@ -49,6 +56,9 @@
 void AudioDecoderSoftwareWrapper::SetDelegate(DecoderDelegate* delegate) {
   DCHECK(delegate);
   delegate_ = delegate;
+  if (decoder_error_) {
+    delegate_->OnDecoderError();
+  }
 }
 
 MediaPipelineBackend::BufferStatus AudioDecoderSoftwareWrapper::PushBuffer(
@@ -73,7 +83,6 @@
 }
 
 bool AudioDecoderSoftwareWrapper::SetConfig(const AudioConfig& config) {
-  DCHECK(delegate_);
   DCHECK(IsValidConfig(config));
 
   if (backend_decoder_->SetConfig(config)) {
@@ -83,6 +92,11 @@
     return true;
   }
 
+  if (base::ContainsValue(kPassthroughCodecs, config.codec)) {
+    LOG(INFO) << "Cannot use software decoder for " << config.codec;
+    return false;
+  }
+
   if (!CreateSoftwareDecoder(config)) {
     LOG(INFO) << "Failed to create software decoder for " << config.codec;
     return false;
@@ -132,14 +146,18 @@
 
 void AudioDecoderSoftwareWrapper::OnDecoderInitialized(bool success) {
   if (!success) {
+    decoder_error_ = true;
     LOG(ERROR) << "Failed to initialize software decoder";
-    delegate_->OnDecoderError();
+    if (delegate_) {
+      delegate_->OnDecoderError();
+    }
   }
 }
 
 void AudioDecoderSoftwareWrapper::OnDecodedBuffer(
     CastAudioDecoder::Status status,
     const scoped_refptr<DecoderBufferBase>& decoded) {
+  DCHECK(delegate_);
   if (status != CastAudioDecoder::kDecodeOk) {
     delegate_->OnPushBufferComplete(MediaPipelineBackend::kBufferFailed);
     return;
diff --git a/chromecast/media/cma/pipeline/audio_decoder_software_wrapper.h b/chromecast/media/cma/pipeline/audio_decoder_software_wrapper.h
index 738c18de3..2872dba 100644
--- a/chromecast/media/cma/pipeline/audio_decoder_software_wrapper.h
+++ b/chromecast/media/cma/pipeline/audio_decoder_software_wrapper.h
@@ -59,6 +59,7 @@
   std::unique_ptr<CastAudioDecoder> software_decoder_;
   AudioConfig output_config_;
   scoped_refptr<DecoderBufferBase> pending_pushed_buffer_;
+  bool decoder_error_;
 
   base::WeakPtrFactory<AudioDecoderSoftwareWrapper> weak_factory_;
 
diff --git a/chromeos/network/client_cert_resolver.cc b/chromeos/network/client_cert_resolver.cc
index 2f7fc21..63911196 100644
--- a/chromeos/network/client_cert_resolver.cc
+++ b/chromeos/network/client_cert_resolver.cc
@@ -14,6 +14,7 @@
 #include "base/bind.h"
 #include "base/location.h"
 #include "base/logging.h"
+#include "base/optional.h"
 #include "base/stl_util.h"
 #include "base/strings/string_util.h"
 #include "base/task_scheduler/post_task.h"
@@ -32,28 +33,29 @@
 
 namespace chromeos {
 
-// Describes a network |network_path| for which a matching certificate |cert_id|
-// was found or for which no certificate was found (|cert_id| will be empty).
-struct ClientCertResolver::NetworkAndMatchingCert {
-  NetworkAndMatchingCert(const std::string& network_path,
-                         client_cert::ConfigType config_type,
-                         const std::string& cert_id,
-                         int slot_id,
-                         const std::string& configured_identity)
-      : service_path(network_path),
-        cert_config_type(config_type),
-        pkcs11_id(cert_id),
-        key_slot_id(slot_id),
+namespace {
+
+// Describes a resolved client certificate along with the EAP identity field.
+struct MatchingCert {
+  MatchingCert() {}
+
+  MatchingCert(const std::string& pkcs11_id,
+               int key_slot_id,
+               const std::string& configured_identity)
+      : pkcs11_id(pkcs11_id),
+        key_slot_id(key_slot_id),
         identity(configured_identity) {}
 
-  std::string service_path;
-  client_cert::ConfigType cert_config_type;
+  bool operator==(const MatchingCert& other) const {
+    return pkcs11_id == other.pkcs11_id && key_slot_id == other.key_slot_id &&
+           identity == other.identity;
+  }
 
-  // The id of the matching certificate or empty if no certificate was found.
+  // The id of the matching certificate.
   std::string pkcs11_id;
 
   // The id of the slot containing the certificate and the private key.
-  int key_slot_id;
+  int key_slot_id = -1;
 
   // The ONC WiFi.EAP.Identity field can contain variables like
   // ${CERT_SAN_EMAIL} which are expanded by ClientCertResolver.
@@ -62,17 +64,62 @@
   std::string identity;
 };
 
-typedef std::vector<ClientCertResolver::NetworkAndMatchingCert>
-    NetworkCertMatches;
+// Describes a network that is configured with |client_cert_config|, which
+// includes the certificate pattern.
+struct NetworkAndCertPattern {
+  NetworkAndCertPattern(const std::string& network_path,
+                        const client_cert::ClientCertConfig& client_cert_config)
+      : service_path(network_path), cert_config(client_cert_config) {}
+
+  std::string service_path;
+  client_cert::ClientCertConfig cert_config;
+};
+
+// The certificate resolving status of a known network that needs certificate
+// pattern resolution.
+enum class ResolveStatus { kResolving, kResolved };
+
+}  // namespace
+
+namespace internal {
+
+// Describes the resolve status for a network, and if resolving already
+// completed, also holds the matched certificate.
+struct MatchingCertAndResolveStatus {
+  // kResolving if client cert resolution is pending, kResolved if client cert
+  // resolution has been completed for the network.
+  ResolveStatus resolve_status = ResolveStatus::kResolving;
+
+  // This is set to the last resolved client certificate or nullopt if no
+  // matching certificate has been found when |resolve_status| is kResolved.
+  // This is also used to determine if re-resolving a network actually changed
+  // any properties.
+  base::Optional<MatchingCert> matching_cert;
+};
+
+// Describes a network |network_path| and the client cert resolution result.
+struct NetworkAndMatchingCert {
+  NetworkAndMatchingCert(const NetworkAndCertPattern& network_and_pattern,
+                         base::Optional<MatchingCert> matching_cert)
+      : service_path(network_and_pattern.service_path),
+        cert_config_type(network_and_pattern.cert_config.location),
+        matching_cert(matching_cert) {}
+
+  std::string service_path;
+  client_cert::ConfigType cert_config_type;
+
+  // The resolved certificate, or |nullopt| if no matching certificate has been
+  // found.
+  base::Optional<MatchingCert> matching_cert;
+};
+
+}  // namespace internal
+
+using internal::MatchingCertAndResolveStatus;
+using internal::NetworkAndMatchingCert;
 
 namespace {
 
-// Returns true if |vector| contains |value|.
-template <class T>
-bool ContainsValue(const std::vector<T>& vector, const T& value) {
-  return find(vector.begin(), vector.end(), value) != vector.end();
-}
-
 // Returns true if a private key for certificate |cert| is installed.
 // Note that HasPrivateKey is not a cheap operation: it iterates all tokens and
 // attempts to look up the private key.
@@ -104,18 +151,6 @@
   return a_not_after > b_not_after;
 }
 
-// Describes a network that is configured with the certificate pattern
-// |client_cert_pattern|.
-struct NetworkAndCertPattern {
-  NetworkAndCertPattern(const std::string& network_path,
-                        const client_cert::ClientCertConfig& client_cert_config)
-      : service_path(network_path),
-        cert_config(client_cert_config) {}
-
-  std::string service_path;
-  client_cert::ClientCertConfig cert_config;
-};
-
 // A unary predicate that returns true if the given CertAndIssuer matches the
 // given certificate pattern.
 struct MatchCertWithPattern {
@@ -147,7 +182,8 @@
 
     const std::vector<std::string>& issuer_ca_pems = pattern.issuer_ca_pems();
     if (!issuer_ca_pems.empty() &&
-        !ContainsValue(issuer_ca_pems, cert_and_issuer.pem_encoded_issuer)) {
+        !base::ContainsValue(issuer_ca_pems,
+                             cert_and_issuer.pem_encoded_issuer)) {
       return false;
     }
     return true;
@@ -193,9 +229,8 @@
   // consumers of CertLoader could also use a pre-filtered list (e.g.
   // NetworkCertMigrator). See crbug.com/781693.
   std::vector<CertAndIssuer> client_certs;
-  for (net::ScopedCERTCertificateList::iterator it = certs.begin();
-       it != certs.end(); ++it) {
-    CERTCertificate* cert = it->get();
+  for (net::ScopedCERTCertificate& scoped_cert : certs) {
+    CERTCertificate* cert = scoped_cert.get();
     base::Time not_after;
     // HasPrivateKey should be invoked after IsCertificateHardwareBacked for
     // performance reasons.
@@ -205,88 +240,90 @@
       continue;
     }
     std::string pem_encoded_issuer = GetPEMEncodedIssuer(cert);
-    client_certs.push_back(CertAndIssuer(std::move(*it), pem_encoded_issuer));
+    client_certs.push_back(
+        CertAndIssuer(std::move(scoped_cert), pem_encoded_issuer));
   }
 
   std::sort(client_certs.begin(), client_certs.end(), &CompareCertExpiration);
   return client_certs;
 }
 
-// Searches for matches between |networks| and |certs| and writes matches to
-// |matches|. Because this calls NSS functions and is potentially slow, it must
-// be run on a worker thread.
-std::unique_ptr<NetworkCertMatches> FindCertificateMatches(
+// Searches for matches between |networks| and |all_certs| (for networks
+// configured in user policy) / |system_certs| (for networks configured in
+// device policy). Returns the matches that were found. Because this calls NSS
+// functions and is potentially slow, it must be run on a worker thread.
+std::vector<NetworkAndMatchingCert> FindCertificateMatches(
     net::ScopedCERTCertificateList all_certs,
     net::ScopedCERTCertificateList system_certs,
-    std::vector<NetworkAndCertPattern>* networks,
+    const std::vector<NetworkAndCertPattern>& networks,
     base::Time now) {
-  std::unique_ptr<NetworkCertMatches> matches =
-      std::make_unique<NetworkCertMatches>();
+  std::vector<NetworkAndMatchingCert> matches;
 
   std::vector<CertAndIssuer> all_client_certs(
       CreateSortedCertAndIssuerList(std::move(all_certs), now));
   std::vector<CertAndIssuer> system_client_certs(
       CreateSortedCertAndIssuerList(std::move(system_certs), now));
 
-  for (std::vector<NetworkAndCertPattern>::const_iterator it =
-           networks->begin();
-       it != networks->end(); ++it) {
+  for (const NetworkAndCertPattern& network_and_pattern : networks) {
     // Use only certs from the system token if the source of the client cert
     // pattern is device policy.
     std::vector<CertAndIssuer>* client_certs =
-        it->cert_config.onc_source == ::onc::ONC_SOURCE_DEVICE_POLICY
+        network_and_pattern.cert_config.onc_source ==
+                ::onc::ONC_SOURCE_DEVICE_POLICY
             ? &system_client_certs
             : &all_client_certs;
-    auto cert_it = std::find_if(client_certs->begin(), client_certs->end(),
-                                MatchCertWithPattern(it->cert_config.pattern));
+    auto cert_it = std::find_if(
+        client_certs->begin(), client_certs->end(),
+        MatchCertWithPattern(network_and_pattern.cert_config.pattern));
+    if (cert_it == client_certs->end()) {
+      VLOG(1) << "Couldn't find a matching client cert for network "
+              << network_and_pattern.service_path;
+      matches.push_back(
+          NetworkAndMatchingCert(network_and_pattern, base::nullopt));
+      continue;
+    }
+
     std::string pkcs11_id;
     int slot_id = -1;
     std::string identity;
 
-    if (cert_it == client_certs->end()) {
-      VLOG(1) << "Couldn't find a matching client cert for network "
-              << it->service_path;
-      // Leave |pkcs11_id| empty to indicate that no cert was found for this
-      // network.
-    } else {
-      pkcs11_id =
-          CertLoader::GetPkcs11IdAndSlotForCert(cert_it->cert.get(), &slot_id);
-      if (pkcs11_id.empty()) {
-        LOG(ERROR) << "Couldn't determine PKCS#11 ID.";
-        // So far this error is not expected to happen. We can just continue, in
-        // the worst case the user can remove the problematic cert.
-        continue;
-      }
+    pkcs11_id =
+        CertLoader::GetPkcs11IdAndSlotForCert(cert_it->cert.get(), &slot_id);
+    if (pkcs11_id.empty()) {
+      LOG(ERROR) << "Couldn't determine PKCS#11 ID.";
+      // So far this error is not expected to happen. We can just continue, in
+      // the worst case the user can remove the problematic cert.
+      continue;
+    }
 
-      // If the policy specifies an identity containing ${CERT_SAN_xxx},
-      // see if the cert contains a suitable subjectAltName that can be
-      // stuffed into the shill properties.
-      identity = it->cert_config.policy_identity;
+    // If the policy specifies an identity containing ${CERT_SAN_xxx},
+    // see if the cert contains a suitable subjectAltName that can be
+    // stuffed into the shill properties.
+    identity = network_and_pattern.cert_config.policy_identity;
+    std::vector<std::string> names;
+
+    size_t offset = identity.find(onc::substitutes::kCertSANEmail, 0);
+    if (offset != std::string::npos) {
       std::vector<std::string> names;
-
-      size_t offset = identity.find(onc::substitutes::kCertSANEmail, 0);
-      if (offset != std::string::npos) {
-        std::vector<std::string> names;
-        net::x509_util::GetRFC822SubjectAltNames(cert_it->cert.get(), &names);
-        if (!names.empty()) {
-          base::ReplaceSubstringsAfterOffset(
-              &identity, offset, onc::substitutes::kCertSANEmail, names[0]);
-        }
-      }
-
-      offset = identity.find(onc::substitutes::kCertSANUPN, 0);
-      if (offset != std::string::npos) {
-        std::vector<std::string> names;
-        net::x509_util::GetUPNSubjectAltNames(cert_it->cert.get(), &names);
-        if (!names.empty()) {
-          base::ReplaceSubstringsAfterOffset(
-              &identity, offset, onc::substitutes::kCertSANUPN, names[0]);
-        }
+      net::x509_util::GetRFC822SubjectAltNames(cert_it->cert.get(), &names);
+      if (!names.empty()) {
+        base::ReplaceSubstringsAfterOffset(
+            &identity, offset, onc::substitutes::kCertSANEmail, names[0]);
       }
     }
-    matches->push_back(ClientCertResolver::NetworkAndMatchingCert(
-        it->service_path, it->cert_config.location, pkcs11_id, slot_id,
-        identity));
+
+    offset = identity.find(onc::substitutes::kCertSANUPN, 0);
+    if (offset != std::string::npos) {
+      std::vector<std::string> names;
+      net::x509_util::GetUPNSubjectAltNames(cert_it->cert.get(), &names);
+      if (!names.empty()) {
+        base::ReplaceSubstringsAfterOffset(
+            &identity, offset, onc::substitutes::kCertSANUPN, names[0]);
+      }
+    }
+
+    matches.push_back(NetworkAndMatchingCert(
+        network_and_pattern, MatchingCert(pkcs11_id, slot_id, identity)));
   }
   return matches;
 }
@@ -417,9 +454,9 @@
     return;
   // Configure only networks that were not configured before.
 
-  // We'll drop networks from |resolved_networks_|, which are not known anymore.
-  std::set<std::string> old_resolved_networks;
-  old_resolved_networks.swap(resolved_networks_);
+  // We'll drop networks from |networks_status_|, which are not known anymore.
+  base::flat_map<std::string, MatchingCertAndResolveStatus> old_networks_status;
+  old_networks_status.swap(networks_status_);
 
   NetworkStateHandler::NetworkStateList networks;
   network_state_handler_->GetNetworkListByType(
@@ -430,14 +467,14 @@
       &networks);
 
   NetworkStateHandler::NetworkStateList networks_to_check;
-  for (NetworkStateHandler::NetworkStateList::const_iterator it =
-           networks.begin(); it != networks.end(); ++it) {
-    const std::string& service_path = (*it)->path();
-    if (base::ContainsKey(old_resolved_networks, service_path)) {
-      resolved_networks_.insert(service_path);
+  for (const NetworkState* network : networks) {
+    const std::string& service_path = network->path();
+    auto old_networks_status_iter = old_networks_status.find(service_path);
+    if (old_networks_status_iter != old_networks_status.end()) {
+      networks_status_[service_path] = old_networks_status_iter->second;
       continue;
     }
-    networks_to_check.push_back(*it);
+    networks_to_check.push_back(network);
   }
 
   if (!networks_to_check.empty()) {
@@ -501,17 +538,16 @@
 void ClientCertResolver::ResolveNetworks(
     const NetworkStateHandler::NetworkStateList& networks) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  std::unique_ptr<std::vector<NetworkAndCertPattern>> networks_to_resolve(
-      new std::vector<NetworkAndCertPattern>);
+  std::vector<NetworkAndCertPattern> networks_to_resolve;
 
   // Filter networks with ClientCertPattern. As ClientCertPatterns can only be
   // set by policy, we check there.
-  for (NetworkStateHandler::NetworkStateList::const_iterator it =
-           networks.begin(); it != networks.end(); ++it) {
-    const NetworkState* network = *it;
-
-    // In any case, don't check this network again in NetworkListChanged.
-    resolved_networks_.insert(network->path());
+  for (const NetworkState* network : networks) {
+    // If the network was not known before, mark it as known but with resolving
+    // pending.
+    if (networks_status_.find(network->path()) == networks_status_.end())
+      networks_status_.insert_or_assign(network->path(),
+                                        MatchingCertAndResolveStatus());
 
     // If this network is not configured, it cannot have a ClientCertPattern.
     if (network->profile_path().empty())
@@ -538,11 +574,11 @@
     if (cert_config.client_cert_type != ::onc::client_cert::kPattern)
       continue;
 
-    networks_to_resolve->push_back(
+    networks_to_resolve.push_back(
         NetworkAndCertPattern(network->path(), cert_config));
   }
 
-  if (networks_to_resolve->empty()) {
+  if (networks_to_resolve.empty()) {
     VLOG(1) << "No networks to resolve.";
     // If a resolve task is running, it will notify observers when it's
     // finished.
@@ -554,7 +590,7 @@
   if (resolve_task_running_) {
     VLOG(1) << "A resolve task is already running. Queue this request.";
     for (const NetworkAndCertPattern& network_and_pattern :
-         *networks_to_resolve) {
+         networks_to_resolve) {
       queued_networks_to_resolve_.insert(network_and_pattern.service_path);
     }
     return;
@@ -570,7 +606,7 @@
                          CertLoader::Get()->all_certs()),
                      net::x509_util::DupCERTCertificateList(
                          CertLoader::Get()->system_certs()),
-                     base::Owned(networks_to_resolve.release()), Now()),
+                     networks_to_resolve, Now()),
       base::BindOnce(&ClientCertResolver::ConfigureCertificates,
                      weak_ptr_factory_.GetWeakPtr()));
 }
@@ -595,33 +631,43 @@
 }
 
 void ClientCertResolver::ConfigureCertificates(
-    std::unique_ptr<NetworkCertMatches> matches) {
+    std::vector<NetworkAndMatchingCert> matches) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  for (NetworkCertMatches::const_iterator it = matches->begin();
-       it != matches->end(); ++it) {
-    NET_LOG(EVENT) << "Configuring certificate for network: "
-                   << it->service_path;
-    base::DictionaryValue shill_properties;
-    if (it->pkcs11_id.empty()) {
-      client_cert::SetEmptyShillProperties(it->cert_config_type,
-                                           &shill_properties);
-    } else {
-      client_cert::SetShillProperties(it->cert_config_type,
-                                      it->key_slot_id,
-                                      it->pkcs11_id,
-                                      &shill_properties);
-      if (!it->identity.empty()) {
-        shill_properties.SetKey(shill::kEapIdentityProperty,
-                                base::Value(it->identity));
-      }
+  for (const NetworkAndMatchingCert& match : matches) {
+    MatchingCertAndResolveStatus& network_status =
+        networks_status_[match.service_path];
+    if (network_status.resolve_status == ResolveStatus::kResolved &&
+        network_status.matching_cert == match.matching_cert) {
+      // The same certificate was configured in the last ConfigureCertificates
+      // call, so don't do anything for this network.
+      continue;
     }
+    network_status.resolve_status = ResolveStatus::kResolved;
+    network_status.matching_cert = match.matching_cert;
     network_properties_changed_ = true;
-    DBusThreadManager::Get()->GetShillServiceClient()->
-        SetProperties(dbus::ObjectPath(it->service_path),
-                        shill_properties,
-                        base::Bind(&base::DoNothing),
-                        base::Bind(&LogError, it->service_path));
-    network_state_handler_->RequestUpdateForNetwork(it->service_path);
+
+    NET_LOG(EVENT) << "Configuring certificate for network: "
+                   << match.service_path;
+
+    base::DictionaryValue shill_properties;
+    if (match.matching_cert.has_value()) {
+      const MatchingCert& matching_cert = match.matching_cert.value();
+      client_cert::SetShillProperties(
+          match.cert_config_type, matching_cert.key_slot_id,
+          matching_cert.pkcs11_id, &shill_properties);
+      if (!matching_cert.identity.empty()) {
+        shill_properties.SetKey(shill::kEapIdentityProperty,
+                                base::Value(matching_cert.identity));
+      }
+    } else {
+      client_cert::SetEmptyShillProperties(match.cert_config_type,
+                                           &shill_properties);
+    }
+    DBusThreadManager::Get()->GetShillServiceClient()->SetProperties(
+        dbus::ObjectPath(match.service_path), shill_properties,
+        base::BindRepeating(&base::DoNothing),
+        base::BindRepeating(&LogError, match.service_path));
+    network_state_handler_->RequestUpdateForNetwork(match.service_path);
   }
   resolve_task_running_ = false;
   if (queued_networks_to_resolve_.empty())
diff --git a/chromeos/network/client_cert_resolver.h b/chromeos/network/client_cert_resolver.h
index 394d800..acc2642 100644
--- a/chromeos/network/client_cert_resolver.h
+++ b/chromeos/network/client_cert_resolver.h
@@ -9,6 +9,7 @@
 #include <string>
 #include <vector>
 
+#include "base/containers/flat_map.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
@@ -30,6 +31,11 @@
 class NetworkState;
 class ManagedNetworkConfigurationHandler;
 
+namespace internal {
+struct NetworkAndMatchingCert;
+struct MatchingCertAndResolveStatus;
+}  // namespace internal
+
 // Observes the known networks. If a network is configured with a client
 // certificate pattern, this class searches for a matching client certificate.
 // Each time it finds a match, it configures the network accordingly.
@@ -37,8 +43,6 @@
                                            public CertLoader::Observer,
                                            public NetworkPolicyObserver {
  public:
-  struct NetworkAndMatchingCert;
-
   class Observer {
    public:
     // Called every time resolving of client certificate patterns finishes,
@@ -107,7 +111,7 @@
   // |matches| contains networks for which a matching certificate was found.
   // Configures these networks.
   void ConfigureCertificates(
-      std::unique_ptr<std::vector<NetworkAndMatchingCert>> matches);
+      std::vector<internal::NetworkAndMatchingCert> matches);
 
   // Trigger a ResolveRequestCompleted event on all observers.
   void NotifyResolveRequestCompleted();
@@ -119,9 +123,11 @@
 
   base::ObserverList<Observer, true> observers_;
 
-  // The set of networks that were checked/resolved in previous passes. These
-  // networks are skipped in the NetworkListChanged notification.
-  std::set<std::string> resolved_networks_;
+  // Stores the current client certificate resolution status for each network.
+  // The key is the network's service path. If a network is not present, it is
+  // not known yet (or disappeared from the list of known networks again).
+  base::flat_map<std::string, internal::MatchingCertAndResolveStatus>
+      networks_status_;
 
   // The list of network paths that still have to be resolved.
   std::set<std::string> queued_networks_to_resolve_;
diff --git a/chromeos/network/client_cert_resolver_unittest.cc b/chromeos/network/client_cert_resolver_unittest.cc
index 92f9366..b41edc92 100644
--- a/chromeos/network/client_cert_resolver_unittest.cc
+++ b/chromeos/network/client_cert_resolver_unittest.cc
@@ -537,12 +537,51 @@
   EXPECT_EQ(test_cert_id_, pkcs11_id);
 
   // Verify that, after the certificate expired and the network disconnection
-  // happens, no client certificate was configured.
+  // happens, no client certificate was configured and the ClientCertResolver
+  // notified its observers with |network_properties_changed| = true.
+  network_properties_changed_count_ = 0;
   test_clock_->SetNow(base::Time::Max());
   SetWifiState(shill::kStateOffline);
   scoped_task_environment_.RunUntilIdle();
   GetServiceProperty(shill::kEapCertIdProperty, &pkcs11_id);
   EXPECT_EQ(std::string(), pkcs11_id);
+  EXPECT_EQ(1, network_properties_changed_count_);
+}
+
+// Test for crbug.com/765489. When the ClientCertResolver re-resolves a network
+// as response to a NetworkConnectionStateChanged notification, and the
+// resulting cert is the same as the last resolved cert, it should not call
+// ResolveRequestCompleted with |network_properties_changed| = true.
+TEST_F(ClientCertResolverTest, SameCertAfterNetworkConnectionStateChanged) {
+  SetupTestCerts("client_1", true /* import issuer */);
+  SetupWifi();
+  scoped_task_environment_.RunUntilIdle();
+
+  SetupNetworkHandlers();
+  SetupPolicyMatchingIssuerPEM(onc::ONC_SOURCE_USER_POLICY, "");
+  scoped_task_environment_.RunUntilIdle();
+
+  StartCertLoader();
+  scoped_task_environment_.RunUntilIdle();
+
+  SetWifiState(shill::kStateOnline);
+  scoped_task_environment_.RunUntilIdle();
+
+  // Verify that the resolver positively matched the pattern in the policy with
+  // the test client cert and configured the network.
+  std::string pkcs11_id;
+  GetServiceProperty(shill::kEapCertIdProperty, &pkcs11_id);
+  EXPECT_EQ(test_cert_id_, pkcs11_id);
+
+  // Verify that after the network disconnection happens, the configured
+  // certificate doesn't change and ClientCertResolver does not notify its
+  // observers with |network_properties_changed| = true.
+  network_properties_changed_count_ = 0;
+  SetWifiState(shill::kStateOffline);
+  scoped_task_environment_.RunUntilIdle();
+  GetServiceProperty(shill::kEapCertIdProperty, &pkcs11_id);
+  EXPECT_EQ(test_cert_id_, pkcs11_id);
+  EXPECT_EQ(0, network_properties_changed_count_);
 }
 
 TEST_F(ClientCertResolverTest, UserPolicyUsesSystemToken) {
diff --git a/components/BUILD.gn b/components/BUILD.gn
index 680fe6d4..ec32ef49 100644
--- a/components/BUILD.gn
+++ b/components/BUILD.gn
@@ -488,6 +488,7 @@
     }
 
     if (is_android) {
+      enable_multidex = true
       sources += [
         "test/android/browsertests_apk/components_browser_tests_jni_onload.cc",
       ]
diff --git a/components/cbor/cbor_values.cc b/components/cbor/cbor_values.cc
index 837b5c5..42454aac 100644
--- a/components/cbor/cbor_values.cc
+++ b/components/cbor/cbor_values.cc
@@ -69,16 +69,41 @@
 CBORValue::CBORValue(BinaryValue&& in_bytes) noexcept
     : type_(Type::BYTE_STRING), bytestring_value_(std::move(in_bytes)) {}
 
-CBORValue::CBORValue(const char* in_string)
-    : CBORValue(std::string(in_string)) {}
+CBORValue::CBORValue(const char* in_string, Type type)
+    : CBORValue(base::StringPiece(in_string), type) {}
 
-CBORValue::CBORValue(std::string&& in_string) noexcept
-    : type_(Type::STRING), string_value_(std::move(in_string)) {
-  DCHECK(base::IsStringUTF8(string_value_));
+CBORValue::CBORValue(std::string&& in_string, Type type) noexcept
+    : type_(type) {
+  switch (type_) {
+    case Type::STRING:
+      new (&string_value_) std::string();
+      string_value_ = std::move(in_string);
+      DCHECK(base::IsStringUTF8(string_value_));
+      break;
+    case Type::BYTE_STRING:
+      new (&bytestring_value_) BinaryValue();
+      bytestring_value_ = BinaryValue(in_string.begin(), in_string.end());
+      break;
+    default:
+      NOTREACHED();
+  }
 }
 
-CBORValue::CBORValue(base::StringPiece in_string)
-    : CBORValue(in_string.as_string()) {}
+CBORValue::CBORValue(base::StringPiece in_string, Type type) : type_(type) {
+  switch (type_) {
+    case Type::STRING:
+      new (&string_value_) std::string();
+      string_value_ = in_string.as_string();
+      DCHECK(base::IsStringUTF8(string_value_));
+      break;
+    case Type::BYTE_STRING:
+      new (&bytestring_value_) BinaryValue();
+      bytestring_value_ = BinaryValue(in_string.begin(), in_string.end());
+      break;
+    default:
+      NOTREACHED();
+  }
+}
 
 CBORValue::CBORValue(const ArrayValue& in_array)
     : type_(Type::ARRAY), array_value_() {
@@ -171,6 +196,14 @@
   return bytestring_value_;
 }
 
+base::StringPiece CBORValue::GetBytestringAsString() const {
+  CHECK(is_bytestring());
+  const auto& bytestring_value = GetBytestring();
+  return base::StringPiece(
+      reinterpret_cast<const char*>(bytestring_value.data()),
+      bytestring_value.size());
+}
+
 const CBORValue::ArrayValue& CBORValue::GetArray() const {
   CHECK(is_array());
   return array_value_;
diff --git a/components/cbor/cbor_values.h b/components/cbor/cbor_values.h
index af752f9..e95cbfd 100644
--- a/components/cbor/cbor_values.h
+++ b/components/cbor/cbor_values.h
@@ -108,9 +108,10 @@
   explicit CBORValue(const BinaryValue& in_bytes);
   explicit CBORValue(BinaryValue&& in_bytes) noexcept;
 
-  explicit CBORValue(const char* in_string);
-  explicit CBORValue(std::string&& in_string) noexcept;
-  explicit CBORValue(base::StringPiece in_string);
+  explicit CBORValue(const char* in_string, Type type = Type::STRING);
+  explicit CBORValue(std::string&& in_string,
+                     Type type = Type::STRING) noexcept;
+  explicit CBORValue(base::StringPiece in_string, Type type = Type::STRING);
 
   explicit CBORValue(const ArrayValue& in_array);
   explicit CBORValue(ArrayValue&& in_array) noexcept;
@@ -152,6 +153,7 @@
   const int64_t& GetUnsigned() const;
   const int64_t& GetNegative() const;
   const BinaryValue& GetBytestring() const;
+  base::StringPiece GetBytestringAsString() const;
   // Returned string may contain NUL characters.
   const std::string& GetString() const;
   const ArrayValue& GetArray() const;
diff --git a/components/cbor/cbor_values_unittest.cc b/components/cbor/cbor_values_unittest.cc
index fbeebc3..23a959e 100644
--- a/components/cbor/cbor_values_unittest.cc
+++ b/components/cbor/cbor_values_unittest.cc
@@ -69,6 +69,14 @@
             value.GetBytestring());
 }
 
+TEST(CBORValuesTest, ConstructBytestringFromString) {
+  CBORValue value(CBORValue("hello", CBORValue::Type::BYTE_STRING));
+  ASSERT_EQ(CBORValue::Type::BYTE_STRING, value.type());
+  EXPECT_EQ(CBORValue::BinaryValue({'h', 'e', 'l', 'l', 'o'}),
+            value.GetBytestring());
+  EXPECT_EQ("hello", value.GetBytestringAsString());
+}
+
 TEST(CBORValuesTest, ConstructArray) {
   CBORValue::ArrayValue array;
   array.emplace_back(CBORValue("foo"));
diff --git a/components/download/internal/background_service/controller_impl.cc b/components/download/internal/background_service/controller_impl.cc
index 56bab0d..ec17c3a 100644
--- a/components/download/internal/background_service/controller_impl.cc
+++ b/components/download/internal/background_service/controller_impl.cc
@@ -4,6 +4,8 @@
 
 #include "components/download/internal/background_service/controller_impl.h"
 
+#include <inttypes.h>
+
 #include <string>
 #include <vector>
 
@@ -11,6 +13,7 @@
 #include "base/callback_helpers.h"
 #include "base/memory/ptr_util.h"
 #include "base/optional.h"
+#include "base/strings/stringprintf.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/trace_event/memory_allocator_dump.h"
 #include "base/trace_event/memory_dump_manager.h"
@@ -597,7 +600,9 @@
 
 bool ControllerImpl::OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
                                   base::trace_event::ProcessMemoryDump* pmd) {
-  auto* dump = pmd->GetOrCreateAllocatorDump("components/download");
+  auto* dump = pmd->CreateAllocatorDump(
+      base::StringPrintf("components/download/controller_0x%" PRIXPTR,
+                         reinterpret_cast<uintptr_t>(this)));
 
   size_t memory_cost =
       base::trace_event::EstimateMemoryUsage(externally_active_downloads_);
diff --git a/components/metrics/call_stack_profile_metrics_provider.cc b/components/metrics/call_stack_profile_metrics_provider.cc
index 37eee2d..b748a262 100644
--- a/components/metrics/call_stack_profile_metrics_provider.cc
+++ b/components/metrics/call_stack_profile_metrics_provider.cc
@@ -478,18 +478,10 @@
       return UNKNOWN_THREAD;
     case CallStackProfileParams::UI_THREAD:
       return UI_THREAD;
-    case CallStackProfileParams::FILE_THREAD:
-      return FILE_THREAD;
-    case CallStackProfileParams::FILE_USER_BLOCKING_THREAD:
-      return FILE_USER_BLOCKING_THREAD;
     case CallStackProfileParams::PROCESS_LAUNCHER_THREAD:
       return PROCESS_LAUNCHER_THREAD;
-    case CallStackProfileParams::CACHE_THREAD:
-      return CACHE_THREAD;
     case CallStackProfileParams::IO_THREAD:
       return IO_THREAD;
-    case CallStackProfileParams::DB_THREAD:
-      return DB_THREAD;
     case CallStackProfileParams::GPU_MAIN_THREAD:
       return GPU_MAIN_THREAD;
     case CallStackProfileParams::RENDER_THREAD:
diff --git a/components/metrics/call_stack_profile_params.h b/components/metrics/call_stack_profile_params.h
index deddc953..9c74eed 100644
--- a/components/metrics/call_stack_profile_params.h
+++ b/components/metrics/call_stack_profile_params.h
@@ -30,12 +30,8 @@
 
     // Browser process threads, some of which occur in other processes as well.
     UI_THREAD,
-    FILE_THREAD,
-    FILE_USER_BLOCKING_THREAD,
     PROCESS_LAUNCHER_THREAD,
-    CACHE_THREAD,
     IO_THREAD,
-    DB_THREAD,
 
     // GPU process thread.
     GPU_MAIN_THREAD,
diff --git a/components/metrics/public/cpp/call_stack_profile_struct_traits.h b/components/metrics/public/cpp/call_stack_profile_struct_traits.h
index a024ac73..edea7ce 100644
--- a/components/metrics/public/cpp/call_stack_profile_struct_traits.h
+++ b/components/metrics/public/cpp/call_stack_profile_struct_traits.h
@@ -230,18 +230,10 @@
         return metrics::mojom::Thread::UNKNOWN_THREAD;
       case metrics::CallStackProfileParams::Thread::UI_THREAD:
         return metrics::mojom::Thread::UI_THREAD;
-      case metrics::CallStackProfileParams::Thread::FILE_THREAD:
-        return metrics::mojom::Thread::FILE_THREAD;
-      case metrics::CallStackProfileParams::Thread::FILE_USER_BLOCKING_THREAD:
-        return metrics::mojom::Thread::FILE_USER_BLOCKING_THREAD;
       case metrics::CallStackProfileParams::Thread::PROCESS_LAUNCHER_THREAD:
         return metrics::mojom::Thread::PROCESS_LAUNCHER_THREAD;
-      case metrics::CallStackProfileParams::Thread::CACHE_THREAD:
-        return metrics::mojom::Thread::CACHE_THREAD;
       case metrics::CallStackProfileParams::Thread::IO_THREAD:
         return metrics::mojom::Thread::IO_THREAD;
-      case metrics::CallStackProfileParams::Thread::DB_THREAD:
-        return metrics::mojom::Thread::DB_THREAD;
       case metrics::CallStackProfileParams::Thread::GPU_MAIN_THREAD:
         return metrics::mojom::Thread::GPU_MAIN_THREAD;
       case metrics::CallStackProfileParams::Thread::RENDER_THREAD:
@@ -264,25 +256,12 @@
       case metrics::mojom::Thread::UI_THREAD:
         *out = metrics::CallStackProfileParams::Thread::UI_THREAD;
         return true;
-      case metrics::mojom::Thread::FILE_THREAD:
-        *out = metrics::CallStackProfileParams::Thread::FILE_THREAD;
-        return true;
-      case metrics::mojom::Thread::FILE_USER_BLOCKING_THREAD:
-        *out =
-            metrics::CallStackProfileParams::Thread::FILE_USER_BLOCKING_THREAD;
-        return true;
       case metrics::mojom::Thread::PROCESS_LAUNCHER_THREAD:
         *out = metrics::CallStackProfileParams::Thread::PROCESS_LAUNCHER_THREAD;
         return true;
-      case metrics::mojom::Thread::CACHE_THREAD:
-        *out = metrics::CallStackProfileParams::Thread::CACHE_THREAD;
-        return true;
       case metrics::mojom::Thread::IO_THREAD:
         *out = metrics::CallStackProfileParams::Thread::IO_THREAD;
         return true;
-      case metrics::mojom::Thread::DB_THREAD:
-        *out = metrics::CallStackProfileParams::Thread::DB_THREAD;
-        return true;
       case metrics::mojom::Thread::GPU_MAIN_THREAD:
         *out = metrics::CallStackProfileParams::Thread::GPU_MAIN_THREAD;
         return true;
diff --git a/components/metrics/public/cpp/call_stack_profile_struct_traits_unittest.cc b/components/metrics/public/cpp/call_stack_profile_struct_traits_unittest.cc
index 6457a62..ae4b7c7 100644
--- a/components/metrics/public/cpp/call_stack_profile_struct_traits_unittest.cc
+++ b/components/metrics/public/cpp/call_stack_profile_struct_traits_unittest.cc
@@ -306,24 +306,12 @@
   EXPECT_TRUE(proxy_->BounceThread(Thread::UI_THREAD, &out));
   EXPECT_EQ(Thread::UI_THREAD, out);
 
-  EXPECT_TRUE(proxy_->BounceThread(Thread::FILE_THREAD, &out));
-  EXPECT_EQ(Thread::FILE_THREAD, out);
-
-  EXPECT_TRUE(proxy_->BounceThread(Thread::FILE_USER_BLOCKING_THREAD, &out));
-  EXPECT_EQ(Thread::FILE_USER_BLOCKING_THREAD, out);
-
   EXPECT_TRUE(proxy_->BounceThread(Thread::PROCESS_LAUNCHER_THREAD, &out));
   EXPECT_EQ(Thread::PROCESS_LAUNCHER_THREAD, out);
 
-  EXPECT_TRUE(proxy_->BounceThread(Thread::CACHE_THREAD, &out));
-  EXPECT_EQ(Thread::CACHE_THREAD, out);
-
   EXPECT_TRUE(proxy_->BounceThread(Thread::IO_THREAD, &out));
   EXPECT_EQ(Thread::IO_THREAD, out);
 
-  EXPECT_TRUE(proxy_->BounceThread(Thread::DB_THREAD, &out));
-  EXPECT_EQ(Thread::DB_THREAD, out);
-
   EXPECT_TRUE(proxy_->BounceThread(Thread::GPU_MAIN_THREAD, &out));
   EXPECT_EQ(Thread::GPU_MAIN_THREAD, out);
 
diff --git a/components/metrics/public/interfaces/call_stack_profile_collector.mojom b/components/metrics/public/interfaces/call_stack_profile_collector.mojom
index 157b1002..cff0ec4 100644
--- a/components/metrics/public/interfaces/call_stack_profile_collector.mojom
+++ b/components/metrics/public/interfaces/call_stack_profile_collector.mojom
@@ -48,12 +48,8 @@
   UNKNOWN_THREAD,
 
   UI_THREAD,
-  FILE_THREAD,
-  FILE_USER_BLOCKING_THREAD,
   PROCESS_LAUNCHER_THREAD,
-  CACHE_THREAD,
   IO_THREAD,
-  DB_THREAD,
 
   GPU_MAIN_THREAD,
 
diff --git a/components/policy/proto/chrome_device_policy.proto b/components/policy/proto/chrome_device_policy.proto
index ef2369b..1915777 100644
--- a/components/policy/proto/chrome_device_policy.proto
+++ b/components/policy/proto/chrome_device_policy.proto
@@ -938,6 +938,19 @@
   optional bool unaffiliated_arc_allowed = 1;
 }
 
+// Allowed encryption types for requesting Kerberos tickets from Active
+// Directory servers. Applies to Active Directory management mode only.
+message DeviceKerberosEncryptionTypesProto {
+  enum Types {
+    ENC_TYPES_ALL = 0;     // AES + RC4_HMAC.
+    ENC_TYPES_STRONG = 1;  // AES only.
+    ENC_TYPES_LEGACY = 2;  // RC4_HMAC only.
+    // Next ID to use: 3
+  }
+
+  optional Types types = 1 [default = ENC_TYPES_STRONG];
+}
+
 message ChromeDeviceSettingsProto {
   reserved 61;
   optional DevicePolicyRefreshRateProto device_policy_refresh_rate = 1;
@@ -1016,4 +1029,6 @@
       device_login_screen_auto_select_certificate_for_urls = 62;
   optional UnaffiliatedArcAllowedProto unaffiliated_arc_allowed = 63;
   optional NetworkHostnameProto network_hostname = 64;
+  optional DeviceKerberosEncryptionTypesProto device_kerberos_encryption_types =
+      65;
 }
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index a632402..0b83cba1 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -146,7 +146,7 @@
 #   persistent IDs for all fields (but not for groups!) are needed. These are
 #   specified by the 'id' keys of each policy. NEVER CHANGE EXISTING IDs,
 #   because doing so would break the deployed wire format!
-#   For your editing convenience: highest ID currently used: 413
+#   For your editing convenience: highest ID currently used: 415
 #   And don't forget to also update the EnterprisePolicies enum of
 #   histograms.xml (run 'python tools/metrics/histograms/update_policies.py').
 #
@@ -5031,6 +5031,50 @@
       'arc_support': 'Android apps can use the network configurations and CA certificates set via this policy, but do not have access to some configuration options.',
     },
     {
+      'name': 'DeviceKerberosEncryptionTypes',
+      'type': 'int-enum',
+      'schema': {
+        'type': 'integer',
+        'enum': [ 0, 1, 2 ],
+      },
+      'items': [
+        {
+          'name': 'All',
+          'value': 0,
+          'caption': '''All''',
+        },
+        {
+          'name': 'Strong',
+          'value': 1,
+          'caption': '''Strong''',
+        },
+        {
+          'name': 'Legacy',
+          'value': 2,
+          'caption': '''Legacy''',
+        },
+      ],
+      'supported_on': ['chrome_os:66-'],
+      'supported_chrome_os_management': ['active_directory'],
+      'device_only': True,
+      'features': {
+        'dynamic_refresh': True,
+      },
+      'example_value': 1,
+      'id': 415,
+      'caption': '''Allowed Kerberos encryption types''',
+      'tags': ['system-security'],
+      'desc': '''Sets encryption types that are allowed when requesting Kerberos tickets from an <ph name="MS_AD_NAME">Microsoft® Active Directory®</ph> server.
+
+      If the policy is set to 'All', both the AES encryption types 'aes256-cts-hmac-sha1-96' and 'aes128-cts-hmac-sha1-96' as well as the RC4 encryption type 'rc4-hmac' are allowed. AES encryption takes preference if the server supports both types. Note that RC4 is considered weak and the server should be reconfigured if possible to support AES encryption.
+
+      If the policy is set to 'Strong' or if it is unset, only the AES encryption types are allowed.
+
+      If the policy is set to 'Legacy', only the RC4 encryption type is allowed. This option is insecure and should only be needed in very specific circumstances.
+
+      See also https://wiki.samba.org/index.php/Samba_4.6_Features_added/changed#Kerberos_client_encryption_types.''',
+    },
+    {
       'name': 'CloudPrintSubmitEnabled',
       'type': 'main',
       'schema': { 'type': 'boolean' },
@@ -10742,6 +10786,30 @@
       ''',
     },
     {
+      'name': 'WebDriverOverridesIncompatiblePolicies',
+      'type': 'main',
+      'schema': { 'type': 'boolean' },
+      'supported_on': ['chrome.*:65-'],
+      'device_only': False,
+      'features': {
+        'dynamic_refresh': False,
+        'per_profile': False,
+      },
+      'example_value': True,
+      'id': 414,
+      'caption': '''Allow WebDriver to Override Incompatible Policies''',
+      'tags': ['system-security'],
+      'desc': '''This policy allows users of the WebDriver feature to override
+      policies which can interfere with its operation.
+
+      Currently this policy disables SitePerProcess and IsolateOrigins policies.
+
+      If the policy is enabled, WebDriver will be able to override incomaptible
+      policies.
+      If the policy is disabled or not configured, WebDriver will not be allowed
+      to override incompatible policies.''',
+    },
+    {
       'name': 'UnsafelyTreatInsecureOriginAsSecure',
       'type': 'list',
       'schema': {
@@ -10944,11 +11012,11 @@
       'tags': [],
       'desc': '''Contains a list of patterns which are used to control the visiblity of accounts in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>.
 
-      Account on the device will be visible in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> if its name matches any pattern from the list. Otherwise account will be filtered out and hidden.
+      Each Google account on the device will be compared to patterns stored in this policy to determine the account visibility in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. The account will be visible if its name matches any pattern on the list. Otherwise, the account will be hidden.
 
-      The wildcard character '*' can be used to match zero or more arbitrary characters. The escape character is '\\', so to match actual '*' or '\\' characters, you can put a '\\' in front of them.
+      Use the wildcard character '*' to match zero or more arbitrary characters. The escape character is '\\', so to match actual '*' or '\\' characters, put a '\\' in front of them.
 
-      If this policy is left not set then all Google accounts on the device will be visible in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>.''',
+      If this policy is not set, all Google accounts on the device will be visible in <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>.''',
     },
     {
       'name': 'PasswordProtectionWarningTrigger',
diff --git a/components/spellcheck/renderer/spellcheck_provider.cc b/components/spellcheck/renderer/spellcheck_provider.cc
index 54e0d03d..5c4b0c48 100644
--- a/components/spellcheck/renderer/spellcheck_provider.cc
+++ b/components/spellcheck/renderer/spellcheck_provider.cc
@@ -46,7 +46,8 @@
     : content::RenderFrameObserver(render_frame),
       content::RenderFrameObserverTracker<SpellCheckProvider>(render_frame),
       spellcheck_(spellcheck),
-      embedder_provider_(embedder_provider) {
+      embedder_provider_(embedder_provider),
+      weak_factory_(this) {
   DCHECK(spellcheck_);
   if (render_frame)  // NULL in unit tests.
     render_frame->GetWebFrame()->SetTextCheckClient(this);
@@ -96,7 +97,7 @@
     return;  // NULL in tests that do not provide a spell_check_host_.
   GetSpellCheckHost().CallSpellingService(
       text, base::BindOnce(&SpellCheckProvider::OnRespondSpellingService,
-                           base::Unretained(this), last_identifier_, text));
+                           weak_factory_.GetWeakPtr(), last_identifier_, text));
 #endif  // !USE_BROWSER_SPELLCHECKER
 }
 
diff --git a/components/spellcheck/renderer/spellcheck_provider.h b/components/spellcheck/renderer/spellcheck_provider.h
index 8a4260e..c9f6efc 100644
--- a/components/spellcheck/renderer/spellcheck_provider.h
+++ b/components/spellcheck/renderer/spellcheck_provider.h
@@ -124,11 +124,14 @@
   // Weak pointer to shared (per renderer) spellcheck data.
   SpellCheck* spellcheck_;
 
+  // Not owned. |embedder_provider_| should outlive SpellCheckProvider.
   service_manager::LocalInterfaceProvider* embedder_provider_;
 
   // Interface to the SpellCheckHost.
   spellcheck::mojom::SpellCheckHostPtr spell_check_host_;
 
+  base::WeakPtrFactory<SpellCheckProvider> weak_factory_;
+
   DISALLOW_COPY_AND_ASSIGN(SpellCheckProvider);
 };
 
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index bbee78c8..9349328 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -966,6 +966,8 @@
     "leveldb_wrapper_impl.h",
     "loader/cross_site_document_resource_handler.cc",
     "loader/cross_site_document_resource_handler.h",
+    "loader/data_pipe_to_source_stream.cc",
+    "loader/data_pipe_to_source_stream.h",
     "loader/detachable_resource_handler.cc",
     "loader/detachable_resource_handler.h",
     "loader/downloaded_temp_file_impl.cc",
@@ -1021,6 +1023,8 @@
     "loader/resource_scheduler_filter.h",
     "loader/signed_exchange_handler.cc",
     "loader/signed_exchange_handler.h",
+    "loader/source_stream_to_data_pipe.cc",
+    "loader/source_stream_to_data_pipe.h",
     "loader/stream_resource_handler.cc",
     "loader/stream_resource_handler.h",
     "loader/stream_writer.cc",
@@ -1471,6 +1475,8 @@
     "service_worker/embedded_worker_registry.cc",
     "service_worker/embedded_worker_registry.h",
     "service_worker/embedded_worker_status.h",
+    "service_worker/payment_handler_support.cc",
+    "service_worker/payment_handler_support.h",
     "service_worker/service_worker_blob_reader.cc",
     "service_worker/service_worker_blob_reader.h",
     "service_worker/service_worker_cache_writer.cc",
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
index 806a68c..c640a87 100644
--- a/content/browser/browser_main_loop.cc
+++ b/content/browser/browser_main_loop.cc
@@ -376,25 +376,6 @@
 MSVC_DISABLE_OPTIMIZE()
 MSVC_PUSH_DISABLE_WARNING(4748)
 
-NOINLINE void ResetThread_DB() {
-  volatile int inhibit_comdat = __LINE__;
-  ALLOW_UNUSED_LOCAL(inhibit_comdat);
-  BrowserThreadImpl::StopRedirectionOfThreadID(BrowserThread::DB);
-}
-
-NOINLINE void ResetThread_FILE() {
-  volatile int inhibit_comdat = __LINE__;
-  ALLOW_UNUSED_LOCAL(inhibit_comdat);
-  BrowserThreadImpl::StopRedirectionOfThreadID(BrowserThread::FILE);
-}
-
-NOINLINE void ResetThread_FILE_USER_BLOCKING() {
-  volatile int inhibit_comdat = __LINE__;
-  ALLOW_UNUSED_LOCAL(inhibit_comdat);
-  BrowserThreadImpl::StopRedirectionOfThreadID(
-      BrowserThread::FILE_USER_BLOCKING);
-}
-
 #if defined(OS_ANDROID)
 NOINLINE void ResetThread_PROCESS_LAUNCHER(
     std::unique_ptr<BrowserProcessSubThread> thread) {
@@ -410,21 +391,6 @@
 }
 #endif  // defined(OS_ANDROID)
 
-#if defined(OS_WIN)
-NOINLINE void ResetThread_CACHE(
-    std::unique_ptr<BrowserProcessSubThread> thread) {
-  volatile int inhibit_comdat = __LINE__;
-  ALLOW_UNUSED_LOCAL(inhibit_comdat);
-    thread.reset();
-}
-#else   // defined(OS_WIN)
-NOINLINE void ResetThread_CACHE() {
-  volatile int inhibit_comdat = __LINE__;
-  ALLOW_UNUSED_LOCAL(inhibit_comdat);
-  BrowserThreadImpl::StopRedirectionOfThreadID(BrowserThread::CACHE);
-}
-#endif  // defined(OS_WIN)
-
 NOINLINE void ResetThread_IO(std::unique_ptr<BrowserProcessSubThread> thread) {
   volatile int inhibit_comdat = __LINE__;
   ALLOW_UNUSED_LOCAL(inhibit_comdat);
@@ -1093,42 +1059,10 @@
     base::MessageLoop* message_loop = nullptr;
 
     // Otherwise this thread ID will be backed by a SingleThreadTaskRunner using
-    // |non_ui_non_io_task_runner_traits| (which can be augmented below).
-    // TODO(gab): Existing non-UI/non-IO BrowserThreads allow sync primitives so
-    // the initial redirection will as well but they probably don't need to.
-    base::TaskTraits non_ui_non_io_task_runner_traits;
-
-    // Note: if you're copying these TaskTraits elsewhere, you most likely don't
-    // need and shouldn't use base::WithBaseSyncPrimitives() -- see its
-    // documentation.
-    constexpr base::TaskTraits kUserVisibleTraits = {
-        base::MayBlock(), base::WithBaseSyncPrimitives(),
-        base::TaskPriority::USER_VISIBLE,
-        base::TaskShutdownBehavior::BLOCK_SHUTDOWN};
-    constexpr base::TaskTraits kUserBlockingTraits = {
-        base::MayBlock(), base::WithBaseSyncPrimitives(),
-        base::TaskPriority::USER_BLOCKING,
-        base::TaskShutdownBehavior::BLOCK_SHUTDOWN};
+    // |task_traits| (to be set below instead of |thread_to_start|).
+    base::TaskTraits task_traits;
 
     switch (thread_id) {
-      case BrowserThread::DB:
-        TRACE_EVENT_BEGIN1("startup",
-            "BrowserMainLoop::CreateThreads:start",
-            "Thread", "BrowserThread::DB");
-        non_ui_non_io_task_runner_traits = kUserVisibleTraits;
-        break;
-      case BrowserThread::FILE_USER_BLOCKING:
-        TRACE_EVENT_BEGIN1("startup",
-            "BrowserMainLoop::CreateThreads:start",
-            "Thread", "BrowserThread::FILE_USER_BLOCKING");
-        non_ui_non_io_task_runner_traits = kUserBlockingTraits;
-        break;
-      case BrowserThread::FILE:
-        TRACE_EVENT_BEGIN1("startup",
-            "BrowserMainLoop::CreateThreads:start",
-            "Thread", "BrowserThread::FILE");
-        non_ui_non_io_task_runner_traits = kUserVisibleTraits;
-        break;
       case BrowserThread::PROCESS_LAUNCHER:
         TRACE_EVENT_BEGIN1("startup",
             "BrowserMainLoop::CreateThreads:start",
@@ -1141,26 +1075,12 @@
         DCHECK(message_loop);
         thread_to_start = &process_launcher_thread_;
 #else   // defined(OS_ANDROID)
-        non_ui_non_io_task_runner_traits = kUserBlockingTraits;
+        // TODO(gab): WithBaseSyncPrimitives() is likely not required here.
+        task_traits = {base::MayBlock(), base::WithBaseSyncPrimitives(),
+                       base::TaskPriority::USER_BLOCKING,
+                       base::TaskShutdownBehavior::BLOCK_SHUTDOWN};
 #endif  // defined(OS_ANDROID)
         break;
-      case BrowserThread::CACHE:
-        TRACE_EVENT_BEGIN1("startup",
-            "BrowserMainLoop::CreateThreads:start",
-            "Thread", "BrowserThread::CACHE");
-#if defined(OS_WIN)
-        // TaskScheduler doesn't support async I/O on Windows as CACHE thread is
-        // the only user and this use case is going away in
-        // https://codereview.chromium.org/2216583003/.
-        // TODO(gavinp): Remove this ifdef (and thus enable redirection of the
-        // CACHE thread on Windows) once that CL lands.
-        thread_to_start = &cache_thread_;
-        options = io_message_loop_options;
-        options.timer_slack = base::TIMER_SLACK_MAXIMUM;
-#else  // OS_WIN
-        non_ui_non_io_task_runner_traits = kUserBlockingTraits;
-#endif  // OS_WIN
-        break;
       case BrowserThread::IO:
         TRACE_EVENT_BEGIN1("startup",
             "BrowserMainLoop::CreateThreads:start",
@@ -1189,24 +1109,9 @@
       if (!message_loop && !(*thread_to_start)->StartWithOptions(options))
         LOG(FATAL) << "Failed to start the browser thread: id == " << id;
     } else {
-      scoped_refptr<base::SingleThreadTaskRunner> redirection_task_runner;
-#if defined(OS_WIN)
-      // On Windows, the FILE thread needs to have a UI message loop which
-      // pumps messages in such a way that Google Update can communicate back
-      // to us. The COM STA task runner provides this service.
-      redirection_task_runner =
-          (thread_id == BrowserThread::FILE)
-              ? base::CreateCOMSTATaskRunnerWithTraits(
-                    non_ui_non_io_task_runner_traits,
-                    base::SingleThreadTaskRunnerThreadMode::DEDICATED)
-              : base::CreateSingleThreadTaskRunnerWithTraits(
-                    non_ui_non_io_task_runner_traits,
-                    base::SingleThreadTaskRunnerThreadMode::DEDICATED);
-#else   // defined(OS_WIN)
-      redirection_task_runner = base::CreateSingleThreadTaskRunnerWithTraits(
-          non_ui_non_io_task_runner_traits,
-          base::SingleThreadTaskRunnerThreadMode::DEDICATED);
-#endif  // defined(OS_WIN)
+      scoped_refptr<base::SingleThreadTaskRunner> redirection_task_runner =
+          base::CreateSingleThreadTaskRunnerWithTraits(
+              task_traits, base::SingleThreadTaskRunnerThreadMode::DEDICATED);
       DCHECK(redirection_task_runner);
       BrowserThreadImpl::RedirectThreadIDToTaskRunner(
           id, std::move(redirection_task_runner));
@@ -1370,33 +1275,10 @@
       // BrowserThread::ID enumeration.
       //
       // The destruction order is the reverse order of occurrence in the
-      // BrowserThread::ID list. The rationale for the order is as follows (need
-      // to be filled in a bit):
-      //
-      // - The IO thread is the only user of the CACHE thread.
-      //
-      // - The PROCESS_LAUNCHER thread must be stopped after IO in case
-      //   the IO thread posted a task to terminate a process on the
-      //   process launcher thread.
-      //
-      // - (Not sure why DB stops last.)
+      // BrowserThread::ID list. The rationale for the order is that he
+      // PROCESS_LAUNCHER thread must be stopped after IO in case the IO thread
+      // posted a task to terminate a process on the process launcher thread.
       switch (thread_id) {
-        case BrowserThread::DB: {
-          TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:DBThread");
-          ResetThread_DB();
-          break;
-        }
-        case BrowserThread::FILE: {
-          TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:FileThread");
-          ResetThread_FILE();
-          break;
-        }
-        case BrowserThread::FILE_USER_BLOCKING: {
-          TRACE_EVENT0("shutdown",
-                       "BrowserMainLoop::Subsystem:FileUserBlockingThread");
-          ResetThread_FILE_USER_BLOCKING();
-          break;
-        }
         case BrowserThread::PROCESS_LAUNCHER: {
           TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:LauncherThread");
 #if defined(OS_ANDROID)
@@ -1406,15 +1288,6 @@
 #endif  // defined(OS_ANDROID)
           break;
         }
-        case BrowserThread::CACHE: {
-          TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:CacheThread");
-#if defined(OS_WIN)
-          ResetThread_CACHE(std::move(cache_thread_));
-#else   // defined(OS_WIN)
-          ResetThread_CACHE();
-#endif  // defined(OS_WIN)
-          break;
-        }
         case BrowserThread::IO: {
           TRACE_EVENT0("shutdown", "BrowserMainLoop::Subsystem:IOThread");
           ResetThread_IO(std::move(io_thread_));
diff --git a/content/browser/browser_thread_impl.cc b/content/browser/browser_thread_impl.cc
index f859e96..5a3e4e4 100644
--- a/content/browser/browser_thread_impl.cc
+++ b/content/browser/browser_thread_impl.cc
@@ -33,11 +33,7 @@
 // Friendly names for the well-known threads.
 static const char* const g_browser_thread_names[BrowserThread::ID_COUNT] = {
   "",  // UI (name assembled in browser_main.cc).
-  "Chrome_DBThread",  // DB
-  "Chrome_FileThread",  // FILE
-  "Chrome_FileUserBlockingThread",  // FILE_USER_BLOCKING
   "Chrome_ProcessLauncherThread",  // PROCESS_LAUNCHER
-  "Chrome_CacheThread",  // CACHE
   "Chrome_IOThread",  // IO
 };
 
@@ -182,11 +178,7 @@
   }
 #endif  // DCHECK_IS_ON()
 
-  if (identifier_ == BrowserThread::DB ||
-      identifier_ == BrowserThread::FILE ||
-      identifier_ == BrowserThread::FILE_USER_BLOCKING ||
-      identifier_ == BrowserThread::PROCESS_LAUNCHER ||
-      identifier_ == BrowserThread::CACHE) {
+  if (identifier_ == BrowserThread::PROCESS_LAUNCHER) {
     // Nesting and task observers are not allowed on redirected threads.
     base::RunLoop::DisallowNestingOnCurrentThread();
     message_loop()->DisallowTaskObservers();
@@ -211,25 +203,6 @@
   CHECK_GT(line_number, 0);
 }
 
-NOINLINE void BrowserThreadImpl::DBThreadRun(base::RunLoop* run_loop) {
-  volatile int line_number = __LINE__;
-  Thread::Run(run_loop);
-  CHECK_GT(line_number, 0);
-}
-
-NOINLINE void BrowserThreadImpl::FileThreadRun(base::RunLoop* run_loop) {
-  volatile int line_number = __LINE__;
-  Thread::Run(run_loop);
-  CHECK_GT(line_number, 0);
-}
-
-NOINLINE void BrowserThreadImpl::FileUserBlockingThreadRun(
-    base::RunLoop* run_loop) {
-  volatile int line_number = __LINE__;
-  Thread::Run(run_loop);
-  CHECK_GT(line_number, 0);
-}
-
 NOINLINE void BrowserThreadImpl::ProcessLauncherThreadRun(
     base::RunLoop* run_loop) {
   volatile int line_number = __LINE__;
@@ -237,12 +210,6 @@
   CHECK_GT(line_number, 0);
 }
 
-NOINLINE void BrowserThreadImpl::CacheThreadRun(base::RunLoop* run_loop) {
-  volatile int line_number = __LINE__;
-  Thread::Run(run_loop);
-  CHECK_GT(line_number, 0);
-}
-
 NOINLINE void BrowserThreadImpl::IOThreadRun(base::RunLoop* run_loop) {
   volatile int line_number = __LINE__;
   Thread::Run(run_loop);
@@ -269,16 +236,8 @@
   switch (identifier_) {
     case BrowserThread::UI:
       return UIThreadRun(run_loop);
-    case BrowserThread::DB:
-      return DBThreadRun(run_loop);
-    case BrowserThread::FILE:
-      return FileThreadRun(run_loop);
-    case BrowserThread::FILE_USER_BLOCKING:
-      return FileUserBlockingThreadRun(run_loop);
     case BrowserThread::PROCESS_LAUNCHER:
       return ProcessLauncherThreadRun(run_loop);
-    case BrowserThread::CACHE:
-      return CacheThreadRun(run_loop);
     case BrowserThread::IO:
       return IOThreadRun(run_loop);
     case BrowserThread::ID_COUNT:
diff --git a/content/browser/browser_thread_impl.h b/content/browser/browser_thread_impl.h
index a9eca4c..fd03629 100644
--- a/content/browser/browser_thread_impl.h
+++ b/content/browser/browser_thread_impl.h
@@ -76,11 +76,7 @@
   // The following are unique function names that makes it possible to tell
   // the thread id from the callstack alone in crash dumps.
   void UIThreadRun(base::RunLoop* run_loop);
-  void DBThreadRun(base::RunLoop* run_loop);
-  void FileThreadRun(base::RunLoop* run_loop);
-  void FileUserBlockingThreadRun(base::RunLoop* run_loop);
   void ProcessLauncherThreadRun(base::RunLoop* run_loop);
-  void CacheThreadRun(base::RunLoop* run_loop);
   void IOThreadRun(base::RunLoop* run_loop);
 
   static bool PostTaskHelper(BrowserThread::ID identifier,
diff --git a/content/browser/dom_storage/dom_storage_browsertest.cc b/content/browser/dom_storage/dom_storage_browsertest.cc
index 0691e13..834b56b 100644
--- a/content/browser/dom_storage/dom_storage_browsertest.cc
+++ b/content/browser/dom_storage/dom_storage_browsertest.cc
@@ -4,12 +4,14 @@
 
 #include "base/command_line.h"
 #include "base/run_loop.h"
+#include "base/test/bind_test_util.h"
 #include "build/build_config.h"
 #include "content/browser/dom_storage/dom_storage_context_wrapper.h"
 #include "content/browser/dom_storage/local_storage_context_mojo.h"
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/common/dom_storage/dom_storage_types.h"
 #include "content/public/browser/browser_context.h"
+#include "content/public/browser/local_storage_usage_info.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/common/content_paths.h"
 #include "content/public/common/content_switches.h"
@@ -48,6 +50,30 @@
       FAIL() << "Failed: " << js_result;
     }
   }
+
+  std::vector<LocalStorageUsageInfo> GetUsage() {
+    auto* context = BrowserContext::GetDefaultStoragePartition(
+                        shell()->web_contents()->GetBrowserContext())
+                        ->GetDOMStorageContext();
+    base::RunLoop loop;
+    std::vector<LocalStorageUsageInfo> usage;
+    context->GetLocalStorageUsage(base::BindLambdaForTesting(
+        [&](const std::vector<LocalStorageUsageInfo>& u) {
+          usage = u;
+          loop.Quit();
+        }));
+    loop.Run();
+    return usage;
+  }
+
+  void DeletePhysicalOrigin(GURL origin) {
+    auto* context = BrowserContext::GetDefaultStoragePartition(
+                        shell()->web_contents()->GetBrowserContext())
+                        ->GetDOMStorageContext();
+    base::RunLoop loop;
+    context->DeleteLocalStorageForPhysicalOrigin(origin, loop.QuitClosure());
+    loop.Run();
+  }
 };
 
 class MojoDOMStorageBrowserTest : public DOMStorageBrowserTest {
@@ -120,6 +146,15 @@
   SimpleTest(GetTestUrl("dom_storage", "verify_data.html"), kNotIncognito);
 }
 
+IN_PROC_BROWSER_TEST_F(MojoDOMStorageBrowserTest, DeletePhysicalOrigin) {
+  EXPECT_EQ(0U, GetUsage().size());
+  SimpleTest(GetTestUrl("dom_storage", "store_data.html"), kNotIncognito);
+  std::vector<LocalStorageUsageInfo> usage = GetUsage();
+  ASSERT_EQ(1U, usage.size());
+  DeletePhysicalOrigin(usage[0].origin);
+  EXPECT_EQ(0U, GetUsage().size());
+}
+
 // On Windows file://localhost/C:/src/chromium/src/content/test/data/title1.html
 // doesn't work.
 #if !defined(OS_WIN)
diff --git a/content/browser/dom_storage/dom_storage_context_wrapper.cc b/content/browser/dom_storage/dom_storage_context_wrapper.cc
index 382ccddd..58293a1 100644
--- a/content/browser/dom_storage/dom_storage_context_wrapper.cc
+++ b/content/browser/dom_storage/dom_storage_context_wrapper.cc
@@ -65,6 +65,12 @@
   done_callback.Run();
 }
 
+void GotMojoDeletionCallback(
+    scoped_refptr<base::SingleThreadTaskRunner> reply_task_runner,
+    base::OnceClosure callback) {
+  reply_task_runner->PostTask(FROM_HERE, std::move(callback));
+}
+
 void GotMojoLocalStorageUsage(
     scoped_refptr<base::SingleThreadTaskRunner> reply_task_runner,
     const DOMStorageContext::GetLocalStorageUsageCallback& callback,
@@ -207,8 +213,10 @@
 }
 
 void DOMStorageContextWrapper::DeleteLocalStorageForPhysicalOrigin(
-    const GURL& origin) {
+    const GURL& origin,
+    base::OnceClosure callback) {
   DCHECK(context_.get());
+  DCHECK(callback);
   context_->task_runner()->PostShutdownBlockingTask(
       FROM_HERE, DOMStorageTaskRunner::PRIMARY_SEQUENCE,
       base::BindOnce(
@@ -223,12 +231,17 @@
         FROM_HERE,
         base::BindOnce(&LocalStorageContextMojo::DeleteStorageForPhysicalOrigin,
                        base::Unretained(mojo_state_),
-                       url::Origin::Create(origin)));
+                       url::Origin::Create(origin),
+                       base::BindOnce(&GotMojoDeletionCallback,
+                                      base::ThreadTaskRunnerHandle::Get(),
+                                      std::move(callback))));
   }
 }
 
-void DOMStorageContextWrapper::DeleteLocalStorage(const GURL& origin) {
+void DOMStorageContextWrapper::DeleteLocalStorage(const GURL& origin,
+                                                  base::OnceClosure callback) {
   DCHECK(context_.get());
+  DCHECK(callback);
   context_->task_runner()->PostShutdownBlockingTask(
       FROM_HERE, DOMStorageTaskRunner::PRIMARY_SEQUENCE,
       base::BindOnce(&DOMStorageContextImpl::DeleteLocalStorage, context_,
@@ -239,9 +252,13 @@
     // as soon as that task is posted, mojo_state_ is set to null, preventing
     // further tasks from being queued.
     mojo_task_runner_->PostTask(
-        FROM_HERE, base::BindOnce(&LocalStorageContextMojo::DeleteStorage,
-                                  base::Unretained(mojo_state_),
-                                  url::Origin::Create(origin)));
+        FROM_HERE,
+        base::BindOnce(&LocalStorageContextMojo::DeleteStorage,
+                       base::Unretained(mojo_state_),
+                       url::Origin::Create(origin),
+                       base::BindOnce(&GotMojoDeletionCallback,
+                                      base::ThreadTaskRunnerHandle::Get(),
+                                      std::move(callback))));
   }
 }
 
diff --git a/content/browser/dom_storage/dom_storage_context_wrapper.h b/content/browser/dom_storage/dom_storage_context_wrapper.h
index ccc7d2f..237bc05 100644
--- a/content/browser/dom_storage/dom_storage_context_wrapper.h
+++ b/content/browser/dom_storage/dom_storage_context_wrapper.h
@@ -56,8 +56,10 @@
       const GetLocalStorageUsageCallback& callback) override;
   void GetSessionStorageUsage(
       const GetSessionStorageUsageCallback& callback) override;
-  void DeleteLocalStorageForPhysicalOrigin(const GURL& origin) override;
-  void DeleteLocalStorage(const GURL& origin) override;
+  void DeleteLocalStorageForPhysicalOrigin(const GURL& origin,
+                                           base::OnceClosure callback) override;
+  void DeleteLocalStorage(const GURL& origin,
+                          base::OnceClosure callback) override;
   void DeleteSessionStorage(const SessionStorageUsageInfo& usage_info) override;
   void SetSaveSessionStorageOnDisk() override;
   scoped_refptr<SessionStorageNamespace> RecreateSessionStorage(
diff --git a/content/browser/dom_storage/local_storage_context_mojo.cc b/content/browser/dom_storage/local_storage_context_mojo.cc
index f7dfc76f9..802af4c 100644
--- a/content/browser/dom_storage/local_storage_context_mojo.cc
+++ b/content/browser/dom_storage/local_storage_context_mojo.cc
@@ -6,6 +6,7 @@
 
 #include <inttypes.h>
 #include <cctype>  // for std::isalnum
+#include "base/barrier_closure.h"
 #include "base/memory/ptr_util.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
@@ -81,8 +82,13 @@
   return key;
 }
 
-void NoOpSuccess(bool success) {}
-void NoOpDatabaseError(leveldb::mojom::DatabaseError error) {}
+void SuccessResponse(base::OnceClosure callback, bool success) {
+  std::move(callback).Run();
+}
+void DatabaseErrorResponse(base::OnceClosure callback,
+                           leveldb::mojom::DatabaseError error) {
+  std::move(callback).Run();
+}
 
 void MigrateStorageHelper(
     base::FilePath db_path,
@@ -397,10 +403,12 @@
                      weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
 }
 
-void LocalStorageContextMojo::DeleteStorage(const url::Origin& origin) {
+void LocalStorageContextMojo::DeleteStorage(const url::Origin& origin,
+                                            base::OnceClosure callback) {
   if (connection_state_ != CONNECTION_FINISHED) {
     RunWhenConnected(base::BindOnce(&LocalStorageContextMojo::DeleteStorage,
-                                    weak_ptr_factory_.GetWeakPtr(), origin));
+                                    weak_ptr_factory_.GetWeakPtr(), origin,
+                                    std::move(callback)));
     return;
   }
 
@@ -408,21 +416,26 @@
   if (found != level_db_wrappers_.end()) {
     // Renderer process expects |source| to always be two newline separated
     // strings.
-    found->second->level_db_wrapper()->DeleteAll("\n",
-                                                 base::BindOnce(&NoOpSuccess));
+    found->second->level_db_wrapper()->DeleteAll(
+        "\n", base::BindOnce(&SuccessResponse, std::move(callback)));
     found->second->level_db_wrapper()->ScheduleImmediateCommit();
   } else if (database_) {
     std::vector<leveldb::mojom::BatchedOperationPtr> operations;
     AddDeleteOriginOperations(&operations, origin);
-    database_->Write(std::move(operations), base::BindOnce(&NoOpDatabaseError));
+    database_->Write(
+        std::move(operations),
+        base::BindOnce(&DatabaseErrorResponse, std::move(callback)));
+  } else {
+    std::move(callback).Run();
   }
 }
 
 void LocalStorageContextMojo::DeleteStorageForPhysicalOrigin(
-    const url::Origin& origin) {
+    const url::Origin& origin,
+    base::OnceClosure callback) {
   GetStorageUsage(base::BindOnce(
       &LocalStorageContextMojo::OnGotStorageUsageForDeletePhysicalOrigin,
-      weak_ptr_factory_.GetWeakPtr(), origin));
+      weak_ptr_factory_.GetWeakPtr(), origin, std::move(callback)));
 }
 
 void LocalStorageContextMojo::Flush() {
@@ -963,14 +976,21 @@
 
 void LocalStorageContextMojo::OnGotStorageUsageForDeletePhysicalOrigin(
     const url::Origin& origin,
+    base::OnceClosure callback,
     std::vector<LocalStorageUsageInfo> usage) {
+  // Wait for callbacks for each entry in |usage| and a callback for |origin|.
+  base::RepeatingClosure barrier =
+      base::BarrierClosure(usage.size() + 1, std::move(callback));
   for (const auto& info : usage) {
     url::Origin origin_candidate = url::Origin::Create(info.origin);
     if (!origin_candidate.IsSameOriginWith(origin) &&
-        origin_candidate.IsSamePhysicalOriginWith(origin))
-      DeleteStorage(origin_candidate);
+        origin_candidate.IsSamePhysicalOriginWith(origin)) {
+      DeleteStorage(origin_candidate, barrier);
+    } else {
+      barrier.Run();
+    }
   }
-  DeleteStorage(origin);
+  DeleteStorage(origin, barrier);
 }
 
 void LocalStorageContextMojo::OnGotStorageUsageForShutdown(
diff --git a/content/browser/dom_storage/local_storage_context_mojo.h b/content/browser/dom_storage/local_storage_context_mojo.h
index e100572..407e17d 100644
--- a/content/browser/dom_storage/local_storage_context_mojo.h
+++ b/content/browser/dom_storage/local_storage_context_mojo.h
@@ -57,9 +57,12 @@
   void OpenLocalStorage(const url::Origin& origin,
                         mojom::LevelDBWrapperRequest request);
   void GetStorageUsage(GetStorageUsageCallback callback);
-  void DeleteStorage(const url::Origin& origin);
+  // |callback| is called when the deletion is sent to the database and
+  // GetStorageUsage() will not return entries for |origin| anymore.
+  void DeleteStorage(const url::Origin& origin, base::OnceClosure callback);
   // Like DeleteStorage(), but also deletes storage for all sub-origins.
-  void DeleteStorageForPhysicalOrigin(const url::Origin& origin);
+  void DeleteStorageForPhysicalOrigin(const url::Origin& origin,
+                                      base::OnceClosure callback);
   void Flush();
   void FlushOriginForTesting(const url::Origin& origin);
 
@@ -130,6 +133,7 @@
 
   void OnGotStorageUsageForDeletePhysicalOrigin(
       const url::Origin& origin,
+      base::OnceClosure callback,
       std::vector<LocalStorageUsageInfo> usage);
 
   void OnGotStorageUsageForShutdown(std::vector<LocalStorageUsageInfo> usage);
diff --git a/content/browser/dom_storage/local_storage_context_mojo_unittest.cc b/content/browser/dom_storage/local_storage_context_mojo_unittest.cc
index c7b69d5..a9d4bb5 100644
--- a/content/browser/dom_storage/local_storage_context_mojo_unittest.cc
+++ b/content/browser/dom_storage/local_storage_context_mojo_unittest.cc
@@ -512,8 +512,10 @@
   set_mock_data("VERSION", "1");
   set_mock_data(std::string("_http://foobar.com") + '\x00' + "key", "value");
 
-  context()->DeleteStorage(url::Origin::Create(GURL("http://foobar.com")));
-  base::RunLoop().RunUntilIdle();
+  base::RunLoop run_loop;
+  context()->DeleteStorage(url::Origin::Create(GURL("http://foobar.com")),
+                           run_loop.QuitClosure());
+  run_loop.Run();
   EXPECT_EQ(1u, mock_data().size());
 }
 
@@ -538,7 +540,7 @@
   base::RunLoop().RunUntilIdle();
   EXPECT_FALSE(mock_data().empty());
 
-  context()->DeleteStorage(origin1);
+  context()->DeleteStorage(origin1, base::BindOnce(&base::DoNothing));
   base::RunLoop().RunUntilIdle();
 
   // Data from origin2 should exist, including meta-data, but nothing should
@@ -580,7 +582,7 @@
   wrapper->AddObserver(observer.Bind());
   base::RunLoop().RunUntilIdle();
 
-  context()->DeleteStorage(origin1);
+  context()->DeleteStorage(origin1, base::BindOnce(&base::DoNothing));
   base::RunLoop().RunUntilIdle();
 
   ASSERT_EQ(1u, observer.observations().size());
@@ -628,7 +630,7 @@
                base::BindOnce(&NoOpSuccess));
   base::RunLoop().RunUntilIdle();
 
-  context()->DeleteStorage(origin1);
+  context()->DeleteStorage(origin1, base::BindOnce(&base::DoNothing));
   base::RunLoop().RunUntilIdle();
 
   ASSERT_EQ(2u, observer.observations().size());
@@ -677,7 +679,8 @@
   base::RunLoop().RunUntilIdle();
   EXPECT_FALSE(mock_data().empty());
 
-  context()->DeleteStorageForPhysicalOrigin(origin1b);
+  context()->DeleteStorageForPhysicalOrigin(origin1b,
+                                            base::BindOnce(&base::DoNothing));
   base::RunLoop().RunUntilIdle();
 
   // Data from origin2 should exist, including meta-data, but nothing should
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc
index 0faad5d..dad3e18e 100644
--- a/content/browser/frame_host/render_frame_host_manager.cc
+++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -1316,6 +1316,8 @@
   // isn't a strict invariant but rather a heuristic to avoid unnecessary
   // OOPIFs; see https://crbug.com/711006.  Note that this shouldn't apply to
   // TopDocumentIsolation, so do this after TDI checks above.
+  //
+  // TODO(alexmos): Remove this check after fixing https://crbug.com/787576.
   if (!frame_tree_node_->IsMainFrame()) {
     RenderFrameHostImpl* parent =
         frame_tree_node_->parent()->current_frame_host();
@@ -1382,6 +1384,20 @@
     return true;
   }
 
+  // If the destination URL is not same-site with current RenderFrameHost and
+  // doesn't require a dedicated process (see above), but it is same-site with
+  // the opener RenderFrameHost, attempt a transfer so that the destination URL
+  // can go back to the opener SiteInstance.  This avoids breaking scripting in
+  // some cases when only a subset of sites is isolated
+  // (https://crbug.com/807184).
+  //
+  // TODO(alexmos): This is a temporary workaround and should be removed after
+  // fixing https://crbug.com/787576.
+  FrameTreeNode* opener = frame_tree_node_->opener();
+  if (opener && IsCurrentlySameSite(opener->current_frame_host(), dest_url) &&
+      opener->current_frame_host()->GetSiteInstance() != rfh->GetSiteInstance())
+    return true;
+
   return false;
 }
 
diff --git a/content/browser/isolated_origin_browsertest.cc b/content/browser/isolated_origin_browsertest.cc
index 89fc7f4b..547bb6e 100644
--- a/content/browser/isolated_origin_browsertest.cc
+++ b/content/browser/isolated_origin_browsertest.cc
@@ -421,6 +421,77 @@
   EXPECT_EQ(bar_url2.spec(), popup_location);
 }
 
+// Check that when a non-isolated-origin page opens a popup, navigates it
+// to an isolated origin, and then the popup navigates to a third non-isolated
+// origin and finally back to its opener's origin, the popup and the opener
+// iframe end up in the same process and can script each other:
+//
+//   foo.com
+//      |
+//  window.open()
+//      |
+//      V
+//  about:blank -> isolated.foo.com -> bar.com -> foo.com
+//
+// This is a variant of PopupNavigatesToIsolatedOriginAndBack where the popup
+// navigates to a third site before coming back to the opener's site. See
+// https://crbug.com/807184.
+IN_PROC_BROWSER_TEST_F(IsolatedOriginTest,
+                       PopupNavigatesToIsolatedOriginThenToAnotherSiteAndBack) {
+  // Start on www.foo.com.
+  GURL foo_url(embedded_test_server()->GetURL("www.foo.com", "/title1.html"));
+  EXPECT_TRUE(NavigateToURL(shell(), foo_url));
+  FrameTreeNode* root = web_contents()->GetFrameTree()->root();
+
+  // Open a blank popup.
+  ShellAddedObserver new_shell_observer;
+  EXPECT_TRUE(ExecuteScript(root, "window.w = window.open();"));
+  Shell* new_shell = new_shell_observer.GetShell();
+
+  // Have the opener navigate the popup to an isolated origin.
+  GURL isolated_url(
+      embedded_test_server()->GetURL("isolated.foo.com", "/title1.html"));
+  {
+    TestNavigationManager manager(new_shell->web_contents(), isolated_url);
+    EXPECT_TRUE(ExecuteScript(
+        root, "window.w.location.href = '" + isolated_url.spec() + "';"));
+    manager.WaitForNavigationFinished();
+  }
+
+  // Simulate the isolated origin in the popup navigating to bar.com.
+  GURL bar_url(embedded_test_server()->GetURL("bar.com", "/title2.html"));
+  {
+    TestNavigationManager manager(new_shell->web_contents(), bar_url);
+    EXPECT_TRUE(
+        ExecuteScript(new_shell, "location.href = '" + bar_url.spec() + "';"));
+    manager.WaitForNavigationFinished();
+  }
+
+  // At this point, the popup and the opener should still be in separate
+  // SiteInstances.
+  EXPECT_NE(new_shell->web_contents()->GetMainFrame()->GetSiteInstance(),
+            root->current_frame_host()->GetSiteInstance());
+
+  // Simulate the isolated origin in the popup navigating to www.foo.com.
+  {
+    TestNavigationManager manager(new_shell->web_contents(), foo_url);
+    EXPECT_TRUE(
+        ExecuteScript(new_shell, "location.href = '" + foo_url.spec() + "';"));
+    manager.WaitForNavigationFinished();
+  }
+
+  // The popup should now be in the same SiteInstance as its same-site opener.
+  EXPECT_EQ(new_shell->web_contents()->GetMainFrame()->GetSiteInstance(),
+            root->current_frame_host()->GetSiteInstance());
+
+  // Check that the popup can script the opener.
+  std::string opener_location;
+  EXPECT_TRUE(ExecuteScriptAndExtractString(
+      new_shell, "domAutomationController.send(window.opener.location.href);",
+      &opener_location));
+  EXPECT_EQ(foo_url.spec(), opener_location);
+}
+
 // Check that with an ABA hierarchy, where B is an isolated origin, the root
 // and grandchild frames end up in the same process and can script each other.
 // See https://crbug.com/796912.
diff --git a/content/browser/loader/data_pipe_to_source_stream.cc b/content/browser/loader/data_pipe_to_source_stream.cc
new file mode 100644
index 0000000..2748b6f
--- /dev/null
+++ b/content/browser/loader/data_pipe_to_source_stream.cc
@@ -0,0 +1,101 @@
+// 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 "content/browser/loader/data_pipe_to_source_stream.h"
+
+#include "base/auto_reset.h"
+#include "net/base/io_buffer.h"
+
+namespace content {
+
+DataPipeToSourceStream::DataPipeToSourceStream(
+    mojo::ScopedDataPipeConsumerHandle body)
+    : net::SourceStream(net::SourceStream::TYPE_NONE),
+      body_(std::move(body)),
+      handle_watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL) {
+  handle_watcher_.Watch(
+      body_.get(), MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
+      base::BindRepeating(&DataPipeToSourceStream::OnReadable,
+                          base::Unretained(this)));
+}
+
+DataPipeToSourceStream::~DataPipeToSourceStream() = default;
+
+std::string DataPipeToSourceStream::Description() const {
+  return "DataPipe";
+}
+
+int DataPipeToSourceStream::Read(net::IOBuffer* buf,
+                                 int buf_size,
+                                 const net::CompletionCallback& callback) {
+  base::AutoReset<bool>(&inside_read_, true);
+
+  if (!body_.get()) {
+    // We have finished reading the pipe.
+    return 0;
+  }
+
+  const void* buffer = nullptr;
+  uint32_t available = 0;
+  MojoResult result =
+      body_->BeginReadData(&buffer, &available, MOJO_READ_DATA_FLAG_NONE);
+  switch (result) {
+    case MOJO_RESULT_OK: {
+      uint32_t consume =
+          std::min(base::checked_cast<uint32_t>(buf_size), available);
+      memcpy(buf->data(), buffer, consume);
+      body_->EndReadData(consume);
+      return base::checked_cast<int>(consume);
+    }
+    case MOJO_RESULT_FAILED_PRECONDITION:
+      // Finished reading.
+      FinishReading();
+      return 0;
+    case MOJO_RESULT_SHOULD_WAIT:
+      // Data is not available yet.
+      pending_callback_ = callback;
+      output_buf_ = buf;
+      output_buf_size_ = buf_size;
+      handle_watcher_.ArmOrNotify();
+      return net::ERR_IO_PENDING;
+  }
+  NOTREACHED() << static_cast<int>(result);
+  return net::ERR_UNEXPECTED;
+}
+
+void DataPipeToSourceStream::OnReadable(MojoResult unused) {
+  // It's not expected that we call this synchronously inside Read.
+  DCHECK(!inside_read_);
+  DCHECK(pending_callback_);
+  DCHECK(output_buf_);
+  const void* buffer = nullptr;
+  uint32_t available = 0;
+  MojoResult result =
+      body_->BeginReadData(&buffer, &available, MOJO_READ_DATA_FLAG_NONE);
+  switch (result) {
+    case MOJO_RESULT_OK: {
+      uint32_t consume =
+          std::min(base::checked_cast<uint32_t>(output_buf_size_), available);
+      memcpy(output_buf_->data(), buffer, consume);
+      body_->EndReadData(consume);
+      std::move(pending_callback_).Run(consume);
+      return;
+    }
+    case MOJO_RESULT_FAILED_PRECONDITION:
+      FinishReading();
+      std::move(pending_callback_).Run(0);
+      return;
+    case MOJO_RESULT_SHOULD_WAIT:
+      handle_watcher_.ArmOrNotify();
+      return;
+  }
+  NOTREACHED() << static_cast<int>(result);
+}
+
+void DataPipeToSourceStream::FinishReading() {
+  handle_watcher_.Cancel();
+  body_.reset();
+}
+
+}  // namespace content
diff --git a/content/browser/loader/data_pipe_to_source_stream.h b/content/browser/loader/data_pipe_to_source_stream.h
new file mode 100644
index 0000000..0616cfd
--- /dev/null
+++ b/content/browser/loader/data_pipe_to_source_stream.h
@@ -0,0 +1,42 @@
+// 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 CONTENT_BROWSER_LOADER_DATA_PIPE_TO_SOURCE_STREAM_H_
+#define CONTENT_BROWSER_LOADER_DATA_PIPE_TO_SOURCE_STREAM_H_
+
+#include "mojo/public/cpp/system/data_pipe.h"
+#include "mojo/public/cpp/system/simple_watcher.h"
+#include "net/filter/source_stream.h"
+
+namespace content {
+
+class DataPipeToSourceStream final : public net::SourceStream {
+ public:
+  explicit DataPipeToSourceStream(mojo::ScopedDataPipeConsumerHandle body);
+  ~DataPipeToSourceStream() override;
+
+  int Read(net::IOBuffer* buf,
+           int buf_size,
+           const net::CompletionCallback& callback) override;
+  std::string Description() const override;
+
+ private:
+  void OnReadable(MojoResult result);
+  void FinishReading();
+
+  mojo::ScopedDataPipeConsumerHandle body_;
+  mojo::SimpleWatcher handle_watcher_;
+
+  bool inside_read_ = false;
+
+  scoped_refptr<net::IOBuffer> output_buf_;
+  int output_buf_size_ = 0;
+  net::CompletionCallback pending_callback_;
+
+  DISALLOW_COPY_AND_ASSIGN(DataPipeToSourceStream);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_LOADER_DATA_PIPE_TO_SOURCE_STREAM_H_
diff --git a/content/browser/loader/signed_exchange_handler.cc b/content/browser/loader/signed_exchange_handler.cc
index 95e611c..6cf5bca 100644
--- a/content/browser/loader/signed_exchange_handler.cc
+++ b/content/browser/loader/signed_exchange_handler.cc
@@ -7,87 +7,124 @@
 #include "base/feature_list.h"
 #include "content/public/common/content_features.h"
 #include "mojo/public/cpp/system/string_data_pipe_producer.h"
+#include "net/base/io_buffer.h"
 #include "net/http/http_response_headers.h"
 #include "services/network/public/cpp/resource_response.h"
 #include "services/network/public/cpp/url_loader_completion_status.h"
 
 namespace content {
-namespace {
-
-constexpr size_t kPipeSizeForSignedResponseBody = 65536;
-
-}  // namespace
 
 SignedExchangeHandler::SignedExchangeHandler(
-    mojo::ScopedDataPipeConsumerHandle body)
-    : body_(std::move(body)) {
+    std::unique_ptr<net::SourceStream> upstream,
+    ExchangeHeadersCallback headers_callback)
+    : net::FilterSourceStream(net::SourceStream::TYPE_NONE,
+                              std::move(upstream)),
+      headers_callback_(std::move(headers_callback)),
+      weak_factory_(this) {
   DCHECK(base::FeatureList::IsEnabled(features::kSignedHTTPExchange));
+
+  // Triggering the first read (asynchronously) for header parsing.
+  header_out_buf_ = base::MakeRefCounted<net::IOBufferWithSize>(1);
+  base::SequencedTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE, base::BindOnce(&SignedExchangeHandler::DoHeaderLoop,
+                                weak_factory_.GetWeakPtr()));
 }
 
 SignedExchangeHandler::~SignedExchangeHandler() = default;
 
-void SignedExchangeHandler::GetHTTPExchange(
-    ExchangeFoundCallback found_callback,
-    ExchangeFinishedCallback finish_callback) {
-  DCHECK(!found_callback_);
-  DCHECK(!finish_callback_);
-  found_callback_ = std::move(found_callback);
-  finish_callback_ = std::move(finish_callback);
+int SignedExchangeHandler::FilterData(net::IOBuffer* output_buffer,
+                                      int output_buffer_size,
+                                      net::IOBuffer* input_buffer,
+                                      int input_buffer_size,
+                                      int* consumed_bytes,
+                                      bool upstream_eof_reached) {
+  *consumed_bytes = 0;
 
-  drainer_.reset(new mojo::common::DataPipeDrainer(this, std::move(body_)));
+  original_body_string_.append(input_buffer->data(), input_buffer_size);
+  *consumed_bytes += input_buffer_size;
+
+  // We shouldn't write any data into the out buffer while we're
+  // parsing the header.
+  if (headers_callback_)
+    return 0;
+
+  if (upstream_eof_reached) {
+    // Run the parser code if this part is run for the first time.
+    // Now original_body_string_ has the entire body.
+    // (Note that we may come here multiple times if output_buffer_size
+    // is not big enough.
+    // TODO(https://crbug.com/803774): Do the streaming instead.
+    size_t size_to_copy =
+        std::min(original_body_string_.size() - body_string_offset_,
+                 base::checked_cast<size_t>(output_buffer_size));
+    memcpy(output_buffer->data(),
+           original_body_string_.data() + body_string_offset_, size_to_copy);
+    body_string_offset_ += size_to_copy;
+    return base::checked_cast<int>(size_to_copy);
+  }
+
+  return 0;
 }
 
-void SignedExchangeHandler::OnDataAvailable(const void* data,
-                                            size_t num_bytes) {
-  original_body_string_.append(static_cast<const char*>(data), num_bytes);
+std::string SignedExchangeHandler::GetTypeAsString() const {
+  return "HTXG";  // Tentative.
 }
 
-void SignedExchangeHandler::OnDataComplete() {
-  if (!found_callback_)
+void SignedExchangeHandler::DoHeaderLoop() {
+  // Run the internal read loop by ourselves until we finish
+  // parsing the headers. (After that the caller should pumb
+  // the Read() calls).
+  DCHECK(headers_callback_);
+  DCHECK(header_out_buf_);
+  int rv = Read(header_out_buf_.get(), header_out_buf_->size(),
+                base::BindRepeating(&SignedExchangeHandler::DidReadForHeaders,
+                                    base::Unretained(this), false /* sync */));
+  if (rv != net::ERR_IO_PENDING)
+    DidReadForHeaders(true /* sync */, rv);
+}
+
+void SignedExchangeHandler::DidReadForHeaders(bool completed_syncly,
+                                              int result) {
+  if (MaybeRunHeadersCallback() || result < 0)
     return;
+  DCHECK_EQ(0, result);
+  if (completed_syncly) {
+    base::SequencedTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE, base::BindOnce(&SignedExchangeHandler::DoHeaderLoop,
+                                  weak_factory_.GetWeakPtr()));
+  } else {
+    DoHeaderLoop();
+  }
+}
 
+bool SignedExchangeHandler::MaybeRunHeadersCallback() {
+  if (!headers_callback_)
+    return false;
+
+  // If this was the first read, fire the headers callback now.
+  // TODO(https://crbug.com/803774): This is just for testing, we should
+  // implement the CBOR parsing here.
+  FillMockExchangeHeaders();
+  std::move(headers_callback_)
+      .Run(request_url_, request_method_, response_head_, ssl_info_);
+
+  // TODO(https://crbug.com/803774) Consume the bytes size that were
+  // necessary to read out the headers.
+
+  return true;
+}
+
+void SignedExchangeHandler::FillMockExchangeHeaders() {
   // TODO(https://crbug.com/803774): Get the request url by parsing CBOR format.
-  GURL request_url = GURL("https://example.com/test.html");
+  request_url_ = GURL("https://example.com/test.html");
   // TODO(https://crbug.com/803774): Get the request method by parsing CBOR
   // format.
-  std::string request_method = "GET";
-  // TODO(https://crbug.com/803774): Get the payload by parsing CBOR format.
-  std::string payload = original_body_string_;
-  original_body_string_.clear();
-
+  request_method_ = "GET";
   // TODO(https://crbug.com/803774): Get more headers by parsing CBOR.
   scoped_refptr<net::HttpResponseHeaders> headers(
       new net::HttpResponseHeaders("HTTP/1.1 200 OK"));
-  network::ResourceResponseHead resource_response;
-  resource_response.headers = headers;
-  resource_response.mime_type = "text/html";
-
-  // TODO(https://crbug.com/803774): Get the certificate by parsing CBOR and
-  // verify.
-  base::Optional<net::SSLInfo> ssl_info;
-
-  mojo::DataPipe pipe(kPipeSizeForSignedResponseBody);
-  // TODO(https://crbug.com/803774): Write the error handling code. This could
-  // fail.
-  DCHECK(pipe.consumer_handle.is_valid());
-  mojo::ScopedDataPipeConsumerHandle response_body =
-      std::move(pipe.consumer_handle);
-  std::move(found_callback_)
-      .Run(request_url, request_method, resource_response, std::move(ssl_info),
-           std::move(response_body));
-
-  data_producer_ = std::make_unique<mojo::StringDataPipeProducer>(
-      std::move(pipe.producer_handle));
-  data_producer_->Write(payload,
-                        base::BindOnce(&SignedExchangeHandler::OnDataWritten,
-                                       base::Unretained(this)));
-}
-
-void SignedExchangeHandler::OnDataWritten(MojoResult result) {
-  data_producer_.reset();
-  std::move(finish_callback_)
-      .Run(network::URLLoaderCompletionStatus(
-          result == MOJO_RESULT_OK ? net::OK : net::ERR_FAILED));
+  response_head_.headers = headers;
+  response_head_.mime_type = "text/html";
 }
 
 }  // namespace content
diff --git a/content/browser/loader/signed_exchange_handler.h b/content/browser/loader/signed_exchange_handler.h
index 92bdf28..d0f6048f 100644
--- a/content/browser/loader/signed_exchange_handler.h
+++ b/content/browser/loader/signed_exchange_handler.h
@@ -9,20 +9,13 @@
 
 #include "base/callback.h"
 #include "base/optional.h"
-#include "mojo/common/data_pipe_drainer.h"
 #include "mojo/public/cpp/system/data_pipe.h"
+#include "net/base/completion_callback.h"
+#include "net/filter/filter_source_stream.h"
 #include "net/ssl/ssl_info.h"
+#include "services/network/public/cpp/resource_response.h"
 #include "url/gurl.h"
 
-namespace mojo {
-class StringDataPipeProducer;
-}  // namespace mojo
-
-namespace network {
-struct ResourceResponseHead;
-struct URLLoaderCompletionStatus;
-}  // namespace network
-
 namespace content {
 
 // IMPORTANT: Currenly SignedExchangeHandler doesn't implement any CBOR parsing
@@ -31,47 +24,58 @@
 // a response with a payload which is equal to the original body.
 // TODO(https://crbug.com/803774): Implement CBOR parsing logic and verifying
 // logic.
-class SignedExchangeHandler final
-    : public mojo::common::DataPipeDrainer::Client {
+class SignedExchangeHandler final : public net::FilterSourceStream {
  public:
-  using ExchangeFoundCallback =
+  // TODO(https://crbug.com/803774): Add verification status here.
+  using ExchangeHeadersCallback =
       base::OnceCallback<void(const GURL& request_url,
                               const std::string& request_method,
                               const network::ResourceResponseHead&,
-                              base::Optional<net::SSLInfo>,
-                              mojo::ScopedDataPipeConsumerHandle)>;
-  using ExchangeFinishedCallback =
-      base::OnceCallback<void(const network::URLLoaderCompletionStatus&)>;
+                              base::Optional<net::SSLInfo>)>;
 
-  // The passed |body| will be read to parse the signed HTTP exchange.
-  // TODO(https://crbug.com/803774): Consider making SignedExchangeHandler
-  // independent from DataPipe to make it easy to port it in //net.
-  explicit SignedExchangeHandler(mojo::ScopedDataPipeConsumerHandle body);
-
+  // Once constructed |this| starts reading the |body| and parses the response
+  // as a signed HTTP exchange. The response body of the exchange can be read
+  // from |this| as a net::SourceStream after |headers_callback| is called.
+  SignedExchangeHandler(std::unique_ptr<net::SourceStream> body,
+                        ExchangeHeadersCallback headers_callback);
   ~SignedExchangeHandler() override;
 
-  // TODO(https://crbug.com/803774): Currently SignedExchangeHandler always
-  // calls found_callback and then calls finish_callback after reading the all
-  // buffer. Need to redesign this callback model when we will introduce
-  // SignedExchangeHandler::Reader class to read the body and introduce the
-  // cert verification.
-  void GetHTTPExchange(ExchangeFoundCallback found_callback,
-                       ExchangeFinishedCallback finish_callback);
+  // net::FilterSourceStream:
+  int FilterData(net::IOBuffer* output_buffer,
+                 int output_buffer_size,
+                 net::IOBuffer* input_buffer,
+                 int input_buffer_size,
+                 int* consumed_bytes,
+                 bool upstream_eof_reached) override;
+  std::string GetTypeAsString() const override;
 
  private:
-  // mojo::Common::DataPipeDrainer::Client
-  void OnDataAvailable(const void* data, size_t num_bytes) override;
-  void OnDataComplete() override;
+  void DoHeaderLoop();
+  void DidReadForHeaders(bool completed_syncly, int result);
+  bool MaybeRunHeadersCallback();
 
-  // Called from |data_producer_|.
-  void OnDataWritten(MojoResult result);
+  // TODO(https://crbug.com/803774): Remove this.
+  void FillMockExchangeHeaders();
 
-  mojo::ScopedDataPipeConsumerHandle body_;
-  std::unique_ptr<mojo::common::DataPipeDrainer> drainer_;
-  ExchangeFoundCallback found_callback_;
-  ExchangeFinishedCallback finish_callback_;
+  // Signed exchange contents.
+  GURL request_url_;
+  std::string request_method_;
+  network::ResourceResponseHead response_head_;
+  base::Optional<net::SSLInfo> ssl_info_;
+
+  ExchangeHeadersCallback headers_callback_;
+
+  // Internal IOBuffer used during reading the header. Note that during parsing
+  // the header we don't really need the output buffer, but we still need to
+  // give some > 0 buffer.
+  scoped_refptr<net::IOBufferWithSize> header_out_buf_;
+
+  // TODO(https://crbug.cxom/803774): Just for now. Implement the streaming
+  // parser.
   std::string original_body_string_;
-  std::unique_ptr<mojo::StringDataPipeProducer> data_producer_;
+  size_t body_string_offset_ = 0;
+
+  base::WeakPtrFactory<SignedExchangeHandler> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(SignedExchangeHandler);
 };
diff --git a/content/browser/loader/source_stream_to_data_pipe.cc b/content/browser/loader/source_stream_to_data_pipe.cc
new file mode 100644
index 0000000..fcf961d37
--- /dev/null
+++ b/content/browser/loader/source_stream_to_data_pipe.cc
@@ -0,0 +1,113 @@
+// 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 "content/browser/loader/source_stream_to_data_pipe.h"
+
+#include "base/bind.h"
+#include "net/filter/source_stream.h"
+
+namespace content {
+
+SourceStreamToDataPipe::SourceStreamToDataPipe(
+    net::SourceStream* source,
+    mojo::ScopedDataPipeProducerHandle dest,
+    base::OnceCallback<void(int)> completion_callback)
+    : source_(source),
+      dest_(std::move(dest)),
+      completion_callback_(std::move(completion_callback)),
+      writable_handle_watcher_(FROM_HERE,
+                               mojo::SimpleWatcher::ArmingPolicy::MANUAL),
+      peer_closed_handle_watcher_(FROM_HERE,
+                                  mojo::SimpleWatcher::ArmingPolicy::MANUAL),
+      weak_factory_(this) {
+  peer_closed_handle_watcher_.Watch(
+      dest_.get(), MOJO_HANDLE_SIGNAL_PEER_CLOSED,
+      base::BindRepeating(&SourceStreamToDataPipe::OnDataPipeClosed,
+                          base::Unretained(this)));
+  peer_closed_handle_watcher_.ArmOrNotify();
+  writable_handle_watcher_.Watch(
+      dest_.get(), MOJO_HANDLE_SIGNAL_WRITABLE,
+      base::BindRepeating(&SourceStreamToDataPipe::OnDataPipeWritable,
+                          base::Unretained(this)));
+}
+
+SourceStreamToDataPipe::~SourceStreamToDataPipe() = default;
+
+void SourceStreamToDataPipe::Start() {
+  ReadMore();
+}
+
+void SourceStreamToDataPipe::ReadMore() {
+  DCHECK(!pending_write_.get());
+
+  uint32_t num_bytes;
+  MojoResult mojo_result = network::NetToMojoPendingBuffer::BeginWrite(
+      &dest_, &pending_write_, &num_bytes);
+  if (mojo_result == MOJO_RESULT_SHOULD_WAIT) {
+    // The pipe is full.  We need to wait for it to have more space.
+    writable_handle_watcher_.ArmOrNotify();
+    return;
+  } else if (mojo_result != MOJO_RESULT_OK) {
+    // The body stream is in a bad state. Bail out.
+    OnComplete(net::ERR_UNEXPECTED);
+    return;
+  }
+
+  scoped_refptr<net::IOBuffer> buffer(
+      new network::NetToMojoIOBuffer(pending_write_.get()));
+  int result =
+      source_->Read(buffer.get(), base::checked_cast<int>(num_bytes),
+                    base::BindRepeating(&SourceStreamToDataPipe::DidRead,
+                                        base::Unretained(this)));
+
+  if (result != net::ERR_IO_PENDING)
+    DidRead(result);
+}
+
+void SourceStreamToDataPipe::DidRead(int result) {
+  DCHECK(pending_write_);
+  if (result < 0) {
+    // An error case.
+    OnComplete(result);
+    return;
+  }
+  if (result == 0) {
+    pending_write_->Complete(0);
+    OnComplete(net::OK);
+    return;
+  }
+  dest_ = pending_write_->Complete(result);
+  pending_write_ = nullptr;
+
+  base::SequencedTaskRunnerHandle::Get()->PostTask(
+      FROM_HERE, base::BindOnce(&SourceStreamToDataPipe::ReadMore,
+                                weak_factory_.GetWeakPtr()));
+}
+
+void SourceStreamToDataPipe::OnDataPipeWritable(MojoResult result) {
+  if (result == MOJO_RESULT_FAILED_PRECONDITION) {
+    OnComplete(net::ERR_ABORTED);
+    return;
+  }
+  DCHECK_EQ(result, MOJO_RESULT_OK) << result;
+
+  ReadMore();
+}
+
+void SourceStreamToDataPipe::OnDataPipeClosed(MojoResult result) {
+  OnComplete(net::ERR_ABORTED);
+}
+
+void SourceStreamToDataPipe::OnComplete(int result) {
+  // Resets the watchers, pipes and the exchange handler, so that
+  // we will never be called back.
+  writable_handle_watcher_.Cancel();
+  peer_closed_handle_watcher_.Cancel();
+  pending_write_ = nullptr;  // Closes the data pipe if this was holding it.
+  dest_.reset();
+
+  std::move(completion_callback_).Run(result);
+}
+
+}  // namespace content
diff --git a/content/browser/loader/source_stream_to_data_pipe.h b/content/browser/loader/source_stream_to_data_pipe.h
new file mode 100644
index 0000000..f54c5d9
--- /dev/null
+++ b/content/browser/loader/source_stream_to_data_pipe.h
@@ -0,0 +1,56 @@
+// 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 CONTENT_BROWSER_LOADER_SOURCE_STREAM_TO_DATA_PIPE_H_
+#define CONTENT_BROWSER_LOADER_SOURCE_STREAM_TO_DATA_PIPE_H_
+
+#include "base/callback_forward.h"
+#include "base/memory/weak_ptr.h"
+#include "mojo/public/cpp/system/data_pipe.h"
+#include "mojo/public/cpp/system/simple_watcher.h"
+#include "services/network/public/cpp/net_adapters.h"
+
+namespace net {
+class SourceStream;
+}
+
+namespace content {
+
+// A convenient adapter class to read out data from net::SourceStream
+// and write them into a data pipe.
+class SourceStreamToDataPipe {
+ public:
+  // Reads out the data from |source| and write into |dest|.
+  // Note that this does not take the ownership of |source|, the caller
+  // needs to take care that it is kept alive.
+  SourceStreamToDataPipe(net::SourceStream* source,
+                         mojo::ScopedDataPipeProducerHandle dest,
+                         base::OnceCallback<void(int)> completion_callback);
+  ~SourceStreamToDataPipe();
+
+  // Start reading the source.
+  void Start();
+
+ private:
+  void ReadMore();
+  void DidRead(int result);
+
+  void OnDataPipeWritable(MojoResult result);
+  void OnDataPipeClosed(MojoResult result);
+  void OnComplete(int result);
+
+  net::SourceStream* source_;  // Not owned.
+  mojo::ScopedDataPipeProducerHandle dest_;
+  base::OnceCallback<void(int)> completion_callback_;
+
+  scoped_refptr<network::NetToMojoPendingBuffer> pending_write_;
+  mojo::SimpleWatcher writable_handle_watcher_;
+  mojo::SimpleWatcher peer_closed_handle_watcher_;
+
+  base::WeakPtrFactory<SourceStreamToDataPipe> weak_factory_;
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_LOADER_SOURCE_STREAM_TO_DATA_PIPE_H_
diff --git a/content/browser/loader/web_package_loader.cc b/content/browser/loader/web_package_loader.cc
index fe70f71d..ed30bb6 100644
--- a/content/browser/loader/web_package_loader.cc
+++ b/content/browser/loader/web_package_loader.cc
@@ -6,10 +6,13 @@
 
 #include "base/feature_list.h"
 #include "base/strings/stringprintf.h"
+#include "content/browser/loader/data_pipe_to_source_stream.h"
 #include "content/browser/loader/signed_exchange_handler.h"
+#include "content/browser/loader/source_stream_to_data_pipe.h"
 #include "content/public/common/content_features.h"
 #include "net/http/http_util.h"
 #include "services/network/public/cpp/features.h"
+#include "services/network/public/cpp/url_loader_completion_status.h"
 
 namespace content {
 
@@ -24,6 +27,8 @@
   return redirect_info;
 }
 
+constexpr static int kDefaultBufferSize = 64 * 1024;
+
 }  // namespace
 
 class WebPackageLoader::ResponseTimingInfo {
@@ -135,12 +140,9 @@
 
 void WebPackageLoader::OnStartLoadingResponseBody(
     mojo::ScopedDataPipeConsumerHandle body) {
-  signed_exchange_handler_ =
-      base::MakeUnique<SignedExchangeHandler>(std::move(body));
-  signed_exchange_handler_->GetHTTPExchange(
+  signed_exchange_handler_ = std::make_unique<SignedExchangeHandler>(
+      base::MakeUnique<DataPipeToSourceStream>(std::move(body)),
       base::BindOnce(&WebPackageLoader::OnHTTPExchangeFound,
-                     weak_factory_.GetWeakPtr()),
-      base::BindOnce(&WebPackageLoader::OnHTTPExchangeFinished,
                      weak_factory_.GetWeakPtr()));
 }
 
@@ -158,12 +160,11 @@
   // TODO(https://crbug.com/791049): Remove this when NetworkService is
   // enabled by default.
   DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
-  DCHECK(pending_body_.is_valid());
-  DCHECK(client_);
-  client_->OnStartLoadingResponseBody(std::move(pending_body_));
-  if (pending_completion_status_) {
-    client_->OnComplete(*pending_completion_status_);
-  }
+  DCHECK(body_data_pipe_adapter_);
+  DCHECK(pending_body_consumer_.is_valid());
+
+  body_data_pipe_adapter_->Start();
+  client_->OnStartLoadingResponseBody(std::move(pending_body_consumer_));
 }
 
 void WebPackageLoader::SetPriority(net::RequestPriority priority,
@@ -190,8 +191,7 @@
     const GURL& request_url,
     const std::string& request_method,
     const network::ResourceResponseHead& resource_response,
-    base::Optional<net::SSLInfo> ssl_info,
-    mojo::ScopedDataPipeConsumerHandle body) {
+    base::Optional<net::SSLInfo> ssl_info) {
   // TODO(https://crbug.com/803774): Handle no-GET request_method as a error.
   DCHECK(original_response_timing_info_);
   forwarding_client_->OnReceiveRedirect(
@@ -203,24 +203,31 @@
   client_->OnReceiveResponse(resource_response, std::move(ssl_info),
                              nullptr /* downloaded_file */);
 
+  // Currently we always assume that we have body.
+  // TODO(https://crbug.com/80374): Add error handling and bail out
+  // earlier if there's an error.
+
+  mojo::DataPipe data_pipe(kDefaultBufferSize);
+  pending_body_consumer_ = std::move(data_pipe.consumer_handle);
+
+  body_data_pipe_adapter_ = std::make_unique<SourceStreamToDataPipe>(
+      signed_exchange_handler_.get(), std::move(data_pipe.producer_handle),
+      base::BindOnce(&WebPackageLoader::FinishReadingBody,
+                     base::Unretained(this)));
+
   if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
     // Need to wait until ProceedWithResponse() is called.
-    pending_body_ = std::move(body);
-  } else {
-    client_->OnStartLoadingResponseBody(std::move(body));
+    return;
   }
+
+  // Start reading.
+  body_data_pipe_adapter_->Start();
+  client_->OnStartLoadingResponseBody(std::move(pending_body_consumer_));
 }
 
-void WebPackageLoader::OnHTTPExchangeFinished(
-    const network::URLLoaderCompletionStatus& status) {
-  if (pending_body_.is_valid()) {
-    DCHECK(!base::FeatureList::IsEnabled(network::features::kNetworkService));
-    // If ProceedWithResponse() was not called yet, need to call OnComplete()
-    // after ProceedWithResponse() is called.
-    pending_completion_status_ = status;
-  } else {
-    client_->OnComplete(status);
-  }
+void WebPackageLoader::FinishReadingBody(int result) {
+  // This will eventually delete |this|.
+  client_->OnComplete(network::URLLoaderCompletionStatus(result));
 }
 
 }  // namespace content
diff --git a/content/browser/loader/web_package_loader.h b/content/browser/loader/web_package_loader.h
index 2ce2316..9cf9668 100644
--- a/content/browser/loader/web_package_loader.h
+++ b/content/browser/loader/web_package_loader.h
@@ -7,13 +7,16 @@
 
 #include "base/optional.h"
 #include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/system/simple_watcher.h"
 #include "net/ssl/ssl_info.h"
 #include "net/url_request/redirect_info.h"
+#include "services/network/public/cpp/net_adapters.h"
 #include "services/network/public/interfaces/url_loader.mojom.h"
 
 namespace content {
 
 class SignedExchangeHandler;
+class SourceStreamToDataPipe;
 
 // WebPackageLoader handles an origin-signed HTTP exchange response. It is
 // created when a WebPackageRequestHandler recieves an origin-signed HTTP
@@ -66,12 +69,9 @@
       const GURL& request_url,
       const std::string& request_method,
       const network::ResourceResponseHead& resource_response,
-      base::Optional<net::SSLInfo> ssl_info,
-      mojo::ScopedDataPipeConsumerHandle body);
+      base::Optional<net::SSLInfo> ssl_info);
 
-  // Called from |signed_exchange_handler_| when it finished sending the
-  // payload of the origin-signed HTTP response.
-  void OnHTTPExchangeFinished(const network::URLLoaderCompletionStatus& status);
+  void FinishReadingBody(int result);
 
   // This timing info is used to create a dummy redirect response.
   std::unique_ptr<const ResponseTimingInfo> original_response_timing_info_;
@@ -92,11 +92,10 @@
   network::mojom::URLLoaderClientRequest pending_client_request_;
 
   std::unique_ptr<SignedExchangeHandler> signed_exchange_handler_;
+  std::unique_ptr<SourceStreamToDataPipe> body_data_pipe_adapter_;
 
-  // This is used to keep the DataPipe until ProceedWithResponse() is called.
-  mojo::ScopedDataPipeConsumerHandle pending_body_;
-  // This is used to keep the status until ProceedWithResponse() is called.
-  base::Optional<network::URLLoaderCompletionStatus> pending_completion_status_;
+  // Kept around until ProceedWithResponse is called.
+  mojo::ScopedDataPipeConsumerHandle pending_body_consumer_;
 
   base::WeakPtrFactory<WebPackageLoader> weak_factory_;
 
diff --git a/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc b/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc
index d1b125c..5fb0c017 100644
--- a/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc
+++ b/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc
@@ -200,7 +200,6 @@
                                      FindFamilyCallback callback) {
   InitializeDirectWrite();
   TRACE_EVENT0("dwrite", "FontProxyHost::OnFindFamily");
-  DCHECK(collection_);
   UINT32 family_index = UINT32_MAX;
   if (collection_) {
     BOOL exists = FALSE;
@@ -218,8 +217,7 @@
 void DWriteFontProxyImpl::GetFamilyCount(GetFamilyCountCallback callback) {
   InitializeDirectWrite();
   TRACE_EVENT0("dwrite", "FontProxyHost::OnGetFamilyCount");
-  DCHECK(collection_);
-  std::move(callback).Run(collection_->GetFontFamilyCount());
+  std::move(callback).Run(collection_ ? collection_->GetFontFamilyCount() : 0);
 }
 
 void DWriteFontProxyImpl::GetFamilyNames(UINT32 family_index,
@@ -228,7 +226,6 @@
   TRACE_EVENT0("dwrite", "FontProxyHost::OnGetFamilyNames");
   callback = mojo::WrapCallbackWithDefaultInvokeIfNotRun(
       std::move(callback), std::vector<mojom::DWriteStringPairPtr>());
-  DCHECK(collection_);
   if (!collection_)
     return;
 
@@ -291,7 +288,6 @@
   callback = mojo::WrapCallbackWithDefaultInvokeIfNotRun(
       std::move(callback), std::vector<base::FilePath>(),
       std::vector<base::File>());
-  DCHECK(collection_);
   if (!collection_)
     return;
 
diff --git a/content/browser/service_worker/payment_handler_support.cc b/content/browser/service_worker/payment_handler_support.cc
new file mode 100644
index 0000000..ccf233f
--- /dev/null
+++ b/content/browser/service_worker/payment_handler_support.cc
@@ -0,0 +1,108 @@
+// 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 "content/browser/service_worker/payment_handler_support.h"
+
+#include "content/browser/service_worker/service_worker_context_core.h"
+#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/browser/storage_partition_impl.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/content_browser_client.h"
+#include "content/public/common/content_client.h"
+
+namespace content {
+
+namespace {
+
+// An instance of this class is created and passed ownership into
+// ContentBrowserClient::ShowPaymentHandlerWindow(), to handle these 2 different
+// scenarios:
+//   - If the embedder supports opening Payment Handler window,
+//   ContentBrowserClient::ShowPaymentHandlerWindow() returns true and tries to
+//   open the window, then finally invokes
+//   ShowPaymentHandlerWindowReplier::Run() to notify the result. In such a
+//   case, the response callback |response_callback| of Mojo call
+//   ServiceWorkerHost.OpenPaymentHandlerWindow() is bound into |callback| and
+//   invoked there.
+//   - Otherwise ContentBrowserClient::ShowPaymentHandlerWindow() just returns
+//   false and does nothing else, then |this| will be dropped silently without
+//   invoking Run(). In such a case, dtor of |this| invokes |fallback| (which
+//   e.g. opens a normal window), |response_callback| is bound into |fallback|
+//   and invoked there.
+class ShowPaymentHandlerWindowReplier {
+ public:
+  ShowPaymentHandlerWindowReplier(
+      PaymentHandlerSupport::ShowPaymentHandlerWindowCallback callback,
+      PaymentHandlerSupport::OpenWindowFallback fallback,
+      blink::mojom::ServiceWorkerHost::OpenPaymentHandlerWindowCallback
+          response_callback)
+      : callback_(std::move(callback)),
+        fallback_(std::move(fallback)),
+        response_callback_(std::move(response_callback)) {
+    DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  }
+
+  ~ShowPaymentHandlerWindowReplier() {
+    DCHECK_CURRENTLY_ON(BrowserThread::UI);
+    if (response_callback_) {
+      DCHECK(fallback_);
+      BrowserThread::PostTask(
+          BrowserThread::IO, FROM_HERE,
+          base::BindOnce(std::move(fallback_), std::move(response_callback_)));
+    }
+  }
+
+  void Run(bool success, int render_process_id, int render_frame_id) {
+    DCHECK_CURRENTLY_ON(BrowserThread::UI);
+    BrowserThread::PostTask(
+        BrowserThread::IO, FROM_HERE,
+        base::BindOnce(std::move(callback_), std::move(response_callback_),
+                       success, render_process_id, render_frame_id));
+  }
+
+ private:
+  PaymentHandlerSupport::ShowPaymentHandlerWindowCallback callback_;
+  PaymentHandlerSupport::OpenWindowFallback fallback_;
+  blink::mojom::ServiceWorkerHost::OpenPaymentHandlerWindowCallback
+      response_callback_;
+
+  DISALLOW_COPY_AND_ASSIGN(ShowPaymentHandlerWindowReplier);
+};
+
+void ShowPaymentHandlerWindowOnUI(
+    scoped_refptr<ServiceWorkerContextWrapper> context_wrapper,
+    const GURL& url,
+    PaymentHandlerSupport::ShowPaymentHandlerWindowCallback callback,
+    PaymentHandlerSupport::OpenWindowFallback fallback,
+    blink::mojom::ServiceWorkerHost::OpenPaymentHandlerWindowCallback
+        response_callback) {
+  GetContentClient()->browser()->ShowPaymentHandlerWindow(
+      context_wrapper->storage_partition()->browser_context(), url,
+      base::BindOnce(&ShowPaymentHandlerWindowReplier::Run,
+                     std::make_unique<ShowPaymentHandlerWindowReplier>(
+                         std::move(callback), std::move(fallback),
+                         std::move(response_callback))));
+}
+
+}  // namespace
+
+// static
+void PaymentHandlerSupport::ShowPaymentHandlerWindow(
+    const GURL& url,
+    ServiceWorkerContextCore* context,
+    ShowPaymentHandlerWindowCallback callback,
+    OpenWindowFallback fallback,
+    blink::mojom::ServiceWorkerHost::OpenPaymentHandlerWindowCallback
+        response_callback) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+  DCHECK(context);
+  BrowserThread::PostTask(
+      BrowserThread::UI, FROM_HERE,
+      base::BindOnce(&ShowPaymentHandlerWindowOnUI,
+                     base::WrapRefCounted(context->wrapper()), url,
+                     std::move(callback), std::move(fallback),
+                     std::move(response_callback)));
+}
+
+}  // namespace content
diff --git a/content/browser/service_worker/payment_handler_support.h b/content/browser/service_worker/payment_handler_support.h
new file mode 100644
index 0000000..7c6cff63
--- /dev/null
+++ b/content/browser/service_worker/payment_handler_support.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 CONTENT_BROWSER_SERVICE_WORKER_PAYMENT_HANDLER_SUPPORT_H_
+#define CONTENT_BROWSER_SERVICE_WORKER_PAYMENT_HANDLER_SUPPORT_H_
+
+#include "base/callback.h"
+#include "third_party/WebKit/common/service_worker/service_worker.mojom.h"
+
+class GURL;
+
+namespace content {
+
+class ServiceWorkerContextCore;
+
+// Support for Payment Handler <https://w3c.github.io/payment-handler/>.
+class PaymentHandlerSupport {
+ public:
+  using OpenWindowFallback = base::OnceCallback<void(
+      blink::mojom::ServiceWorkerHost::
+          OpenPaymentHandlerWindowCallback /* response_callback */)>;
+  using ShowPaymentHandlerWindowCallback = base::OnceCallback<void(
+      blink::mojom::ServiceWorkerHost::
+          OpenPaymentHandlerWindowCallback /* response_callback */,
+      bool /* success */,
+      int /* render_process_id */,
+      int /* render_frame_id */)>;
+
+  // Tries to open a Payment Handler window. The //content embedder may or may
+  // not support this operation. If the embedder supports it, |callback| is
+  // called with |response_callback| passed to it. Otherwise, |fallback| is
+  // called with |response_callback| passed to it. A typical fallback is to open
+  // a normal window.
+  static void ShowPaymentHandlerWindow(
+      const GURL& url,
+      ServiceWorkerContextCore* context,
+      ShowPaymentHandlerWindowCallback callback,
+      OpenWindowFallback fallback,
+      blink::mojom::ServiceWorkerHost::OpenPaymentHandlerWindowCallback
+          response_callback);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_SERVICE_WORKER_PAYMENT_HANDLER_SUPPORT_H_
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
index 163766a0..2e2aed83 100644
--- a/content/browser/service_worker/service_worker_version.cc
+++ b/content/browser/service_worker/service_worker_version.cc
@@ -25,13 +25,13 @@
 #include "content/browser/bad_message.h"
 #include "content/browser/child_process_security_policy_impl.h"
 #include "content/browser/service_worker/embedded_worker_registry.h"
+#include "content/browser/service_worker/payment_handler_support.h"
 #include "content/browser/service_worker/service_worker_client_utils.h"
 #include "content/browser/service_worker/service_worker_context_core.h"
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
 #include "content/browser/service_worker/service_worker_installed_scripts_sender.h"
 #include "content/browser/service_worker/service_worker_registration.h"
 #include "content/browser/service_worker/service_worker_type_converters.h"
-#include "content/browser/storage_partition_impl.h"
 #include "content/common/origin_trials/trial_policy_impl.h"
 #include "content/common/service_worker/embedded_worker.mojom.h"
 #include "content/common/service_worker/embedded_worker_messages.h"
@@ -197,57 +197,39 @@
   return info;
 }
 
-void DidNavigateInPaymentHandlerWindow(
+void OnOpenWindowFinished(
+    blink::mojom::ServiceWorkerHost::OpenNewTabCallback callback,
+    ServiceWorkerStatusCode status,
+    blink::mojom::ServiceWorkerClientInfoPtr client_info) {
+  DCHECK_CURRENTLY_ON(BrowserThread::IO);
+
+  if (status != SERVICE_WORKER_OK) {
+    std::move(callback).Run(
+        nullptr /* client */,
+        std::string("Something went wrong while trying to open the window."));
+    return;
+  }
+
+  DCHECK(client_info);
+  std::move(callback).Run(std::move(client_info),
+                          base::nullopt /* error_msg */);
+}
+
+void DidShowPaymentHandlerWindow(
     const GURL& url,
     const base::WeakPtr<ServiceWorkerContextCore>& context,
-    service_worker_client_utils::NavigationCallback callback,
+    blink::mojom::ServiceWorkerHost::OpenPaymentHandlerWindowCallback callback,
     bool success,
     int render_process_id,
     int render_frame_id) {
   if (success) {
     service_worker_client_utils::DidNavigate(
-        context, url.GetOrigin(), std::move(callback), render_process_id,
-        render_frame_id);
+        context, url.GetOrigin(),
+        base::BindOnce(&OnOpenWindowFinished, std::move(callback)),
+        render_process_id, render_frame_id);
   } else {
-    std::move(callback).Run(SERVICE_WORKER_ERROR_FAILED,
-                            blink::mojom::ServiceWorkerClientInfo::New());
-  }
-}
-
-using PaymentHandlerOpenWindowCallback =
-    base::OnceCallback<void(bool, int, int)>;
-
-void RunPaymentHandlerOpenWindowCallbackOnIO(
-    PaymentHandlerOpenWindowCallback callback,
-    bool success,
-    int render_process_id,
-    int render_frame_id) {
-  std::move(callback).Run(success, render_process_id, render_frame_id);
-}
-
-void OnOpenPaymentHandlerWindowOpenResponse(
-    PaymentHandlerOpenWindowCallback callback,
-    bool success,
-    int render_process_id,
-    int render_frame_id) {
-  BrowserThread::PostTask(
-      BrowserThread::IO, FROM_HERE,
-      base::BindOnce(&RunPaymentHandlerOpenWindowCallbackOnIO,
-                     std::move(callback), success, render_process_id,
-                     render_frame_id));
-}
-
-void ShowPaymentHandlerWindowOnUI(
-    ContentBrowserClient* browser,
-    const scoped_refptr<ServiceWorkerContextWrapper>& context_wrapper,
-    const GURL& url,
-    PaymentHandlerOpenWindowCallback callback,
-    base::OnceCallback<void(void)> fallback) {
-  if (!browser->ShowPaymentHandlerWindow(
-          context_wrapper->storage_partition()->browser_context(), url,
-          base::BindOnce(&OnOpenPaymentHandlerWindowOpenResponse,
-                         std::move(callback)))) {
-    BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, std::move(fallback));
+    OnOpenWindowFinished(std::move(callback), SERVICE_WORKER_ERROR_FAILED,
+                         blink::mojom::ServiceWorkerClientInfo::New());
   }
 }
 
@@ -1056,9 +1038,6 @@
 bool ServiceWorkerVersion::OnMessageReceived(const IPC::Message& message) {
   bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(ServiceWorkerVersion, message)
-    IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_OpenNewTab, OnOpenNewTab)
-    IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_OpenPaymentHandlerWindow,
-                        OnOpenPaymentHandlerWindow)
     IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToClient,
                         OnPostMessageToClient)
     IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_FocusClient,
@@ -1154,6 +1133,32 @@
   service_worker_client_utils::GetClient(provider_host, std::move(callback));
 }
 
+void ServiceWorkerVersion::OpenNewTab(const GURL& url,
+                                      OpenNewTabCallback callback) {
+  OpenWindow(url, WindowOpenDisposition::NEW_FOREGROUND_TAB,
+             std::move(callback));
+}
+
+void ServiceWorkerVersion::OpenPaymentHandlerWindow(
+    const GURL& url,
+    OpenPaymentHandlerWindowCallback callback) {
+  // Just respond failure if we are shutting down.
+  if (!context_) {
+    std::move(callback).Run(
+        nullptr /* client */,
+        std::string("The service worker system is shutting down."));
+    return;
+  }
+
+  PaymentHandlerSupport::ShowPaymentHandlerWindow(
+      url, context_.get(),
+      base::BindOnce(&DidShowPaymentHandlerWindow, url, context_),
+      base::BindOnce(&ServiceWorkerVersion::OpenWindow,
+                     weak_factory_.GetWeakPtr(), url,
+                     WindowOpenDisposition::NEW_POPUP),
+      std::move(callback));
+}
+
 void ServiceWorkerVersion::SkipWaiting(SkipWaitingCallback callback) {
   skip_waiting_ = true;
 
@@ -1209,6 +1214,45 @@
     listener.OnCachedMetadataUpdated(this, 0);
 }
 
+void ServiceWorkerVersion::OpenWindow(GURL url,
+                                      WindowOpenDisposition disposition,
+                                      OpenNewTabCallback callback) {
+  // Just respond failure if we are shutting down.
+  if (!context_) {
+    std::move(callback).Run(
+        nullptr /* client */,
+        std::string("The service worker system is shutting down."));
+    return;
+  }
+
+  if (!url.is_valid()) {
+    mojo::ReportBadMessage(
+        "Received unexpected invalid URL from renderer process.");
+    binding_.Close();
+    return;
+  }
+
+  // The renderer treats all URLs in the about: scheme as being about:blank.
+  // Canonicalize about: URLs to about:blank.
+  if (url.SchemeIs(url::kAboutScheme))
+    url = GURL(url::kAboutBlankURL);
+
+  // Reject requests for URLs that the process is not allowed to access. It's
+  // possible to receive such requests since the renderer-side checks are
+  // slightly different. For example, the view-source scheme will not be
+  // filtered out by Blink.
+  if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanRequestURL(
+          embedded_worker_->process_id(), url)) {
+    std::move(callback).Run(nullptr /* client */,
+                            url.spec() + " cannot be opened.");
+    return;
+  }
+
+  service_worker_client_utils::OpenWindow(
+      url, script_url_, embedded_worker_->process_id(), context_, disposition,
+      base::BindOnce(&OnOpenWindowFinished, std::move(callback)));
+}
+
 void ServiceWorkerVersion::OnSimpleEventFinished(
     int request_id,
     blink::mojom::ServiceWorkerEventStatus status,
@@ -1249,83 +1293,6 @@
   return false;
 }
 
-void ServiceWorkerVersion::OnOpenNewTab(int request_id, const GURL& url) {
-  OnOpenWindow(request_id, url, WindowOpenDisposition::NEW_FOREGROUND_TAB);
-}
-
-void ServiceWorkerVersion::OnOpenPaymentHandlerWindow(int request_id,
-                                                      const GURL& url) {
-  BrowserThread::PostTask(
-      BrowserThread::UI, FROM_HERE,
-      base::BindOnce(
-          &ShowPaymentHandlerWindowOnUI, GetContentClient()->browser(),
-          base::WrapRefCounted(context_->wrapper()), url,
-          base::BindOnce(
-              &DidNavigateInPaymentHandlerWindow, url, context_,
-              base::BindOnce(&ServiceWorkerVersion::OnOpenWindowFinished,
-                             weak_factory_.GetWeakPtr(), request_id)),
-          base::BindOnce(&ServiceWorkerVersion::OnOpenWindow,
-                         weak_factory_.GetWeakPtr(), request_id, url,
-                         WindowOpenDisposition::NEW_POPUP)));
-}
-
-void ServiceWorkerVersion::OnOpenWindow(int request_id,
-                                        GURL url,
-                                        WindowOpenDisposition disposition) {
-  // Just abort if we are shutting down.
-  if (!context_)
-    return;
-
-  if (!url.is_valid()) {
-    DVLOG(1) << "Received unexpected invalid URL from renderer process.";
-    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
-                            base::BindOnce(&KillEmbeddedWorkerProcess,
-                                           embedded_worker_->process_id()));
-    return;
-  }
-
-  // The renderer treats all URLs in the about: scheme as being about:blank.
-  // Canonicalize about: URLs to about:blank.
-  if (url.SchemeIs(url::kAboutScheme))
-    url = GURL(url::kAboutBlankURL);
-
-  // Reject requests for URLs that the process is not allowed to access. It's
-  // possible to receive such requests since the renderer-side checks are
-  // slightly different. For example, the view-source scheme will not be
-  // filtered out by Blink.
-  if (!ChildProcessSecurityPolicyImpl::GetInstance()->CanRequestURL(
-          embedded_worker_->process_id(), url)) {
-    embedded_worker_->SendIpcMessage(ServiceWorkerMsg_OpenWindowError(
-        request_id, url.spec() + " cannot be opened."));
-    return;
-  }
-
-  service_worker_client_utils::OpenWindow(
-      url, script_url_, embedded_worker_->process_id(), context_, disposition,
-      base::BindOnce(&ServiceWorkerVersion::OnOpenWindowFinished,
-                     weak_factory_.GetWeakPtr(), request_id));
-}
-
-void ServiceWorkerVersion::OnOpenWindowFinished(
-    int request_id,
-    ServiceWorkerStatusCode status,
-    blink::mojom::ServiceWorkerClientInfoPtr client_info) {
-  DCHECK_CURRENTLY_ON(BrowserThread::IO);
-
-  if (running_status() != EmbeddedWorkerStatus::RUNNING)
-    return;
-
-  if (status != SERVICE_WORKER_OK) {
-    embedded_worker_->SendIpcMessage(ServiceWorkerMsg_OpenWindowError(
-        request_id, "Something went wrong while trying to open the window."));
-    return;
-  }
-
-  DCHECK(client_info);
-  embedded_worker_->SendIpcMessage(
-      ServiceWorkerMsg_OpenWindowResponse(request_id, *client_info));
-}
-
 void ServiceWorkerVersion::OnPostMessageToClient(
     const std::string& client_uuid,
     const base::string16& message,
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h
index 597a9446..f72e9048 100644
--- a/content/browser/service_worker/service_worker_version.h
+++ b/content/browser/service_worker/service_worker_version.h
@@ -632,29 +632,22 @@
                   GetClientsCallback callback) override;
   void GetClient(const std::string& client_uuid,
                  GetClientCallback callback) override;
+  void OpenNewTab(const GURL& url, OpenNewTabCallback callback) override;
+  void OpenPaymentHandlerWindow(
+      const GURL& url,
+      OpenPaymentHandlerWindowCallback callback) override;
   void SkipWaiting(SkipWaitingCallback callback) override;
 
   void OnSetCachedMetadataFinished(int64_t callback_id,
                                    size_t size,
                                    int result);
   void OnClearCachedMetadataFinished(int64_t callback_id, int result);
+  void OpenWindow(GURL url,
+                  WindowOpenDisposition disposition,
+                  OpenNewTabCallback callback);
 
   // Message handlers.
 
-  // Currently used for Clients.openWindow() only.
-  void OnOpenNewTab(int request_id, const GURL& url);
-
-  // Currently used for PaymentRequestEvent.openWindow() only.
-  void OnOpenPaymentHandlerWindow(int request_id, const GURL& url);
-
-  void OnOpenWindow(int request_id,
-                    GURL url,
-                    WindowOpenDisposition disposition);
-  void OnOpenWindowFinished(
-      int request_id,
-      ServiceWorkerStatusCode status,
-      blink::mojom::ServiceWorkerClientInfoPtr client_info);
-
   void OnPostMessageToClient(
       const std::string& client_uuid,
       const base::string16& message,
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index bf5e018..3ab898c 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -177,7 +177,10 @@
 
     if (infos[i].last_modified >= delete_begin &&
         infos[i].last_modified <= delete_end) {
-      dom_storage_context->DeleteLocalStorage(infos[i].origin);
+      // TODO(dullweber): |callback| should be passed to DeleteLocalStorage()
+      // but then ASAN complains about a few tests that need to be fixed.
+      dom_storage_context->DeleteLocalStorage(infos[i].origin,
+                                              base::BindOnce(&base::DoNothing));
     }
   }
   callback.Run();
@@ -216,9 +219,13 @@
     bool can_delete = origin_matcher.is_null() ||
                       origin_matcher.Run(storage_origin,
                                          special_storage_policy.get());
-    if (can_delete)
-      dom_storage_context->DeleteLocalStorageForPhysicalOrigin(storage_origin);
-
+    if (can_delete) {
+      // TODO(dullweber): |callback| should be passed to
+      // DeleteLocalStorageForPhysicalOrigin() but then ASAN complains about a
+      // few tests that need to be fixed.
+      dom_storage_context->DeleteLocalStorageForPhysicalOrigin(
+          storage_origin, base::BindOnce(&base::DoNothing));
+    }
     callback.Run();
     return;
   }
diff --git a/content/browser/top_document_isolation_browsertest.cc b/content/browser/top_document_isolation_browsertest.cc
index cedc2f9..de9288e4 100644
--- a/content/browser/top_document_isolation_browsertest.cc
+++ b/content/browser/top_document_isolation_browsertest.cc
@@ -596,20 +596,20 @@
       DepictFrameTree(root()));
 
   // The popup redirects itself to the advertiser's website (ad.com).
+  RenderFrameDeletedObserver deleted_observer(popup_root->current_frame_host());
   RendererInitiatedNavigateToURL(popup_root, ad_url);
+  deleted_observer.WaitUntilDeleted();
 
   // This must join its same-site opener, in the default subframe SiteInstance.
   EXPECT_EQ(
-      " Site A ------------ proxies for B C\n"
-      "   +--Site B ------- proxies for A C\n"
+      " Site A ------------ proxies for B\n"
+      "   +--Site B ------- proxies for A\n"
       "Where A = http://page.com/\n"
-      "      B = default subframe process\n"
-      "      C = http://adnetwork.com/",
+      "      B = default subframe process",
       DepictFrameTree(root()));
   EXPECT_EQ(
-      " Site C ------------ proxies for B\n"
-      "Where B = default subframe process\n"
-      "      C = http://adnetwork.com/",
+      " Site B\n"
+      "Where B = default subframe process",
       DepictFrameTree(popup_root));
 }
 
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 31e65f9e7..7bdf8df 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -3911,7 +3911,9 @@
 }
 
 void WebContentsImpl::PassiveInsecureContentFound(const GURL& resource_url) {
-  GetDelegate()->PassiveInsecureContentFound(resource_url);
+  if (delegate_) {
+    delegate_->PassiveInsecureContentFound(resource_url);
+  }
 }
 
 bool WebContentsImpl::ShouldAllowRunningInsecureContent(
@@ -3919,8 +3921,12 @@
     bool allowed_per_prefs,
     const url::Origin& origin,
     const GURL& resource_url) {
-  return GetDelegate()->ShouldAllowRunningInsecureContent(
-      web_contents, allowed_per_prefs, origin, resource_url);
+  if (delegate_) {
+    return delegate_->ShouldAllowRunningInsecureContent(
+        web_contents, allowed_per_prefs, origin, resource_url);
+  }
+
+  return allowed_per_prefs;
 }
 
 void WebContentsImpl::ViewSource(RenderFrameHostImpl* frame) {
diff --git a/content/child/font_warmup_win.cc b/content/child/font_warmup_win.cc
index 99d0139..19350e96 100644
--- a/content/child/font_warmup_win.cc
+++ b/content/child/font_warmup_win.cc
@@ -22,12 +22,17 @@
 #include "base/trace_event/trace_event.h"
 #include "base/win/iat_patch_function.h"
 #include "base/win/windows_version.h"
-#include "ppapi/shared_impl/proxy_lock.h"
+#include "build/build_config.h"
+#include "ppapi/features/features.h"
 #include "skia/ext/fontmgr_default_win.h"
 #include "third_party/skia/include/core/SkRefCnt.h"
 #include "third_party/skia/include/ports/SkFontMgr.h"
 #include "third_party/skia/include/ports/SkTypeface_win.h"
 
+#if BUILDFLAG(ENABLE_PLUGINS)
+#include "ppapi/shared_impl/proxy_lock.h"
+#endif  // BUILDFLAG(ENABLE_PLUGINS)
+
 namespace content {
 
 namespace {
@@ -205,7 +210,9 @@
                                        : SkFontStyle::kUpright_Slant);
 
   std::string family_name = base::WideToUTF8(log_font->lfFaceName);
+#if BUILDFLAG(ENABLE_PLUGINS)
   ppapi::ProxyAutoLock lock;  // Needed for DirectWrite font proxy.
+#endif                        // BUILDFLAG(ENABLE_PLUGINS)
   return sk_sp<SkTypeface>(
       g_warmup_fontmgr->matchFamilyStyle(family_name.c_str(), style));
 }
diff --git a/content/common/origin_util.cc b/content/common/origin_util.cc
index eec668f..66516d0f 100644
--- a/content/common/origin_util.cc
+++ b/content/common/origin_util.cc
@@ -59,13 +59,6 @@
   return false;
 }
 
-bool IsOriginWhiteListedTrustworthy(const url::Origin& origin) {
-  if (IsOriginUnique(origin))
-    return false;
-
-  return base::ContainsValue(GetSecureOrigins(), origin);
-}
-
 bool IsPotentiallyTrustworthyOrigin(const url::Origin& origin) {
   // Note: Considering this mirrors SecurityOrigin::isPotentiallyTrustworthy, it
   // assumes m_isUniqueOriginPotentiallyTrustworthy is set to false. This
@@ -81,7 +74,7 @@
     return true;
   }
 
-  if (IsOriginWhiteListedTrustworthy(origin))
+  if (base::ContainsValue(GetSecureOrigins(), origin))
     return true;
 
   return false;
diff --git a/content/common/service_worker/service_worker_messages.h b/content/common/service_worker/service_worker_messages.h
index 90b9b6a..e0b309993 100644
--- a/content/common/service_worker/service_worker_messages.h
+++ b/content/common/service_worker/service_worker_messages.h
@@ -122,16 +122,6 @@
     base::string16 /* message */,
     std::vector<blink::MessagePortChannel> /* sent_message_ports */)
 
-// Ask the browser to open a tab/window (renderer->browser).
-IPC_MESSAGE_ROUTED2(ServiceWorkerHostMsg_OpenNewTab,
-                    int /* request_id */,
-                    GURL /* url */)
-
-// Ask the browser to open a Payment Handler window (renderer->browser).
-IPC_MESSAGE_ROUTED2(ServiceWorkerHostMsg_OpenPaymentHandlerWindow,
-                    int /* request_id */,
-                    GURL /* url */)
-
 // Ask the browser to focus a client (renderer->browser).
 IPC_MESSAGE_ROUTED2(ServiceWorkerHostMsg_FocusClient,
                     int /* request_id */,
@@ -157,16 +147,6 @@
                      int /* handle_id */,
                      blink::mojom::ServiceWorkerState)
 
-// Sent via EmbeddedWorker as a response of OpenWindow.
-IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_OpenWindowResponse,
-                     int /* request_id */,
-                     blink::mojom::ServiceWorkerClientInfo /* client */)
-
-// Sent via EmbeddedWorker as an error response of OpenWindow.
-IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_OpenWindowError,
-                     int /* request_id */,
-                     std::string /* message */ )
-
 // Sent via EmbeddedWorker as a response of FocusClient.
 IPC_MESSAGE_CONTROL2(ServiceWorkerMsg_FocusClientResponse,
                      int /* request_id */,
diff --git a/content/common/url_schemes.cc b/content/common/url_schemes.cc
index c5c80e7..c951b55 100644
--- a/content/common/url_schemes.cc
+++ b/content/common/url_schemes.cc
@@ -11,6 +11,7 @@
 #include "base/strings/string_util.h"
 #include "content/public/common/content_client.h"
 #include "content/public/common/url_constants.h"
+#include "services/network/public/cpp/cors/cors_legacy.h"
 #include "url/url_util.h"
 
 namespace content {
@@ -100,6 +101,7 @@
   delete secure_origins;
   secure_origins = new std::vector<url::Origin>;
   *secure_origins = std::move(schemes.secure_origins);
+  network::cors::legacy::RegisterSecureOrigins(*secure_origins);
 }
 
 const std::vector<std::string>& GetSavableSchemes() {
diff --git a/content/network/BUILD.gn b/content/network/BUILD.gn
index 485e9e8..0b07708 100644
--- a/content/network/BUILD.gn
+++ b/content/network/BUILD.gn
@@ -30,8 +30,6 @@
   ]
 
   sources = [
-    "cors/cors_url_loader.cc",
-    "cors/cors_url_loader.h",
     "cors/cors_url_loader_factory.cc",
     "cors/cors_url_loader_factory.h",
     "resource_scheduler.cc",
diff --git a/content/network/DEPS b/content/network/DEPS
index 78570aa..c8c867d 100644
--- a/content/network/DEPS
+++ b/content/network/DEPS
@@ -3,10 +3,8 @@
   "-content",
   "+content/common/content_export.h",
   "+content/network",
-  "+content/public/common/origin_util.h",
   "+content/public/common/request_context_type.h",
   "+content/public/common/resource_type.h",
-  "+content/public/common/service_worker_modes.h",
   "+services/network",
   "+services/service_manager/public",
 ]
diff --git a/content/network/cors/cors_url_loader_factory.cc b/content/network/cors/cors_url_loader_factory.cc
index 2fefc68..3f08e7e 100644
--- a/content/network/cors/cors_url_loader_factory.cc
+++ b/content/network/cors/cors_url_loader_factory.cc
@@ -4,7 +4,7 @@
 
 #include "content/network/cors/cors_url_loader_factory.h"
 
-#include "content/network/cors/cors_url_loader.h"
+#include "services/network/public/cpp/cors/cors_url_loader.h"
 #include "services/network/public/cpp/features.h"
 
 namespace content {
@@ -25,10 +25,10 @@
     const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
   if (base::FeatureList::IsEnabled(network::features::kOutOfBlinkCORS)) {
     loader_bindings_.AddBinding(
-        std::make_unique<CORSURLLoader>(routing_id, request_id, options,
-                                        resource_request, std::move(client),
-                                        traffic_annotation,
-                                        network_loader_factory_.get()),
+        std::make_unique<network::CORSURLLoader>(
+            routing_id, request_id, options, resource_request,
+            std::move(client), traffic_annotation,
+            network_loader_factory_.get()),
         std::move(request));
   } else {
     network_loader_factory_->CreateLoaderAndStart(
diff --git a/content/network/cors/cors_url_loader_unittest.cc b/content/network/cors/cors_url_loader_unittest.cc
index 42b4eaa5..829e92b 100644
--- a/content/network/cors/cors_url_loader_unittest.cc
+++ b/content/network/cors/cors_url_loader_unittest.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 "content/network/cors/cors_url_loader.h"
+#include "services/network/public/cpp/cors/cors_url_loader.h"
 
 #include "base/logging.h"
 #include "base/macros.h"
diff --git a/content/public/browser/browser_thread.h b/content/public/browser/browser_thread.h
index e9ff7d54..a4bdf19 100644
--- a/content/public/browser/browser_thread.h
+++ b/content/public/browser/browser_thread.h
@@ -67,36 +67,11 @@
     // The main thread in the browser.
     UI,
 
-    // This is the thread that interacts with the database.
-    DB,
-
-    // This is the thread that interacts with the file system.
-    // DEPRECATED: prefer base/task_scheduler/post_task.h for new classes
-    // requiring a background file I/O task runner, i.e.:
-    //   base::CreateSequencedTaskRunnerWithTraits(
-    //       {base::MayBlock(), base::TaskPriority::BACKGROUND})
-    //   Note: You can use base::TaskPriority::USER_VISIBLE instead of
-    //         base::TaskPriority::BACKGROUND if the latency of this operation
-    //         is visible but non-blocking to the user.
-    FILE,
-
-    // Used for file system operations that block user interactions.
-    // Responsiveness of this thread affect users.
-    // DEPRECATED: prefer base/task_scheduler/post_task.h for new classes
-    // requiring a user-blocking file I/O task runner, i.e.:
-    //   base::CreateSequencedTaskRunnerWithTraits(
-    //       {base::MayBlock(), base::TaskPriority::USER_BLOCKING})
-    FILE_USER_BLOCKING,
-
     // Used to launch and terminate Chrome processes.
     PROCESS_LAUNCHER,
 
-    // This is the thread to handle slow HTTP cache operations.
-    CACHE,
-
     // This is the thread that processes non-blocking IO, i.e. IPC and network.
-    // Blocking IO should happen on other threads like DB, FILE,
-    // FILE_USER_BLOCKING and CACHE depending on the usage.
+    // Blocking IO should happen in TaskScheduler.
     IO,
 
     // NOTE: do not add new threads here that are only used by a small number of
diff --git a/content/public/browser/dom_storage_context.h b/content/public/browser/dom_storage_context.h
index 61b285671..5954335b 100644
--- a/content/public/browser/dom_storage_context.h
+++ b/content/public/browser/dom_storage_context.h
@@ -40,13 +40,20 @@
       const GetSessionStorageUsageCallback& callback) = 0;
 
   // Deletes the local storage data for the physical origin of |origin_url|,
-  // including all suborigins at the physical origin.
+  // including all suborigins at the physical origin. |callback| is called when
+  // the deletion is sent to the database and GetLocalStorageUsage() will not
+  // return entries for |origin_url| anymore.
   //
   // See https://w3c.github.io/webappsec-suborigins/.
-  virtual void DeleteLocalStorageForPhysicalOrigin(const GURL& origin_url) = 0;
+  virtual void DeleteLocalStorageForPhysicalOrigin(
+      const GURL& origin_url,
+      base::OnceClosure callback) = 0;
 
-  // Deletes the local storage for the origin of |origin_url|.
-  virtual void DeleteLocalStorage(const GURL& origin_url) = 0;
+  // Deletes the local storage for the origin of |origin_url|. |callback| is
+  // called when the deletion is sent to the database and GetLocalStorageUsage()
+  // will not return entries for |origin_url| anymore.
+  virtual void DeleteLocalStorage(const GURL& origin_url,
+                                  base::OnceClosure callback) = 0;
 
   // Deletes the session storage data identified by |usage_info|.
   virtual void DeleteSessionStorage(
diff --git a/content/public/browser/session_storage_usage_info.h b/content/public/browser/session_storage_usage_info.h
index 2faf952..b1238ba3 100644
--- a/content/public/browser/session_storage_usage_info.h
+++ b/content/public/browser/session_storage_usage_info.h
@@ -5,6 +5,9 @@
 #ifndef CONTENT_PUBLIC_BROWSER_SESSION_STORAGE_USAGE_INFO_H_
 #define CONTENT_PUBLIC_BROWSER_SESSION_STORAGE_USAGE_INFO_H_
 
+#include "content/common/content_export.h"
+#include "url/gurl.h"
+
 namespace content {
 
 // Used to report Session Storage usage info by DOMStorageContext.
diff --git a/content/public/common/origin_util.h b/content/public/common/origin_util.h
index faaadafc..b352f37c 100644
--- a/content/public/common/origin_util.h
+++ b/content/public/common/origin_util.h
@@ -23,11 +23,6 @@
 // http (localhost only), https, or a custom-set secure scheme.
 bool CONTENT_EXPORT OriginCanAccessServiceWorkers(const GURL& url);
 
-// Returns true if the origin is unique or was considered secure by the client.
-// This behaves as close as possible to
-// SecurityPolicy::isOriginWhiteListedTrustworthy.
-bool CONTENT_EXPORT IsOriginWhiteListedTrustworthy(const url::Origin& origin);
-
 // This is based on SecurityOrigin::isPotentiallyTrustworthy and tries to mimic
 // its behavior.
 bool CONTENT_EXPORT IsPotentiallyTrustworthyOrigin(const url::Origin& origin);
diff --git a/content/public/test/test_browser_thread_bundle.cc b/content/public/test/test_browser_thread_bundle.cc
index d39888c..05b943db 100644
--- a/content/public/test/test_browser_thread_bundle.cc
+++ b/content/public/test/test_browser_thread_bundle.cc
@@ -39,16 +39,8 @@
   base::RunLoop().RunUntilIdle();
   io_thread_->Stop();
   base::RunLoop().RunUntilIdle();
-  cache_thread_->Stop();
-  base::RunLoop().RunUntilIdle();
   process_launcher_thread_->Stop();
   base::RunLoop().RunUntilIdle();
-  file_user_blocking_thread_->Stop();
-  base::RunLoop().RunUntilIdle();
-  file_thread_->Stop();
-  base::RunLoop().RunUntilIdle();
-  db_thread_->Stop();
-  base::RunLoop().RunUntilIdle();
   ui_thread_->Stop();
   base::RunLoop().RunUntilIdle();
 
@@ -124,16 +116,8 @@
 void TestBrowserThreadBundle::CreateBrowserThreads() {
   CHECK(!threads_created_);
 
-  db_thread_ = std::make_unique<TestBrowserThread>(
-      BrowserThread::DB, base::MessageLoop::current());
-  file_thread_ = std::make_unique<TestBrowserThread>(
-      BrowserThread::FILE, base::MessageLoop::current());
-  file_user_blocking_thread_ = std::make_unique<TestBrowserThread>(
-      BrowserThread::FILE_USER_BLOCKING, base::MessageLoop::current());
   process_launcher_thread_ = std::make_unique<TestBrowserThread>(
       BrowserThread::PROCESS_LAUNCHER, base::MessageLoop::current());
-  cache_thread_ = std::make_unique<TestBrowserThread>(
-      BrowserThread::CACHE, base::MessageLoop::current());
 
   if (options_ & REAL_IO_THREAD) {
     io_thread_ = std::make_unique<TestBrowserThread>(BrowserThread::IO);
diff --git a/content/public/test/test_browser_thread_bundle.h b/content/public/test/test_browser_thread_bundle.h
index de319651..afc45cb 100644
--- a/content/public/test/test_browser_thread_bundle.h
+++ b/content/public/test/test_browser_thread_bundle.h
@@ -130,11 +130,7 @@
 
   std::unique_ptr<base::test::ScopedTaskEnvironment> scoped_task_environment_;
   std::unique_ptr<TestBrowserThread> ui_thread_;
-  std::unique_ptr<TestBrowserThread> db_thread_;
-  std::unique_ptr<TestBrowserThread> file_thread_;
-  std::unique_ptr<TestBrowserThread> file_user_blocking_thread_;
   std::unique_ptr<TestBrowserThread> process_launcher_thread_;
-  std::unique_ptr<TestBrowserThread> cache_thread_;
   std::unique_ptr<TestBrowserThread> io_thread_;
 
   int options_;
diff --git a/content/renderer/media/rtc_peer_connection_handler.cc b/content/renderer/media/rtc_peer_connection_handler.cc
index b93ad622..edc3a68 100644
--- a/content/renderer/media/rtc_peer_connection_handler.cc
+++ b/content/renderer/media/rtc_peer_connection_handler.cc
@@ -1798,7 +1798,12 @@
       break;
     }
   }
-  DCHECK(webrtc_stream.get());
+  // If the stream was added using addTrack() we might not find it here. When
+  // addStream() and removeStream() is implemented on top of addTrack() and
+  // removeTrack() this won't be a problem and this code will go away.
+  // https://crbug.com/738929
+  if (!webrtc_stream)
+    return;
   // TODO(tommi): Make this async (PostTaskAndReply).
   native_peer_connection_->RemoveStream(webrtc_stream.get());
 
diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc
index 1c2376a..0b3f80c 100644
--- a/content/renderer/service_worker/service_worker_context_client.cc
+++ b/content/renderer/service_worker/service_worker_context_client.cc
@@ -471,6 +471,27 @@
   callbacks->OnSuccess();
 }
 
+void DidOpenWindow(
+    std::unique_ptr<blink::WebServiceWorkerClientCallbacks> callbacks,
+    blink::mojom::ServiceWorkerClientInfoPtr client,
+    const base::Optional<std::string>& error_msg) {
+  if (error_msg) {
+    DCHECK(!client);
+    callbacks->OnError(blink::WebServiceWorkerError(
+        blink::mojom::ServiceWorkerErrorType::kNavigation,
+        blink::WebString::FromUTF8(*error_msg)));
+    return;
+  }
+
+  DCHECK(client);
+  std::unique_ptr<blink::WebServiceWorkerClientInfo> web_client;
+  if (!client->client_uuid.empty()) {
+    web_client = std::make_unique<blink::WebServiceWorkerClientInfo>(
+        ToWebServiceWorkerClientInfo(std::move(client)));
+  }
+  callbacks->OnSuccess(std::move(web_client));
+}
+
 }  // namespace
 
 // Holding data that needs to be bound to the worker context on the
@@ -773,10 +794,6 @@
   CHECK_EQ(embedded_worker_id_, embedded_worker_id);
   bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(ServiceWorkerContextClient, message)
-    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_OpenWindowResponse,
-                        OnOpenWindowResponse)
-    IPC_MESSAGE_HANDLER(ServiceWorkerMsg_OpenWindowError,
-                        OnOpenWindowError)
     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_FocusClientResponse,
                         OnFocusClientResponse)
     IPC_MESSAGE_HANDLER(ServiceWorkerMsg_NavigateClientResponse,
@@ -813,17 +830,19 @@
     const blink::WebURL& url,
     std::unique_ptr<blink::WebServiceWorkerClientCallbacks> callbacks) {
   DCHECK(callbacks);
-  int request_id = context_->client_callbacks.Add(std::move(callbacks));
-  Send(new ServiceWorkerHostMsg_OpenNewTab(GetRoutingID(), request_id, url));
+  (*context_->service_worker_host)
+      ->OpenNewTab(url, WrapCallbackThreadSafe(base::BindOnce(
+                            &DidOpenWindow, std::move(callbacks))));
 }
 
 void ServiceWorkerContextClient::OpenPaymentHandlerWindow(
     const blink::WebURL& url,
     std::unique_ptr<blink::WebServiceWorkerClientCallbacks> callbacks) {
   DCHECK(callbacks);
-  int request_id = context_->client_callbacks.Add(std::move(callbacks));
-  Send(new ServiceWorkerHostMsg_OpenPaymentHandlerWindow(GetRoutingID(),
-                                                         request_id, url));
+  (*context_->service_worker_host)
+      ->OpenPaymentHandlerWindow(
+          url, WrapCallbackThreadSafe(
+                   base::BindOnce(&DidOpenWindow, std::move(callbacks))));
 }
 
 void ServiceWorkerContextClient::SetCachedMetadata(const blink::WebURL& url,
@@ -902,8 +921,7 @@
   // Set ServiceWorkerGlobalScope#registration.
   // TakeRegistrationForServiceWorkerGlobalScope() expects the dispatcher to be
   // already created, so create it first.
-  ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
-      sender_.get(), main_thread_task_runner_.get());
+  ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(sender_.get());
   proxy_->SetRegistration(WebServiceWorkerRegistrationImpl::CreateHandle(
       provider_context_->TakeRegistrationForServiceWorkerGlobalScope(
           io_thread_task_runner_)));
@@ -1580,8 +1598,7 @@
          event->source_info_for_service_worker->version_id !=
              blink::mojom::kInvalidServiceWorkerVersionId);
   ServiceWorkerDispatcher* dispatcher =
-      ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
-          sender_.get(), main_thread_task_runner_.get());
+      ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(sender_.get());
   scoped_refptr<WebServiceWorkerImpl> worker =
       dispatcher->GetOrCreateServiceWorker(
           std::move(event->source_info_for_service_worker));
@@ -1709,43 +1726,6 @@
   proxy_->DispatchPushEvent(request_id, data);
 }
 
-void ServiceWorkerContextClient::OnOpenWindowResponse(
-    int request_id,
-    const blink::mojom::ServiceWorkerClientInfo& client) {
-  TRACE_EVENT0("ServiceWorker",
-               "ServiceWorkerContextClient::OnOpenWindowResponse");
-  blink::WebServiceWorkerClientCallbacks* callbacks =
-      context_->client_callbacks.Lookup(request_id);
-  if (!callbacks) {
-    NOTREACHED() << "Got stray response: " << request_id;
-    return;
-  }
-  std::unique_ptr<blink::WebServiceWorkerClientInfo> web_client;
-  if (!client.client_uuid.empty()) {
-    web_client.reset(new blink::WebServiceWorkerClientInfo(
-        ToWebServiceWorkerClientInfo(client)));
-  }
-  callbacks->OnSuccess(std::move(web_client));
-  context_->client_callbacks.Remove(request_id);
-}
-
-void ServiceWorkerContextClient::OnOpenWindowError(
-    int request_id,
-    const std::string& message) {
-  TRACE_EVENT0("ServiceWorker",
-               "ServiceWorkerContextClient::OnOpenWindowError");
-  blink::WebServiceWorkerClientCallbacks* callbacks =
-      context_->client_callbacks.Lookup(request_id);
-  if (!callbacks) {
-    NOTREACHED() << "Got stray response: " << request_id;
-    return;
-  }
-  callbacks->OnError(blink::WebServiceWorkerError(
-      blink::mojom::ServiceWorkerErrorType::kNavigation,
-      blink::WebString::FromUTF8(message)));
-  context_->client_callbacks.Remove(request_id);
-}
-
 void ServiceWorkerContextClient::OnFocusClientResponse(
     int request_id,
     const blink::mojom::ServiceWorkerClientInfo& client) {
diff --git a/content/renderer/service_worker/service_worker_context_client.h b/content/renderer/service_worker/service_worker_context_client.h
index e63f2c97..551aaf37 100644
--- a/content/renderer/service_worker/service_worker_context_client.h
+++ b/content/renderer/service_worker/service_worker_context_client.h
@@ -359,10 +359,6 @@
       const std::string& notification_id,
       const PlatformNotificationData& notification_data);
 
-  void OnOpenWindowResponse(
-      int request_id,
-      const blink::mojom::ServiceWorkerClientInfo& client);
-  void OnOpenWindowError(int request_id, const std::string& message);
   void OnFocusClientResponse(
       int request_id,
       const blink::mojom::ServiceWorkerClientInfo& client);
diff --git a/content/renderer/service_worker/service_worker_context_client_unittest.cc b/content/renderer/service_worker/service_worker_context_client_unittest.cc
index 0648188..93deefd5 100644
--- a/content/renderer/service_worker/service_worker_context_client_unittest.cc
+++ b/content/renderer/service_worker/service_worker_context_client_unittest.cc
@@ -218,8 +218,7 @@
 
   void TearDown() override {
     ServiceWorkerContextClient::ResetThreadSpecificInstanceForTesting();
-    ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
-        sender_, main_task_runner())
+    ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(sender_)
         ->AllowReinstantiationForTesting();
     // Unregister this thread from worker threads.
     WorkerThreadRegistry::Instance()->WillStopCurrentWorkerThread();
@@ -277,11 +276,6 @@
   }
 
  private:
-  scoped_refptr<base::SingleThreadTaskRunner> main_task_runner() {
-    // Use this thread as the main thread.
-    return task_runner_;
-  }
-
   scoped_refptr<base::SingleThreadTaskRunner> io_task_runner() {
     // Use this thread as the IO thread.
     return task_runner_;
diff --git a/content/renderer/service_worker/service_worker_dispatcher.cc b/content/renderer/service_worker/service_worker_dispatcher.cc
index d3457cf4..3e2be7f 100644
--- a/content/renderer/service_worker/service_worker_dispatcher.cc
+++ b/content/renderer/service_worker/service_worker_dispatcher.cc
@@ -10,7 +10,6 @@
 #include "base/lazy_instance.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted.h"
-#include "base/single_thread_task_runner.h"
 #include "base/stl_util.h"
 #include "base/threading/thread_local.h"
 #include "base/threading/thread_task_runner_handle.h"
@@ -43,10 +42,8 @@
 }  // namespace
 
 ServiceWorkerDispatcher::ServiceWorkerDispatcher(
-    scoped_refptr<ThreadSafeSender> thread_safe_sender,
-    scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner)
-    : thread_safe_sender_(std::move(thread_safe_sender)),
-      main_thread_task_runner_(std::move(main_thread_task_runner)) {
+    scoped_refptr<ThreadSafeSender> thread_safe_sender)
+    : thread_safe_sender_(std::move(thread_safe_sender)) {
   g_dispatcher_tls.Pointer()->Set(static_cast<void*>(this));
 }
 
@@ -74,8 +71,7 @@
 
 ServiceWorkerDispatcher*
 ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
-    scoped_refptr<ThreadSafeSender> thread_safe_sender,
-    scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner) {
+    scoped_refptr<ThreadSafeSender> thread_safe_sender) {
   if (g_dispatcher_tls.Pointer()->Get() ==
       kDeletedServiceWorkerDispatcherMarker) {
     NOTREACHED() << "Re-instantiating TLS ServiceWorkerDispatcher.";
@@ -85,8 +81,8 @@
     return static_cast<ServiceWorkerDispatcher*>(
         g_dispatcher_tls.Pointer()->Get());
 
-  ServiceWorkerDispatcher* dispatcher = new ServiceWorkerDispatcher(
-      std::move(thread_safe_sender), std::move(main_thread_task_runner));
+  ServiceWorkerDispatcher* dispatcher =
+      new ServiceWorkerDispatcher(std::move(thread_safe_sender));
   if (WorkerThread::GetCurrentId())
     WorkerThread::AddObserver(dispatcher);
   return dispatcher;
diff --git a/content/renderer/service_worker/service_worker_dispatcher.h b/content/renderer/service_worker/service_worker_dispatcher.h
index 7e17ab6..3e75298 100644
--- a/content/renderer/service_worker/service_worker_dispatcher.h
+++ b/content/renderer/service_worker/service_worker_dispatcher.h
@@ -27,10 +27,6 @@
 #include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerProvider.h"
 #include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerRegistration.h"
 
-namespace base {
-class SingleThreadTaskRunner;
-}
-
 namespace IPC {
 class Message;
 }
@@ -45,9 +41,8 @@
 // scripts through methods like navigator.registerServiceWorker().
 class CONTENT_EXPORT ServiceWorkerDispatcher : public WorkerThread::Observer {
  public:
-  ServiceWorkerDispatcher(
-      scoped_refptr<ThreadSafeSender> thread_safe_sender,
-      scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner);
+  explicit ServiceWorkerDispatcher(
+      scoped_refptr<ThreadSafeSender> thread_safe_sender);
   ~ServiceWorkerDispatcher() override;
 
   void OnMessageReceived(const IPC::Message& msg);
@@ -58,17 +53,12 @@
       blink::mojom::ServiceWorkerObjectInfoPtr info);
 
   static ServiceWorkerDispatcher* GetOrCreateThreadSpecificInstance(
-      scoped_refptr<ThreadSafeSender> thread_safe_sender,
-      scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner);
+      scoped_refptr<ThreadSafeSender> thread_safe_sender);
 
   // Unlike GetOrCreateThreadSpecificInstance() this doesn't create a new
   // instance if thread-local instance doesn't exist.
   static ServiceWorkerDispatcher* GetThreadSpecificInstance();
 
-  base::SingleThreadTaskRunner* main_thread_task_runner() {
-    return main_thread_task_runner_.get();
-  }
-
  private:
   using WorkerObjectMap = std::map<int, WebServiceWorkerImpl*>;
 
@@ -96,7 +86,6 @@
   WorkerObjectMap service_workers_;
 
   scoped_refptr<ThreadSafeSender> thread_safe_sender_;
-  scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
 
   DISALLOW_COPY_AND_ASSIGN(ServiceWorkerDispatcher);
 };
diff --git a/content/renderer/service_worker/service_worker_dispatcher_unittest.cc b/content/renderer/service_worker/service_worker_dispatcher_unittest.cc
index c7f6b6cd..e14d621 100644
--- a/content/renderer/service_worker/service_worker_dispatcher_unittest.cc
+++ b/content/renderer/service_worker/service_worker_dispatcher_unittest.cc
@@ -49,9 +49,8 @@
   ServiceWorkerDispatcherTest() {}
 
   void SetUp() override {
-    dispatcher_.reset(
-        new ServiceWorkerDispatcher(nullptr /* thread_safe_sender */,
-                                    nullptr /* main_thread_task_runner */));
+    dispatcher_ = std::make_unique<ServiceWorkerDispatcher>(
+        nullptr /* thread_safe_sender */);
   }
 
   bool ContainsServiceWorker(int handle_id) {
diff --git a/content/renderer/service_worker/service_worker_message_filter.cc b/content/renderer/service_worker/service_worker_message_filter.cc
index eaab92ca..97c828c 100644
--- a/content/renderer/service_worker/service_worker_message_filter.cc
+++ b/content/renderer/service_worker/service_worker_message_filter.cc
@@ -26,7 +26,7 @@
 void ServiceWorkerMessageFilter::OnFilteredMessageReceived(
     const IPC::Message& msg) {
   ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
-      thread_safe_sender(), main_thread_task_runner())
+      thread_safe_sender())
       ->OnMessageReceived(msg);
 }
 
diff --git a/content/renderer/service_worker/service_worker_network_provider.cc b/content/renderer/service_worker/service_worker_network_provider.cc
index e754ce2..3b235e41 100644
--- a/content/renderer/service_worker/service_worker_network_provider.cc
+++ b/content/renderer/service_worker/service_worker_network_provider.cc
@@ -295,8 +295,7 @@
   // current() may be null in tests.
   if (ChildThreadImpl::current()) {
     ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
-        ChildThreadImpl::current()->thread_safe_sender(),
-        base::ThreadTaskRunnerHandle::Get().get());
+        ChildThreadImpl::current()->thread_safe_sender());
     context_ = base::MakeRefCounted<ServiceWorkerProviderContext>(
         browser_provider_id, provider_type, std::move(client_request),
         std::move(host_ptr_info), std::move(controller_info),
@@ -318,8 +317,7 @@
     scoped_refptr<ThreadSafeSender> sender) {
   // Initialize the provider context with info for
   // ServiceWorkerGlobalScope#registration.
-  ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(
-      sender, base::ThreadTaskRunnerHandle::Get());
+  ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance(sender);
   context_ = base::MakeRefCounted<ServiceWorkerProviderContext>(
       info->provider_id, std::move(info->client_request),
       std::move(info->host_ptr_info));
diff --git a/content/renderer/service_worker/service_worker_provider_context_unittest.cc b/content/renderer/service_worker/service_worker_provider_context_unittest.cc
index 53d778f..83cb4ca 100644
--- a/content/renderer/service_worker/service_worker_provider_context_unittest.cc
+++ b/content/renderer/service_worker/service_worker_provider_context_unittest.cc
@@ -274,7 +274,7 @@
 
   void SetUp() override {
     sender_ = new ServiceWorkerTestSender(&ipc_sink_);
-    dispatcher_.reset(new ServiceWorkerDispatcher(sender_.get(), nullptr));
+    dispatcher_ = std::make_unique<ServiceWorkerDispatcher>(sender_.get());
   }
 
   void EnableS13nServiceWorker() {
diff --git a/content/test/gpu/PRESUBMIT.py b/content/test/gpu/PRESUBMIT.py
index d2a12e0..f24ba67 100644
--- a/content/test/gpu/PRESUBMIT.py
+++ b/content/test/gpu/PRESUBMIT.py
@@ -14,11 +14,6 @@
       name='run_content_test_gpu_unittests', cmd=[
         input_api.python_executable, 'run_unittests.py', 'gpu_tests'],
       kwargs={}, message=output_api.PresubmitError),
-
-    input_api.Command(
-      name='trigger_gpu_test_unittest', cmd=[
-        input_api.python_executable, 'trigger_gpu_test_unittest.py'],
-      kwargs={}, message=output_api.PresubmitError),
   ]
   return input_api.RunTests(commands)
 
diff --git a/content/test/gpu/generate_buildbot_json.py b/content/test/gpu/generate_buildbot_json.py
index ea64ebd4..dd622f3 100755
--- a/content/test/gpu/generate_buildbot_json.py
+++ b/content/test/gpu/generate_buildbot_json.py
@@ -2558,12 +2558,12 @@
 def add_common_test_properties(test, tester_config):
   if tester_config.get('use_gpu_trigger_script'):
     test['trigger_script'] = {
-      'script': '//content/test/gpu/trigger_gpu_test.py',
+      'script': '//testing/trigger_scripts/trigger_multiple_dimensions.py',
       'args': [
-        '--gpu-trigger-configs',
+        '--multiple-trigger-configs',
         json.dumps(tester_config['swarming_dimensions'] +
                    tester_config.get('alternate_swarming_dimensions', [])),
-        '--gpu-trigger-script-verbose',
+        '--multiple-dimension-script-verbose',
         'True'
       ],
     }
diff --git a/content/test/gpu/gpu_tests/pixel_expectations.py b/content/test/gpu/gpu_tests/pixel_expectations.py
index f085d20..9a945d24 100644
--- a/content/test/gpu/gpu_tests/pixel_expectations.py
+++ b/content/test/gpu/gpu_tests/pixel_expectations.py
@@ -78,6 +78,8 @@
               ['mac', 'linux', 'win', 'android'], bug=735228)
     self.Flaky('Pixel_OffscreenCanvasTransferAfterStyleResize',
               ['mac', 'linux', 'win', 'android'], bug=735171)
+    self.Flaky('Pixel_OffscreenCanvasTransferToImageBitmap',
+              ['linux', 'android'], bug=807742)
 
     self.Flaky('Pixel_OffscreenCanvasWebGLSoftwareCompositingWorker',
         ['mac', ('nvidia', 0xfe9), 'debug'], bug=751328)
diff --git a/docs/ios/build_instructions.md b/docs/ios/build_instructions.md
index 1d0c76a..8f7a6eb 100644
--- a/docs/ios/build_instructions.md
+++ b/docs/ios/build_instructions.md
@@ -236,7 +236,7 @@
 `--gtest_filter=SomeTest.FooBar` should be passed through the `-c` flag:
 
 ```shell
-$ out/Debug-iphonesimulator/iossim -d "iPhone 6s" -s 10.0 \
+$ out/Debug-iphonesimulator/iossim \
     -c "--gtest_filter=SomeTest.FooBar --gtest_repeat=3" \
     out/Debug-iphonesimulator/base_unittests.app
 ```
@@ -253,6 +253,28 @@
     out/Debug-iphonesimulator/ios_chrome_ui_egtests.app/PlugIns/ios_chrome_ui_egtests_module.xctest
 ```
 
+### Running on specific simulator
+
+By default, `iossim` will pick an arbitrary simulator to run the tests. If
+you want to run them on a specific simulator, you can use `-d` to pick the
+simulated device and `-s` to select the iOS version.
+
+For example, to run the tests on a simulated iPhone 6s running iOS 10.0,
+you would invoke `iossim` like this.
+
+```shell
+$ out/Debug-iphonesimulator/iossim -d 'iPhone 6s' -s '10.0' \
+    out/Debug-iphonesimulator/base_unittests.app
+```
+
+Please note that by default only a subset of simulator devices are installed
+with Xcode. You may have to install additional simulators in Xcode (or even
+an older version of Xcode) to be able to run on a specific configuration.
+
+Go to "Preferences > Components" tab in Xcode to install other simulator images
+(this is the location the setting is in Xcode 9.2; it may be different in other
+version of the tool).
+
 ## Update your checkout
 
 To update an existing checkout, you can run
diff --git a/extensions/browser/updater/extension_downloader.cc b/extensions/browser/updater/extension_downloader.cc
index be25a77..35a2cbd 100644
--- a/extensions/browser/updater/extension_downloader.cc
+++ b/extensions/browser/updater/extension_downloader.cc
@@ -31,6 +31,7 @@
 #include "extensions/browser/updater/extension_cache.h"
 #include "extensions/browser/updater/extension_downloader_test_delegate.h"
 #include "extensions/browser/updater/request_queue_impl.h"
+#include "extensions/common/extension_updater_uma.h"
 #include "extensions/common/extension_urls.h"
 #include "extensions/common/manifest_url_handlers.h"
 #include "google_apis/gaia/identity_provider.h"
@@ -450,6 +451,9 @@
     return;
   }
 
+  UMA_HISTOGRAM_COUNTS_100("Extensions.ExtensionUpdaterUpdateCalls",
+                           id_set.size());
+
   RequestQueue<ManifestFetchData>::iterator i;
   for (i = manifests_queue_.begin(); i != manifests_queue_.end(); ++i) {
     if (fetch_data->full_url() == i->full_url()) {
@@ -961,6 +965,8 @@
 
 void ExtensionDownloader::NotifyUpdateFound(const std::string& id,
                                             const std::string& version) {
+  UMA_HISTOGRAM_COUNTS_100("Extensions.ExtensionUpdaterUpdateFoundCount", 1);
+
   UpdateDetails updateInfo(id, base::Version(version));
   content::NotificationService::current()->Notify(
       extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND,
diff --git a/extensions/common/BUILD.gn b/extensions/common/BUILD.gn
index 616fcbe0..f8ee9b4 100644
--- a/extensions/common/BUILD.gn
+++ b/extensions/common/BUILD.gn
@@ -115,6 +115,7 @@
       "extension_resource_path_normalizer.h",
       "extension_set.cc",
       "extension_set.h",
+      "extension_updater_uma.h",
       "extension_urls.cc",
       "extension_urls.h",
       "extension_utility_types.h",
diff --git a/extensions/common/extension_updater_uma.h b/extensions/common/extension_updater_uma.h
new file mode 100644
index 0000000..d5132378
--- /dev/null
+++ b/extensions/common/extension_updater_uma.h
@@ -0,0 +1,21 @@
+// 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 EXTENSIONS_COMMON_EXTENSION_UPDATER_UMA_H_
+#define EXTENSIONS_COMMON_EXTENSION_UPDATER_UMA_H_
+
+namespace extensions {
+
+// These enum values are used in UMA, they should NOT be reordered.
+enum class ExtensionUpdaterUpdateResult {
+  NO_UPDATE = 0,
+  UPDATE_SUCCESS = 1,
+  UPDATE_ERROR = 2,
+
+  UPDATE_RESULT_COUNT
+};
+
+}  // namespace extensions
+
+#endif  // EXTENSIONS_COMMON_EXTENSION_UPDATER_UMA_H_
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index e3cf02d..97b7f5f 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -2377,6 +2377,8 @@
   GLsizei offscreen_target_samples_;
   GLboolean offscreen_target_buffer_preserved_;
 
+  GLint max_offscreen_framebuffer_size_;
+
   // Whether or not offscreen color buffers exist in front/back pairs that
   // can be swapped.
   GLboolean offscreen_single_buffer_;
@@ -3197,6 +3199,7 @@
       offscreen_target_stencil_format_(0),
       offscreen_target_samples_(0),
       offscreen_target_buffer_preserved_(true),
+      max_offscreen_framebuffer_size_(0),
       offscreen_single_buffer_(false),
       offscreen_saved_color_format_(0),
       offscreen_buffer_should_have_alpha_(false),
@@ -3551,6 +3554,10 @@
                                         ? GL_RGBA
                                         : GL_RGB;
 
+    max_offscreen_framebuffer_size_ =
+        std::min(renderbuffer_manager()->max_renderbuffer_size(),
+                 texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D));
+
     gfx::Size initial_size = attrib_helper.offscreen_framebuffer_size;
     if (initial_size.IsEmpty()) {
       // If we're an offscreen surface with zero width and/or height, set to a
@@ -5314,7 +5321,8 @@
   offscreen_size_ = size;
   int w = offscreen_size_.width();
   int h = offscreen_size_.height();
-  if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
+  if (w < 0 || h < 0 || w > max_offscreen_framebuffer_size_ ||
+      h > max_offscreen_framebuffer_size_) {
     LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFramebuffer failed "
                << "to allocate storage due to excessive dimensions.";
     return false;
@@ -5431,8 +5439,12 @@
   GLboolean has_alpha = c.alpha;
   TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
 
-  width = std::max(1U, width);
-  height = std::max(1U, height);
+  // gfx::Size uses integers, make sure width and height do not overflow
+  static_assert(sizeof(GLuint) >= sizeof(int), "Unexpected GLuint size.");
+  static const GLuint kMaxDimension =
+      static_cast<GLuint>(std::numeric_limits<int>::max());
+  width = std::min(std::max(1U, width), kMaxDimension);
+  height = std::min(std::max(1U, height), kMaxDimension);
 
   gl::GLSurface::ColorSpace surface_color_space =
       gl::GLSurface::ColorSpace::UNSPECIFIED;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
index 9f4b840..7946b46 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
@@ -745,6 +745,9 @@
       attrib_helper.lose_context_when_out_of_memory;
 
   api()->glGetIntegervFn(GL_MAX_TEXTURE_SIZE, &max_2d_texture_size_);
+  api()->glGetIntegervFn(GL_MAX_RENDERBUFFER_SIZE, &max_renderbuffer_size_);
+  max_offscreen_framebuffer_size_ =
+      std::min(max_2d_texture_size_, max_renderbuffer_size_);
 
   if (offscreen_) {
     offscreen_single_buffer_ = attrib_helper.single_buffer;
@@ -1025,8 +1028,8 @@
   }
 
   if (size.width() < 0 || size.height() < 0 ||
-      size.width() > max_2d_texture_size_ ||
-      size.height() > max_2d_texture_size_) {
+      size.width() > max_offscreen_framebuffer_size_ ||
+      size.height() > max_offscreen_framebuffer_size_) {
     LOG(ERROR) << "GLES2DecoderPassthroughImpl::ResizeOffscreenFramebuffer "
                   "failed to allocate storage due to excessive dimensions.";
     return false;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
index cbb75760e..8c52069c 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
@@ -644,8 +644,10 @@
   std::vector<std::unique_ptr<EmulatedColorBuffer>> available_color_textures_;
   size_t create_color_buffer_count_for_test_;
 
-  // Maximum 2D texture size for limiting offscreen framebuffer sizes
-  GLint max_2d_texture_size_;
+  // Maximum 2D resource sizes for limiting offscreen framebuffer sizes
+  GLint max_2d_texture_size_ = 0;
+  GLint max_renderbuffer_size_ = 0;
+  GLint max_offscreen_framebuffer_size_ = 0;
 
   // State tracking of currently bound draw and read framebuffers (client IDs)
   GLuint bound_draw_framebuffer_;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
index 9cf9267..cf026d6 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
@@ -3391,7 +3391,12 @@
                                                            GLfloat scale_factor,
                                                            GLenum color_space,
                                                            GLboolean alpha) {
-  gfx::Size safe_size(std::max(1U, width), std::max(1U, height));
+  // gfx::Size uses integers, make sure width and height do not overflow
+  static_assert(sizeof(GLuint) >= sizeof(int), "Unexpected GLuint size.");
+  static const GLuint kMaxDimension =
+      static_cast<GLuint>(std::numeric_limits<int>::max());
+  gfx::Size safe_size(std::min(std::max(1U, width), kMaxDimension),
+                      std::min(std::max(1U, height), kMaxDimension));
   if (offscreen_) {
     if (!ResizeOffscreenFramebuffer(safe_size)) {
       LOG(ERROR) << "GLES2DecoderPassthroughImpl: Context lost because "
diff --git a/gpu/command_buffer/tests/gl_offscreen_surface_unittest.cc b/gpu/command_buffer/tests/gl_offscreen_surface_unittest.cc
index b76c50f..03b2f1e 100644
--- a/gpu/command_buffer/tests/gl_offscreen_surface_unittest.cc
+++ b/gpu/command_buffer/tests/gl_offscreen_surface_unittest.cc
@@ -50,4 +50,33 @@
   gl.Destroy();
 }
 
+// Resize to a number between maximum int and uint
+TEST(OffscreenSurfaceTest, ResizeOverflow) {
+  GLManager::Options options;
+  options.size = gfx::Size(4, 4);
+  options.context_type = CONTEXT_TYPE_OPENGLES2;
+  options.context_lost_allowed = true;
+
+  GLManager gl;
+  gl.Initialize(options);
+  ASSERT_TRUE(gl.IsInitialized());
+  gl.MakeCurrent();
+
+  // If losing the context will cause the process to exit, do not perform this
+  // test as it will cause all subsequent tests to not run.
+  if (gl.workarounds().exit_on_context_lost) {
+    gl.Destroy();
+    return;
+  }
+
+  // Context loss is allowed trying to resize to such a huge value but make sure
+  // that no asserts or undefined behavior is triggered
+  static const GLuint kLargeSize =
+      static_cast<GLuint>(std::numeric_limits<int>::max()) + 10;
+  glResizeCHROMIUM(kLargeSize, 1, 1.0f, GL_COLOR_SPACE_UNSPECIFIED_CHROMIUM,
+                   GL_TRUE);
+
+  gl.Destroy();
+}
+
 }  // namespace gpu
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm
index 9961578..d7cf686 100644
--- a/ios/chrome/browser/ui/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -1840,8 +1840,9 @@
       // by the |completion| block below.
       UIView* launchScreenView = launchScreenController.view;
       launchScreenView.userInteractionEnabled = NO;
-      launchScreenView.frame = self.view.window.bounds;
-      [self.view.window addSubview:launchScreenView];
+      UIWindow* window = UIApplication.sharedApplication.keyWindow;
+      launchScreenView.frame = window.bounds;
+      [window addSubview:launchScreenView];
 
       // Replace the completion handler sent to the superclass with one which
       // removes |launchScreenView| and resets the status bar. If |completion|
diff --git a/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view.mm b/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view.mm
index a06be65..70047f8 100644
--- a/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view.mm
+++ b/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view.mm
@@ -104,10 +104,9 @@
   }
   DCHECK(self.buttonFactory);
 
-  self.backgroundColor =
-      self.buttonFactory.toolbarConfiguration.backgroundColor;
   self.translatesAutoresizingMaskIntoConstraints = NO;
 
+  [self setUpBlurredBackground];
   [self setUpLocationBar];
   [self setUpLeadingStackView];
   [self setUpTrailingStackView];
@@ -124,11 +123,22 @@
 
 #pragma mark - Setup
 
+// Sets the blur effect on the toolbar background.
+- (void)setUpBlurredBackground {
+  UIBlurEffect* blurEffect = self.buttonFactory.toolbarConfiguration.blurEffect;
+  UIVisualEffectView* blur =
+      [[UIVisualEffectView alloc] initWithEffect:blurEffect];
+  [self addSubview:blur];
+  blur.translatesAutoresizingMaskIntoConstraints = NO;
+  AddSameConstraints(blur, self);
+}
+
 // Sets the location bar container and its view if present.
 - (void)setUpLocationBar {
   self.locationBarContainer = [[UIView alloc] init];
   self.locationBarContainer.backgroundColor =
-      self.buttonFactory.toolbarConfiguration.omniboxBackgroundColor;
+      [self.buttonFactory.toolbarConfiguration
+          locationBarBackgroundColorWithVisibility:1];
   self.locationBarContainer.layer.cornerRadius =
       kAdaptiveLocationBarCornerRadius;
   [self.locationBarContainer
diff --git a/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view_controller.mm b/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view_controller.mm
index 6c53a28..5c1d940 100644
--- a/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view_controller.mm
+++ b/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view_controller.mm
@@ -59,8 +59,7 @@
 
 - (void)resetAfterSideSwipeSnapshot {
   [super resetAfterSideSwipeSnapshot];
-  self.view.backgroundColor =
-      self.buttonFactory.toolbarConfiguration.backgroundColor;
+  self.view.backgroundColor = nil;
   self.view.locationBarContainer.hidden = NO;
 }
 
@@ -137,8 +136,8 @@
                         (kToolbarHeight - kToolbarHeightFullscreen) * progress -
                         2 * kLocationBarVerticalMargin);
   self.view.locationBarContainer.backgroundColor =
-      [self.buttonFactory.toolbarConfiguration.omniboxBackgroundColor
-          colorWithAlphaComponent:alphaValue];
+      [self.buttonFactory.toolbarConfiguration
+          locationBarBackgroundColorWithVisibility:alphaValue];
 }
 
 - (void)updateForFullscreenEnabled:(BOOL)enabled {
diff --git a/ios/chrome/browser/ui/toolbar/adaptive/secondary_toolbar_view.mm b/ios/chrome/browser/ui/toolbar/adaptive/secondary_toolbar_view.mm
index b6591c98..461d14d9 100644
--- a/ios/chrome/browser/ui/toolbar/adaptive/secondary_toolbar_view.mm
+++ b/ios/chrome/browser/ui/toolbar/adaptive/secondary_toolbar_view.mm
@@ -71,10 +71,15 @@
   }
   DCHECK(self.buttonFactory);
 
-  self.backgroundColor =
-      self.buttonFactory.toolbarConfiguration.backgroundColor;
   self.translatesAutoresizingMaskIntoConstraints = NO;
 
+  UIBlurEffect* blurEffect = self.buttonFactory.toolbarConfiguration.blurEffect;
+  UIVisualEffectView* blur =
+      [[UIVisualEffectView alloc] initWithEffect:blurEffect];
+  [self addSubview:blur];
+  blur.translatesAutoresizingMaskIntoConstraints = NO;
+  AddSameConstraints(blur, self);
+
   self.tabGridButton = [self.buttonFactory tabGridButton];
   self.shareButton = [self.buttonFactory shareButton];
   self.omniboxButton = [self.buttonFactory omniboxButton];
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_configuration.h b/ios/chrome/browser/ui/toolbar/clean/toolbar_configuration.h
index c6039c1..7ae9c8e 100644
--- a/ios/chrome/browser/ui/toolbar/clean/toolbar_configuration.h
+++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_configuration.h
@@ -19,17 +19,23 @@
 // Style of this configuration.
 @property(nonatomic, assign) ToolbarStyle style;
 
+// Blur effect for the toolbar background.
+@property(nonatomic, readonly) UIBlurEffect* blurEffect;
+
 // Background color of the NTP. Used to do as if the toolbar was transparent and
 // the NTP is visible behind it.
 @property(nonatomic, readonly) UIColor* NTPBackgroundColor;
 
 // Background color of the toolbar.
+// TODO(crbug.com/800266): Remove this property.
 @property(nonatomic, readonly) UIColor* backgroundColor;
 
 // Background color of the omnibox.
+// TODO(crbug.com/800266): Remove this property.
 @property(nonatomic, readonly) UIColor* omniboxBackgroundColor;
 
 // Border color of the omnibox.
+// TODO(crbug.com/800266): Remove this property.
 @property(nonatomic, readonly) UIColor* omniboxBorderColor;
 
 // Color of the title of the buttons for the normal state.
@@ -38,6 +44,12 @@
 // Color of the title of the buttons for the highlighted state.
 @property(nonatomic, readonly) UIColor* buttonTitleHighlightedColor;
 
+// Returns the background color of the location bar, with a |visibilityFactor|.
+// The |visibilityFactor| is here to alter the alpha value of the background
+// color. Even with a |visibilityFactor| of 1, the final color could is
+// translucent.
+- (UIColor*)locationBarBackgroundColorWithVisibility:(CGFloat)visibilityFactor;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_TOOLBAR_CLEAN_TOOLBAR_CONFIGURATION_H_
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_configuration.mm b/ios/chrome/browser/ui/toolbar/clean/toolbar_configuration.mm
index 971e1ee6..e8b9b95f 100644
--- a/ios/chrome/browser/ui/toolbar/clean/toolbar_configuration.mm
+++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_configuration.mm
@@ -4,6 +4,7 @@
 
 #import "ios/chrome/browser/ui/toolbar/clean/toolbar_configuration.h"
 
+#import "base/logging.h"
 #import "ios/chrome/browser/ui/toolbar/clean/toolbar_constants.h"
 #import "ios/chrome/browser/ui/toolbar/public/web_toolbar_controller_constants.h"
 #include "ios/chrome/browser/ui/ui_util.h"
@@ -25,6 +26,15 @@
   return self;
 }
 
+- (UIBlurEffect*)blurEffect {
+  switch (self.style) {
+    case NORMAL:
+      return [UIBlurEffect effectWithStyle:UIBlurEffectStyleProminent];
+    case INCOGNITO:
+      return [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
+  }
+}
+
 - (UIColor*)NTPBackgroundColor {
   switch (self.style) {
     case NORMAL:
@@ -37,12 +47,8 @@
 
 - (UIColor*)backgroundColor {
   if (IsUIRefreshPhase1Enabled()) {
-    switch (self.style) {
-      case NORMAL:
-        return UIColorFromRGB(kAdaptiveToolbarBackgroundColor);
-      case INCOGNITO:
-        return UIColorFromRGB(kIncognitoToolbarBackgroundColor);
-    }
+    NOTREACHED();
+    return nil;
   } else {
     switch (self.style) {
       case NORMAL:
@@ -55,12 +61,8 @@
 
 - (UIColor*)omniboxBackgroundColor {
   if (IsUIRefreshPhase1Enabled()) {
-    switch (self.style) {
-      case NORMAL:
-        return UIColorFromRGB(kAdaptiveLocationBackgroundColor);
-      case INCOGNITO:
-        return UIColorFromRGB(kIcongnitoAdaptiveLocationBackgroundColor);
-    }
+    NOTREACHED();
+    return nil;
   } else {
     switch (self.style) {
       case NORMAL:
@@ -72,11 +74,16 @@
 }
 
 - (UIColor*)omniboxBorderColor {
-  switch (self.style) {
-    case NORMAL:
-      return UIColorFromRGB(kLocationBarBorderColor);
-    case INCOGNITO:
-      return UIColorFromRGB(kIncognitoLocationBarBorderColor);
+  if (IsUIRefreshPhase1Enabled()) {
+    NOTREACHED();
+    return nil;
+  } else {
+    switch (self.style) {
+      case NORMAL:
+        return UIColorFromRGB(kLocationBarBorderColor);
+      case INCOGNITO:
+        return UIColorFromRGB(kIncognitoLocationBarBorderColor);
+    }
   }
 }
 
@@ -98,4 +105,17 @@
   }
 }
 
+- (UIColor*)locationBarBackgroundColorWithVisibility:(CGFloat)visibilityFactor {
+  switch (self.style) {
+    case NORMAL:
+      return [UIColor colorWithWhite:0
+                               alpha:kAdaptiveLocationBarBackgroundAlpha *
+                                     visibilityFactor];
+    case INCOGNITO:
+      return [UIColor colorWithWhite:1
+                               alpha:kAdaptiveLocationBarBackgroundAlpha *
+                                     visibilityFactor];
+  }
+}
+
 @end
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_constants.h b/ios/chrome/browser/ui/toolbar/clean/toolbar_constants.h
index e92359d..c996fa89 100644
--- a/ios/chrome/browser/ui/toolbar/clean/toolbar_constants.h
+++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_constants.h
@@ -56,12 +56,9 @@
 // Animation constants.
 extern const LayoutOffset kToolbarButtonAnimationOffset;
 
-// Adaptive Toolbar styling.
-extern const CGFloat kAdaptiveToolbarBackgroundColor;
-
 // Adaptive Location bar constants.
 extern const CGFloat kAdaptiveLocationBarCornerRadius;
-extern const CGFloat kAdaptiveLocationBackgroundColor;
 extern const CGFloat kIcongnitoAdaptiveLocationBackgroundColor;
+extern const CGFloat kAdaptiveLocationBarBackgroundAlpha;
 
 #endif  // IOS_CHROME_BROWSER_UI_TOOLBAR_CLEAN_TOOLBAR_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_constants.mm b/ios/chrome/browser/ui/toolbar/clean/toolbar_constants.mm
index 7a37185..182740d 100644
--- a/ios/chrome/browser/ui/toolbar/clean/toolbar_constants.mm
+++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_constants.mm
@@ -43,7 +43,6 @@
 
 const LayoutOffset kToolbarButtonAnimationOffset = -10.0;
 
-const CGFloat kAdaptiveToolbarBackgroundColor = 0xE4E4E4;
-const CGFloat kAdaptiveLocationBarCornerRadius = 12;
-const CGFloat kAdaptiveLocationBackgroundColor = 0xCCCCCC;
+const CGFloat kAdaptiveLocationBarCornerRadius = 11;
 const CGFloat kIcongnitoAdaptiveLocationBackgroundColor = 0x6A6A6A;
+const CGFloat kAdaptiveLocationBarBackgroundAlpha = 0.12;
diff --git a/ios/web/web_state/navigation_and_load_callbacks_inttest.mm b/ios/web/web_state/navigation_and_load_callbacks_inttest.mm
index 0780cde..b5f8a52 100644
--- a/ios/web/web_state/navigation_and_load_callbacks_inttest.mm
+++ b/ios/web/web_state/navigation_and_load_callbacks_inttest.mm
@@ -27,6 +27,8 @@
 #import "ios/web/test/web_int_test.h"
 #import "ios/web/web_state/ui/crw_web_controller.h"
 #import "ios/web/web_state/web_state_impl.h"
+#include "net/test/embedded_test_server/default_handlers.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/page_transition_types.h"
@@ -70,7 +72,7 @@
 // Verifies correctness of |NavigationContext| (|arg1|) for new page navigation
 // passed to |DidFinishNavigation|. Asserts that |NavigationContext| the same as
 // |context|.
-ACTION_P3(VerifyNewPageFinishedContext, web_state, url, context) {
+ACTION_P4(VerifyNewPageFinishedContext, web_state, url, mime_type, context) {
   ASSERT_EQ(*context, arg1);
   EXPECT_EQ(web_state, arg0);
   EXPECT_EQ(web_state, (*context)->GetWebState());
@@ -85,10 +87,10 @@
   EXPECT_FALSE((*context)->GetError());
   EXPECT_FALSE((*context)->IsRendererInitiated());
   ASSERT_TRUE((*context)->GetResponseHeaders());
-  std::string mime_type;
-  (*context)->GetResponseHeaders()->GetMimeType(&mime_type);
+  std::string actual_mime_type;
+  (*context)->GetResponseHeaders()->GetMimeType(&actual_mime_type);
   ASSERT_TRUE(web_state->IsLoading());
-  EXPECT_EQ(kExpectedMimeType, mime_type);
+  EXPECT_EQ(mime_type, actual_mime_type);
   NavigationManager* navigation_manager = web_state->GetNavigationManager();
   NavigationItem* item = navigation_manager->GetLastCommittedItem();
   EXPECT_TRUE(!item->GetTimestamp().is_null());
@@ -382,6 +384,10 @@
 
     WebStateImpl* web_state_impl = reinterpret_cast<WebStateImpl*>(web_state());
     web_state_impl->GetWebController().nativeProvider = provider_;
+
+    test_server_ = std::make_unique<net::test_server::EmbeddedTestServer>();
+    RegisterDefaultHandlers(test_server_.get());
+    ASSERT_TRUE(test_server_->Start());
   }
 
   void TearDown() override {
@@ -397,6 +403,8 @@
   ScopedObserver<WebState, WebStateObserver> scoped_observer_;
   testing::InSequence callbacks_sequence_checker_;
 
+  std::unique_ptr<net::test_server::EmbeddedTestServer> test_server_;
+
   DISALLOW_COPY_AND_ASSIGN(NavigationAndLoadCallbacksTest);
 };
 
@@ -416,7 +424,8 @@
   EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/true))
       .WillOnce(Return(true));
   EXPECT_CALL(observer_, DidFinishNavigation(web_state(), _))
-      .WillOnce(VerifyNewPageFinishedContext(web_state(), url, &context));
+      .WillOnce(VerifyNewPageFinishedContext(web_state(), url,
+                                             kExpectedMimeType, &context));
   EXPECT_CALL(observer_, DidStopLoading(web_state()));
   EXPECT_CALL(observer_,
               PageLoaded(web_state(), PageLoadCompletionStatus::SUCCESS));
@@ -443,7 +452,8 @@
   EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/true))
       .WillOnce(Return(true));
   EXPECT_CALL(observer_, DidFinishNavigation(web_state(), _))
-      .WillOnce(VerifyNewPageFinishedContext(web_state(), url, &context));
+      .WillOnce(VerifyNewPageFinishedContext(web_state(), url,
+                                             kExpectedMimeType, &context));
   EXPECT_CALL(observer_, DidStopLoading(web_state()));
   EXPECT_CALL(observer_,
               PageLoaded(web_state(), PageLoadCompletionStatus::SUCCESS));
@@ -537,7 +547,8 @@
   EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/true))
       .WillOnce(Return(true));
   EXPECT_CALL(observer_, DidFinishNavigation(web_state(), _))
-      .WillOnce(VerifyNewPageFinishedContext(web_state(), url, &context));
+      .WillOnce(VerifyNewPageFinishedContext(web_state(), url,
+                                             kExpectedMimeType, &context));
   EXPECT_CALL(observer_, DidStopLoading(web_state()));
   EXPECT_CALL(observer_,
               PageLoaded(web_state(), PageLoadCompletionStatus::SUCCESS));
@@ -602,7 +613,8 @@
   EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/true))
       .WillOnce(Return(true));
   EXPECT_CALL(observer_, DidFinishNavigation(web_state(), _))
-      .WillOnce(VerifyNewPageFinishedContext(web_state(), url, &context));
+      .WillOnce(VerifyNewPageFinishedContext(web_state(), url,
+                                             kExpectedMimeType, &context));
   EXPECT_CALL(observer_, DidStopLoading(web_state()));
   EXPECT_CALL(observer_,
               PageLoaded(web_state(), PageLoadCompletionStatus::SUCCESS));
@@ -645,7 +657,8 @@
   EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/true))
       .WillOnce(Return(true));
   EXPECT_CALL(observer_, DidFinishNavigation(web_state(), _))
-      .WillOnce(VerifyNewPageFinishedContext(web_state(), url, &context));
+      .WillOnce(VerifyNewPageFinishedContext(web_state(), url,
+                                             kExpectedMimeType, &context));
   EXPECT_CALL(observer_, DidStopLoading(web_state()));
   EXPECT_CALL(observer_,
               PageLoaded(web_state(), PageLoadCompletionStatus::SUCCESS));
@@ -984,12 +997,48 @@
   EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/true))
       .WillOnce(Return(true));
   EXPECT_CALL(observer_, DidFinishNavigation(web_state(), _))
-      .WillOnce(
-          VerifyNewPageFinishedContext(web_state(), redirect_url, &context));
+      .WillOnce(VerifyNewPageFinishedContext(web_state(), redirect_url,
+                                             kExpectedMimeType, &context));
   EXPECT_CALL(observer_, DidStopLoading(web_state()));
   EXPECT_CALL(observer_,
               PageLoaded(web_state(), PageLoadCompletionStatus::SUCCESS));
   ASSERT_TRUE(LoadUrl(url));
 }
 
+// Tests failed load after the navigation is sucessfully finished.
+TEST_F(NavigationAndLoadCallbacksTest, FailedLoad) {
+  GURL url = test_server_->GetURL("/exabyte_response");
+
+  NavigationContext* context = nullptr;
+  EXPECT_CALL(observer_, DidStartLoading(web_state()));
+  EXPECT_CALL(*decider_, ShouldAllowRequest(_, _)).WillOnce(Return(true));
+  EXPECT_CALL(observer_, DidStartNavigation(web_state(), _))
+      .WillOnce(VerifyNewPageStartedContext(web_state(), url, &context));
+  EXPECT_CALL(*decider_, ShouldAllowResponse(_, /*for_main_frame=*/true))
+      .WillOnce(Return(true));
+  EXPECT_CALL(observer_, DidFinishNavigation(web_state(), _))
+      .WillOnce(VerifyNewPageFinishedContext(web_state(), url, /*mime_type=*/"",
+                                             &context));
+  EXPECT_CALL(observer_, DidStopLoading(web_state()));
+  EXPECT_CALL(observer_,
+              PageLoaded(web_state(), PageLoadCompletionStatus::FAILURE));
+  // TODO(crbug.com/806457): PageLoaded should be called only once.
+  EXPECT_CALL(observer_,
+              PageLoaded(web_state(), PageLoadCompletionStatus::FAILURE));
+  web::test::LoadUrl(web_state(), url);
+
+  // Server does not stop responding until it's shut down. Let the server run
+  // to make web state finish the navigation.
+  EXPECT_FALSE(WaitUntilConditionOrTimeout(2.0, ^{
+    return !web_state()->IsLoading();
+  }));
+
+  // It this point the navigation should be finished. Shutdown the server and
+  // wait until web state stop loading.
+  ASSERT_TRUE(test_server_->ShutdownAndWaitUntilComplete());
+  EXPECT_TRUE(WaitUntilConditionOrTimeout(testing::kWaitForPageLoadTimeout, ^{
+    return !web_state()->IsLoading();
+  }));
+}
+
 }  // namespace web
diff --git a/net/socket/socket_bio_adapter.cc b/net/socket/socket_bio_adapter.cc
index 25b43261..edbd637a 100644
--- a/net/socket/socket_bio_adapter.cc
+++ b/net/socket/socket_bio_adapter.cc
@@ -18,8 +18,42 @@
 #include "net/socket/socket.h"
 #include "net/socket/stream_socket.h"
 #include "net/ssl/openssl_ssl_util.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
 #include "third_party/boringssl/src/include/openssl/bio.h"
 
+namespace {
+
+net::NetworkTrafficAnnotationTag kTrafficAnnotation =
+    net::DefineNetworkTrafficAnnotation("socket_bio_adapter", R"(
+      semantics {
+        sender: "Socket BIO Adapter"
+        description:
+          "SocketBIOAdapter is used only internal to //net code as an internal "
+          "detail to implement a TLS connection for a Socket class, and is not "
+          "being called directly outside of this abstraction."
+        trigger:
+          "Establishing a TLS connection to a remote endpoint. There are many "
+          "different ways in which a TLS connection may be triggered, such as "
+          "loading an HTTPS URL."
+        data:
+          "All data sent or received over a TLS connection. This traffic may "
+          "either be the handshake or application data. During the handshake, "
+          "the target host name, user's IP, data related to previous "
+          "handshake, client certificates, and channel ID, may be sent. When "
+          "the connection is used to load an HTTPS URL, the application data "
+          "includes cookies, request headers, and the response body."
+        destination: OTHER
+        destination_other:
+          "Any destination the implementing socket is connected to."
+      }
+      policy {
+        cookies_allowed: NO
+        setting: "This feature cannot be disabled."
+        policy_exception_justification: "Essential for navigation."
+      })");
+
+}  // namespace
+
 namespace net {
 
 SocketBIOAdapter::SocketBIOAdapter(StreamSocket* socket,
@@ -247,8 +281,8 @@
   while (write_error_ == OK && write_buffer_used_ > 0) {
     int write_size =
         std::min(write_buffer_used_, write_buffer_->RemainingCapacity());
-    int result =
-        socket_->Write(write_buffer_.get(), write_size, write_callback_);
+    int result = socket_->Write(write_buffer_.get(), write_size,
+                                write_callback_, kTrafficAnnotation);
     if (result == ERR_IO_PENDING) {
       write_error_ = ERR_IO_PENDING;
       return;
diff --git a/pdf/pdfium/pdfium_page.cc b/pdf/pdfium/pdfium_page.cc
index a9c1c516..d2765e9 100644
--- a/pdf/pdfium/pdfium_page.cc
+++ b/pdf/pdfium/pdfium_page.cc
@@ -358,7 +358,7 @@
 PDFiumPage::Area PDFiumPage::GetDestinationTarget(FPDF_DEST destination,
                                                   LinkTarget* target) {
   if (!target)
-    return DOCLINK_AREA;
+    return NONSELECTABLE_AREA;
 
   target->page = FPDFDest_GetPageIndex(engine_->doc(), destination);
 
diff --git a/remoting/android/client_java_tmpl.gni b/remoting/android/client_java_tmpl.gni
index 4db1dea..0832e85 100644
--- a/remoting/android/client_java_tmpl.gni
+++ b/remoting/android/client_java_tmpl.gni
@@ -83,8 +83,6 @@
       "//remoting/android:remoting_apk_manifest",
       "//third_party/android_tools:android_arch_lifecycle_common_java",
       "//third_party/android_tools:android_support_annotations_java",
-      "//third_party/android_tools:android_support_compat_java",
-      "//third_party/android_tools:android_support_core_ui_java",
       "//third_party/android_tools:android_support_v7_appcompat_java",
       "//third_party/android_tools:android_support_v7_mediarouter_java",
       "//ui/android:ui_utils_java",
diff --git a/services/audio/BUILD.gn b/services/audio/BUILD.gn
index 9d20bd13..ed7d66b 100644
--- a/services/audio/BUILD.gn
+++ b/services/audio/BUILD.gn
@@ -46,6 +46,7 @@
     "//base/test:test_support",
     "//media:test_support",
     "//services/audio/public/cpp",
+    "//services/audio/public/cpp:test_support",
     "//services/audio/public/interfaces",
     "//services/service_manager/public/cpp",
     "//services/service_manager/public/cpp:service_test_support",
diff --git a/services/audio/DEPS b/services/audio/DEPS
index 66918d3..88e0aca 100644
--- a/services/audio/DEPS
+++ b/services/audio/DEPS
@@ -2,4 +2,5 @@
    "+media/audio",
    "+media/base",
    "+media/mojo",
+   "+services/audio/public",
 ]
diff --git a/services/audio/public/cpp/BUILD.gn b/services/audio/public/cpp/BUILD.gn
index 8975eeb..43656011 100644
--- a/services/audio/public/cpp/BUILD.gn
+++ b/services/audio/public/cpp/BUILD.gn
@@ -15,3 +15,19 @@
     "//services/service_manager/public/cpp",
   ]
 }
+
+source_set("test_support") {
+  testonly = true
+
+  sources = [
+    "fake_system_info.cc",
+    "fake_system_info.h",
+  ]
+
+  public_deps = [
+    "//base",
+    "//media",
+    "//services/audio/public/interfaces",
+    "//services/service_manager/public/cpp",
+  ]
+}
diff --git a/services/audio/public/cpp/fake_system_info.cc b/services/audio/public/cpp/fake_system_info.cc
new file mode 100644
index 0000000..34fe9781
--- /dev/null
+++ b/services/audio/public/cpp/fake_system_info.cc
@@ -0,0 +1,74 @@
+// 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 "services/audio/public/cpp/fake_system_info.h"
+
+#include "services/audio/public/interfaces/constants.mojom.h"
+#include "services/service_manager/public/cpp/bind_source_info.h"
+#include "services/service_manager/public/cpp/service_context.h"
+
+namespace audio {
+
+FakeSystemInfo::FakeSystemInfo() {}
+
+FakeSystemInfo::~FakeSystemInfo() {}
+
+// static
+void FakeSystemInfo::OverrideGlobalBinderForAudioService(
+    FakeSystemInfo* fake_system_info) {
+  service_manager::ServiceContext::SetGlobalBinderForTesting(
+      mojom::kServiceName, mojom::SystemInfo::Name_,
+      base::BindRepeating(&FakeSystemInfo::Bind,
+                          base::Unretained(fake_system_info)));
+}
+
+void FakeSystemInfo::GetInputStreamParameters(
+    const std::string& device_id,
+    GetInputStreamParametersCallback callback) {
+  std::move(callback).Run(base::nullopt);
+}
+
+void FakeSystemInfo::GetOutputStreamParameters(
+    const std::string& device_id,
+    GetOutputStreamParametersCallback callback) {
+  std::move(callback).Run(base::nullopt);
+}
+
+void FakeSystemInfo::HasInputDevices(HasInputDevicesCallback callback) {
+  std::move(callback).Run(false);
+}
+
+void FakeSystemInfo::HasOutputDevices(HasOutputDevicesCallback callback) {
+  std::move(callback).Run(false);
+}
+
+void FakeSystemInfo::GetInputDeviceDescriptions(
+    GetInputDeviceDescriptionsCallback callback) {
+  std::move(callback).Run(media::AudioDeviceDescriptions());
+}
+
+void FakeSystemInfo::GetOutputDeviceDescriptions(
+    GetOutputDeviceDescriptionsCallback callback) {
+  std::move(callback).Run(media::AudioDeviceDescriptions());
+}
+
+void FakeSystemInfo::GetAssociatedOutputDeviceID(
+    const std::string& input_device_id,
+    GetAssociatedOutputDeviceIDCallback callback) {
+  std::move(callback).Run(base::nullopt);
+}
+
+void FakeSystemInfo::GetInputDeviceInfo(const std::string& input_device_id,
+                                        GetInputDeviceInfoCallback callback) {
+  std::move(callback).Run(base::nullopt, base::nullopt);
+}
+
+void FakeSystemInfo::Bind(const std::string& interface_name,
+                          mojo::ScopedMessagePipeHandle handle,
+                          const service_manager::BindSourceInfo& source_info) {
+  DCHECK(interface_name == mojom::SystemInfo::Name_);
+  bindings_.AddBinding(this, mojom::SystemInfoRequest(std::move(handle)));
+}
+
+}  // namespace audio
diff --git a/services/audio/public/cpp/fake_system_info.h b/services/audio/public/cpp/fake_system_info.h
new file mode 100644
index 0000000..3a9db977
--- /dev/null
+++ b/services/audio/public/cpp/fake_system_info.h
@@ -0,0 +1,64 @@
+// 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 SERVICES_AUDIO_PUBLIC_CPP_FAKE_SYSTEM_INFO_H_
+#define SERVICES_AUDIO_PUBLIC_CPP_FAKE_SYSTEM_INFO_H_
+
+#include <string>
+
+#include "base/macros.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/system/message_pipe.h"
+#include "services/audio/public/interfaces/system_info.mojom.h"
+
+namespace service_manager {
+struct BindSourceInfo;
+}
+
+namespace audio {
+
+// An instance of this class can be used to override the global binding for
+// audio::SystemInfo. By default it behaves as if the system has no audio
+// devices. Inherit from it to override the behavior.
+class FakeSystemInfo : public mojom::SystemInfo {
+ public:
+  FakeSystemInfo();
+  ~FakeSystemInfo() override;
+
+  // See ServiceContext::ClearGlobalBindersForTesting() to clear it if needed.
+  static void OverrideGlobalBinderForAudioService(
+      FakeSystemInfo* fake_system_info);
+
+ protected:
+  // audio::mojom::SystemInfo implementation.
+  void GetInputStreamParameters(
+      const std::string& device_id,
+      GetInputStreamParametersCallback callback) override;
+  void GetOutputStreamParameters(
+      const std::string& device_id,
+      GetOutputStreamParametersCallback callback) override;
+  void HasInputDevices(HasInputDevicesCallback callback) override;
+  void HasOutputDevices(HasOutputDevicesCallback callback) override;
+  void GetInputDeviceDescriptions(
+      GetInputDeviceDescriptionsCallback callback) override;
+  void GetOutputDeviceDescriptions(
+      GetOutputDeviceDescriptionsCallback callback) override;
+  void GetAssociatedOutputDeviceID(
+      const std::string& input_device_id,
+      GetAssociatedOutputDeviceIDCallback callback) override;
+  void GetInputDeviceInfo(const std::string& input_device_id,
+                          GetInputDeviceInfoCallback callback) override;
+
+ private:
+  void Bind(const std::string& interface_name,
+            mojo::ScopedMessagePipeHandle handle,
+            const service_manager::BindSourceInfo& source_info);
+
+  mojo::BindingSet<mojom::SystemInfo> bindings_;
+  DISALLOW_COPY_AND_ASSIGN(FakeSystemInfo);
+};
+
+}  // namespace audio
+
+#endif  // SERVICES_AUDIO_PUBLIC_CPP_FAKE_SYSTEM_INFO_H_
diff --git a/services/audio/service_factory.cc b/services/audio/service_factory.cc
index ce991fd..40532ea 100644
--- a/services/audio/service_factory.cc
+++ b/services/audio/service_factory.cc
@@ -6,6 +6,7 @@
 
 #include "services/audio/in_process_audio_manager_accessor.h"
 #include "services/audio/service.h"
+#include "services/service_manager/public/cpp/service.h"
 
 namespace audio {
 
diff --git a/services/audio/service_factory.h b/services/audio/service_factory.h
index fb586ac..a7cf39e0 100644
--- a/services/audio/service_factory.h
+++ b/services/audio/service_factory.h
@@ -7,8 +7,9 @@
 
 #include <memory>
 
-#include "base/macros.h"
-#include "services/service_manager/public/cpp/service.h"
+namespace service_manager {
+class Service;
+}
 
 namespace media {
 class AudioManager;
diff --git a/services/audio/test/in_process_service_test.cc b/services/audio/test/in_process_service_test.cc
index 812f8a6..d27886d 100644
--- a/services/audio/test/in_process_service_test.cc
+++ b/services/audio/test/in_process_service_test.cc
@@ -7,6 +7,7 @@
 #include "media/audio/test_audio_thread.h"
 #include "mojo/public/cpp/bindings/binding_set.h"
 #include "services/audio/public/cpp/audio_system_to_service_adapter.h"
+#include "services/audio/public/cpp/fake_system_info.h"
 #include "services/audio/public/interfaces/constants.mojom.h"
 #include "services/audio/service_factory.h"
 #include "services/service_manager/public/cpp/service_context.h"
@@ -155,6 +156,36 @@
   DISALLOW_COPY_AND_ASSIGN(InProcessServiceTest);
 };
 
+// Tests for FakeSystemInfo overriding the global binder.
+class FakeSystemInfoTest : public InProcessServiceTest<false>,
+                           public FakeSystemInfo {
+ public:
+  FakeSystemInfoTest() {}
+  ~FakeSystemInfoTest() override {}
+
+ protected:
+  MOCK_METHOD0(MethodCalled, void());
+
+ private:
+  void HasInputDevices(HasInputDevicesCallback callback) override {
+    std::move(callback).Run(true);
+    MethodCalled();
+  }
+
+  DISALLOW_COPY_AND_ASSIGN(FakeSystemInfoTest);
+};
+
+TEST_F(FakeSystemInfoTest, HasInputDevicesCalledOnGlobalBinderOverride) {
+  FakeSystemInfo::OverrideGlobalBinderForAudioService(this);
+  base::RunLoop wait_loop;
+  EXPECT_CALL(*this, MethodCalled())
+      .WillOnce(testing::Invoke(&wait_loop, &base::RunLoop::Quit));
+  audio_system()->HasInputDevices(base::BindOnce([](bool) {}));
+  wait_loop.Run();
+  service_manager::ServiceContext::ClearGlobalBindersForTesting(
+      mojom::kServiceName);
+}
+
 }  // namespace audio
 
 // AudioSystem interface conformance tests.
diff --git a/services/network/public/cpp/BUILD.gn b/services/network/public/cpp/BUILD.gn
index afa471c8..550cab9 100644
--- a/services/network/public/cpp/BUILD.gn
+++ b/services/network/public/cpp/BUILD.gn
@@ -10,6 +10,10 @@
   sources = [
     "cors/cors.cc",
     "cors/cors.h",
+    "cors/cors_legacy.cc",
+    "cors/cors_legacy.h",
+    "cors/cors_url_loader.cc",
+    "cors/cors_url_loader.h",
     "features.cc",
     "features.h",
     "mutable_network_traffic_annotation_tag_struct_traits.h",
diff --git a/services/network/public/cpp/cors/cors.cc b/services/network/public/cpp/cors/cors.cc
index e79503d..6773cbd 100644
--- a/services/network/public/cpp/cors/cors.cc
+++ b/services/network/public/cpp/cors/cors.cc
@@ -4,6 +4,9 @@
 
 #include "services/network/public/cpp/cors/cors.h"
 
+#include <algorithm>
+#include <vector>
+
 #include "url/gurl.h"
 #include "url/origin.h"
 #include "url/url_util.h"
diff --git a/services/network/public/cpp/cors/cors_legacy.cc b/services/network/public/cpp/cors/cors_legacy.cc
new file mode 100644
index 0000000..c6a815e
--- /dev/null
+++ b/services/network/public/cpp/cors/cors_legacy.cc
@@ -0,0 +1,42 @@
+// 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 "services/network/public/cpp/cors/cors_legacy.h"
+
+#include <algorithm>
+#include <vector>
+
+#include "url/gurl.h"
+#include "url/origin.h"
+#include "url/url_util.h"
+
+namespace {
+
+std::vector<url::Origin>* secure_origins = nullptr;
+
+}  // namespace
+
+namespace network {
+
+namespace cors {
+
+namespace legacy {
+
+void RegisterSecureOrigins(const std::vector<url::Origin>& origins) {
+  delete secure_origins;
+  secure_origins = new std::vector<url::Origin>(origins.size());
+  std::copy(origins.begin(), origins.end(), secure_origins->begin());
+}
+
+const std::vector<url::Origin>& GetSecureOrigins() {
+  if (!secure_origins)
+    secure_origins = new std::vector<url::Origin>;
+  return *secure_origins;
+}
+
+}  // namespace legacy
+
+}  // namespace cors
+
+}  // namespace network
diff --git a/services/network/public/cpp/cors/cors_legacy.h b/services/network/public/cpp/cors/cors_legacy.h
new file mode 100644
index 0000000..5263368
--- /dev/null
+++ b/services/network/public/cpp/cors/cors_legacy.h
@@ -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.
+
+#ifndef SERVICES_NETWORK_PUBLIC_CPP_CORS_CORS_LEGACY_H_
+#define SERVICES_NETWORK_PUBLIC_CPP_CORS_CORS_LEGACY_H_
+
+#include <vector>
+
+#include "base/component_export.h"
+
+namespace url {
+class Origin;
+}  // namespace url
+
+namespace network {
+namespace cors {
+
+// Functions in namespace legacy are for legacy code path. Pure Network
+// Service code should not use it. Since files in public/cpp/cors are shared
+// between Network Service and legacy code path in content, but Network Service
+// should not know content dependent concepts, we need to provide abstracted
+// interfaces to implement extra checks for the case code runs in content.
+//
+// TODO(toyoshim): Remove all functions after Network Service is enabled.
+namespace legacy {
+
+// Registers whitelisted secure origins for CORS checks in CORSURLLoader.
+COMPONENT_EXPORT(NETWORK_CPP)
+void RegisterSecureOrigins(const std::vector<url::Origin>& secure_origins);
+
+// Refers the registered whitelisted secure origins.
+COMPONENT_EXPORT(NETWORK_CPP)
+const std::vector<url::Origin>& GetSecureOrigins();
+
+}  // namespace legacy
+
+}  // namespace cors
+}  // namespace network
+
+#endif  // SERVICES_NETWORK_PUBLIC_CPP_CORS_CORS_LEGACY_H_
diff --git a/content/network/cors/cors_url_loader.cc b/services/network/public/cpp/cors/cors_url_loader.cc
similarity index 74%
rename from content/network/cors/cors_url_loader.cc
rename to services/network/public/cpp/cors/cors_url_loader.cc
index cdb399c6..257e3afc 100644
--- a/content/network/cors/cors_url_loader.cc
+++ b/services/network/public/cpp/cors/cors_url_loader.cc
@@ -2,26 +2,32 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/network/cors/cors_url_loader.h"
+#include "services/network/public/cpp/cors/cors_url_loader.h"
 
-#include "content/public/common/origin_util.h"
-#include "content/public/common/resource_type.h"
-#include "content/public/common/service_worker_modes.h"
+#include "base/stl_util.h"
 #include "services/network/public/cpp/cors/cors.h"
+#include "services/network/public/cpp/cors/cors_legacy.h"
+#include "url/url_util.h"
 
-using network::mojom::CORSError;
-using network::mojom::FetchRequestMode;
-
-namespace content {
+namespace network {
 
 namespace {
 
-bool CalculateCORSFlag(const network::ResourceRequest& request) {
-  if (request.fetch_request_mode == FetchRequestMode::kNavigate &&
-      (request.resource_type == RESOURCE_TYPE_MAIN_FRAME ||
-       request.resource_type == RESOURCE_TYPE_SUB_FRAME)) {
+bool IsOriginWhiteListedTrustworthy(const url::Origin& origin) {
+  if (origin.unique())
     return false;
-  }
+
+  // Note: NoAccessSchemes are managed by per-process basis. This check is for
+  // use of network service disabled.
+  if (base::ContainsValue(url::GetNoAccessSchemes(), origin.scheme()))
+    return false;
+
+  return base::ContainsValue(cors::legacy::GetSecureOrigins(), origin);
+}
+
+bool CalculateCORSFlag(const ResourceRequest& request) {
+  if (request.fetch_request_mode == mojom::FetchRequestMode::kNavigate)
+    return false;
   url::Origin url_origin = url::Origin::Create(request.url);
   if (IsOriginWhiteListedTrustworthy(url_origin))
     return false;
@@ -49,10 +55,10 @@
     int32_t routing_id,
     int32_t request_id,
     uint32_t options,
-    const network::ResourceRequest& resource_request,
-    network::mojom::URLLoaderClientPtr client,
+    const ResourceRequest& resource_request,
+    mojom::URLLoaderClientPtr client,
     const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
-    network::mojom::URLLoaderFactory* network_loader_factory)
+    mojom::URLLoaderFactory* network_loader_factory)
     : network_loader_factory_(network_loader_factory),
       network_client_binding_(this),
       forwarding_client_(std::move(client)),
@@ -65,16 +71,16 @@
   DCHECK(network_loader_factory_);
 
   if (fetch_cors_flag_ &&
-      fetch_request_mode_ == FetchRequestMode::kSameOrigin) {
-    forwarding_client_->OnComplete(network::URLLoaderCompletionStatus(
-        network::CORSErrorStatus(CORSError::kDisallowedByMode)));
+      fetch_request_mode_ == mojom::FetchRequestMode::kSameOrigin) {
+    forwarding_client_->OnComplete(URLLoaderCompletionStatus(
+        CORSErrorStatus(mojom::CORSError::kDisallowedByMode)));
     return;
   }
 
   // TODO(toyoshim): Needs some checks if the calculated fetch_cors_flag_
   // is allowed in this request or not.
 
-  network::mojom::URLLoaderClientPtr network_client;
+  mojom::URLLoaderClientPtr network_client;
   network_client_binding_.Bind(mojo::MakeRequest(&network_client));
   // Binding |this| as an unretained pointer is safe because
   // |network_client_binding_| shares this object's lifetime.
@@ -120,29 +126,26 @@
 }
 
 void CORSURLLoader::OnReceiveResponse(
-    const network::ResourceResponseHead& response_head,
+    const ResourceResponseHead& response_head,
     const base::Optional<net::SSLInfo>& ssl_info,
-    network::mojom::DownloadedTempFilePtr downloaded_file) {
+    mojom::DownloadedTempFilePtr downloaded_file) {
   DCHECK(network_loader_);
   DCHECK(forwarding_client_);
   DCHECK(!is_waiting_follow_redirect_call_);
-  if (fetch_cors_flag_ &&
-      network::cors::IsCORSEnabledRequestMode(fetch_request_mode_)) {
-    base::Optional<CORSError> cors_error = network::cors::CheckAccess(
+  if (fetch_cors_flag_ && cors::IsCORSEnabledRequestMode(fetch_request_mode_)) {
+    base::Optional<mojom::CORSError> cors_error = cors::CheckAccess(
         last_response_url_, response_head.headers->response_code(),
         GetHeaderString(response_head.headers,
-                        network::cors::header_names::kAccessControlAllowOrigin),
-        GetHeaderString(
-            response_head.headers,
-            network::cors::header_names::kAccessControlAllowSuborigin),
-        GetHeaderString(
-            response_head.headers,
-            network::cors::header_names::kAccessControlAllowCredentials),
+                        cors::header_names::kAccessControlAllowOrigin),
+        GetHeaderString(response_head.headers,
+                        cors::header_names::kAccessControlAllowSuborigin),
+        GetHeaderString(response_head.headers,
+                        cors::header_names::kAccessControlAllowCredentials),
         fetch_credentials_mode_, security_origin_);
     if (cors_error) {
       // TODO(toyoshim): Generate related_response_headers here.
-      network::CORSErrorStatus cors_error_status(*cors_error);
-      HandleComplete(network::URLLoaderCompletionStatus(cors_error_status));
+      CORSErrorStatus cors_error_status(*cors_error);
+      HandleComplete(URLLoaderCompletionStatus(cors_error_status));
       return;
     }
   }
@@ -152,7 +155,7 @@
 
 void CORSURLLoader::OnReceiveRedirect(
     const net::RedirectInfo& redirect_info,
-    const network::ResourceResponseHead& response_head) {
+    const ResourceResponseHead& response_head) {
   DCHECK(network_loader_);
   DCHECK(forwarding_client_);
   DCHECK(!is_waiting_follow_redirect_call_);
@@ -207,8 +210,7 @@
   forwarding_client_->OnStartLoadingResponseBody(std::move(body));
 }
 
-void CORSURLLoader::OnComplete(
-    const network::URLLoaderCompletionStatus& status) {
+void CORSURLLoader::OnComplete(const URLLoaderCompletionStatus& status) {
   DCHECK(network_loader_);
   DCHECK(forwarding_client_);
   DCHECK(!is_waiting_follow_redirect_call_);
@@ -217,15 +219,14 @@
 
 void CORSURLLoader::OnUpstreamConnectionError() {
   // |network_client_binding_| has experienced a connection error and will no
-  // longer call any of the network::mojom::URLLoaderClient methods above. The
-  // client pipe to the downstream client is closed to inform it of this
-  // failure. The client should respond by closing its network::mojom::URLLoader
-  // pipe which will cause this object to be destroyed.
+  // longer call any of the mojom::URLLoaderClient methods above. The client
+  // pipe to the downstream client is closed to inform it of this failure. The
+  // client should respond by closing its mojom::URLLoader pipe which will cause
+  // this object to be destroyed.
   forwarding_client_.reset();
 }
 
-void CORSURLLoader::HandleComplete(
-    const network::URLLoaderCompletionStatus& status) {
+void CORSURLLoader::HandleComplete(const URLLoaderCompletionStatus& status) {
   forwarding_client_->OnComplete(status);
   forwarding_client_.reset();
 
@@ -234,4 +235,4 @@
   network_loader_.reset();
 }
 
-}  // namespace content
+}  // namespace network
diff --git a/content/network/cors/cors_url_loader.h b/services/network/public/cpp/cors/cors_url_loader.h
similarity index 65%
rename from content/network/cors/cors_url_loader.h
rename to services/network/public/cpp/cors/cors_url_loader.h
index 54d7e399..2213ab3 100644
--- a/content/network/cors/cors_url_loader.h
+++ b/services/network/public/cpp/cors/cors_url_loader.h
@@ -2,10 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_NETWORK_CORS_CORS_URL_LOADER_H_
-#define CONTENT_NETWORK_CORS_CORS_URL_LOADER_H_
+#ifndef SERVICES_NETWORK_PUBLIC_CPP_CORS_CORS_URL_LOADER_H_
+#define SERVICES_NETWORK_PUBLIC_CPP_CORS_CORS_URL_LOADER_H_
 
-#include "content/common/content_export.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "services/network/public/interfaces/fetch_api.mojom.h"
@@ -13,29 +12,30 @@
 #include "url/gurl.h"
 #include "url/origin.h"
 
-namespace content {
+namespace network {
 
 // Wrapper class that adds cross-origin resource sharing capabilities
 // (https://fetch.spec.whatwg.org/#http-cors-protocol), delegating requests as
 // well as potential preflight requests to the supplied
 // |network_loader_factory|. It is owned by the CORSURLLoaderFactory that
 // created it.
-class CONTENT_EXPORT CORSURLLoader : public network::mojom::URLLoader,
-                                     public network::mojom::URLLoaderClient {
+class COMPONENT_EXPORT(NETWORK_CPP) CORSURLLoader
+    : public mojom::URLLoader,
+      public mojom::URLLoaderClient {
  public:
   // Assumes network_loader_factory outlives this loader.
   CORSURLLoader(
       int32_t routing_id,
       int32_t request_id,
       uint32_t options,
-      const network::ResourceRequest& resource_request,
-      network::mojom::URLLoaderClientPtr client,
+      const ResourceRequest& resource_request,
+      mojom::URLLoaderClientPtr client,
       const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
-      network::mojom::URLLoaderFactory* network_loader_factory);
+      mojom::URLLoaderFactory* network_loader_factory);
 
   ~CORSURLLoader() override;
 
-  // network::mojom::URLLoader overrides:
+  // mojom::URLLoader overrides:
   void FollowRedirect() override;
   void ProceedWithResponse() override;
   void SetPriority(net::RequestPriority priority,
@@ -43,13 +43,12 @@
   void PauseReadingBodyFromNet() override;
   void ResumeReadingBodyFromNet() override;
 
-  // network::mojom::URLLoaderClient overrides:
-  void OnReceiveResponse(
-      const network::ResourceResponseHead& head,
-      const base::Optional<net::SSLInfo>& ssl_info,
-      network::mojom::DownloadedTempFilePtr downloaded_file) override;
+  // mojom::URLLoaderClient overrides:
+  void OnReceiveResponse(const ResourceResponseHead& head,
+                         const base::Optional<net::SSLInfo>& ssl_info,
+                         mojom::DownloadedTempFilePtr downloaded_file) override;
   void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
-                         const network::ResourceResponseHead& head) override;
+                         const ResourceResponseHead& head) override;
   void OnDataDownloaded(int64_t data_length, int64_t encoded_length) override;
   void OnUploadProgress(int64_t current_position,
                         int64_t total_size,
@@ -58,7 +57,7 @@
   void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
   void OnStartLoadingResponseBody(
       mojo::ScopedDataPipeConsumerHandle body) override;
-  void OnComplete(const network::URLLoaderCompletionStatus& status) override;
+  void OnComplete(const URLLoaderCompletionStatus& status) override;
 
  private:
   // Called when there is a connection error on the upstream pipe used for the
@@ -66,18 +65,18 @@
   void OnUpstreamConnectionError();
 
   // Handles OnComplete() callback.
-  void HandleComplete(const network::URLLoaderCompletionStatus& status);
+  void HandleComplete(const URLLoaderCompletionStatus& status);
 
   // This raw URLLoaderFactory pointer is shared with the CORSURLLoaderFactory
   // that created and owns this object.
-  network::mojom::URLLoaderFactory* network_loader_factory_;
+  mojom::URLLoaderFactory* network_loader_factory_;
 
   // For the actual request.
-  network::mojom::URLLoaderPtr network_loader_;
-  mojo::Binding<network::mojom::URLLoaderClient> network_client_binding_;
+  mojom::URLLoaderPtr network_loader_;
+  mojo::Binding<mojom::URLLoaderClient> network_client_binding_;
 
   // To be a URLLoader for the client.
-  network::mojom::URLLoaderClientPtr forwarding_client_;
+  mojom::URLLoaderClientPtr forwarding_client_;
 
   // Request initiator's origin.
   url::Origin security_origin_;
@@ -91,13 +90,13 @@
   bool is_waiting_follow_redirect_call_ = false;
 
   // Corresponds to the Fetch spec, https://fetch.spec.whatwg.org/.
-  network::mojom::FetchRequestMode fetch_request_mode_;
-  network::mojom::FetchCredentialsMode fetch_credentials_mode_;
+  mojom::FetchRequestMode fetch_request_mode_;
+  mojom::FetchCredentialsMode fetch_credentials_mode_;
   bool fetch_cors_flag_;
 
   DISALLOW_COPY_AND_ASSIGN(CORSURLLoader);
 };
 
-}  // namespace content
+}  // namespace network
 
-#endif  // CONTENT_NETWORK_CORS_CORS_URL_LOADER_H_
+#endif  // SERVICES_NETWORK_PUBLIC_CPP_CORS_CORS_URL_LOADER_H_
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json
index 9fe1c64..07d79b12 100644
--- a/testing/buildbot/chromium.gpu.fyi.json
+++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -10685,12 +10685,12 @@
         "test": "angle_end2end_tests",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -10711,12 +10711,12 @@
         "test": "angle_white_box_tests",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -10739,12 +10739,12 @@
         "test": "gles2_conform_test",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -10768,12 +10768,12 @@
         "test": "gles2_conform_test",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -10794,12 +10794,12 @@
         "test": "gles2_conform_test",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -10817,12 +10817,12 @@
         "test": "gpu_unittests",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -10840,12 +10840,12 @@
         "test": "swiftshader_unittests",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       }
@@ -10870,12 +10870,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -10908,12 +10908,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -10939,12 +10939,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -10970,12 +10970,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -11007,12 +11007,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -11042,12 +11042,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -11077,12 +11077,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -11112,12 +11112,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -11147,12 +11147,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       }
     ]
@@ -15259,12 +15259,12 @@
         "test": "angle_end2end_tests",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -15286,12 +15286,12 @@
         "test": "angle_unittests",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -15312,12 +15312,12 @@
         "test": "angle_white_box_tests",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -15342,12 +15342,12 @@
         "test": "browser_tests",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -15369,12 +15369,12 @@
         "test": "gl_tests",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -15397,12 +15397,12 @@
         "test": "gl_tests",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -15423,12 +15423,12 @@
         "test": "gl_unittests",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -15451,12 +15451,12 @@
         "test": "gles2_conform_test",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -15480,12 +15480,12 @@
         "test": "gles2_conform_test",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -15506,12 +15506,12 @@
         "test": "gles2_conform_test",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -15529,12 +15529,12 @@
         "test": "gpu_unittests",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -15552,12 +15552,12 @@
         "test": "swiftshader_unittests",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -15581,12 +15581,12 @@
         "test": "video_decode_accelerator_unittest",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -15610,12 +15610,12 @@
         "test": "video_decode_accelerator_unittest",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -15639,12 +15639,12 @@
         "test": "video_decode_accelerator_unittest",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       }
@@ -15669,12 +15669,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -15703,12 +15703,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -15737,12 +15737,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -15771,12 +15771,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -15805,12 +15805,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -15843,12 +15843,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -15884,12 +15884,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -15915,12 +15915,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -15964,12 +15964,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -15999,12 +15999,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -16033,12 +16033,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -16064,12 +16064,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -16101,12 +16101,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -16138,12 +16138,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -16175,12 +16175,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -16210,12 +16210,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -16245,12 +16245,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -16280,12 +16280,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -16315,12 +16315,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -16350,12 +16350,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       }
     ]
@@ -16405,12 +16405,12 @@
         "test": "angle_deqp_egl_tests",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -16434,12 +16434,12 @@
         "test": "angle_deqp_gles2_tests",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -16463,12 +16463,12 @@
         "test": "angle_deqp_gles31_tests",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -16492,12 +16492,12 @@
         "test": "angle_deqp_gles31_tests",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -16521,12 +16521,12 @@
         "test": "angle_deqp_gles3_tests",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       }
diff --git a/testing/buildbot/chromium.gpu.json b/testing/buildbot/chromium.gpu.json
index 5dd9969..2e453a3 100644
--- a/testing/buildbot/chromium.gpu.json
+++ b/testing/buildbot/chromium.gpu.json
@@ -2809,12 +2809,12 @@
         "test": "angle_unittests",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -2839,12 +2839,12 @@
         "test": "browser_tests",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -2866,12 +2866,12 @@
         "test": "gl_tests",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -2894,12 +2894,12 @@
         "test": "gl_tests",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -2920,12 +2920,12 @@
         "test": "gl_unittests",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       },
@@ -2949,12 +2949,12 @@
         "test": "video_decode_accelerator_unittest",
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         },
         "use_xvfb": false
       }
@@ -2986,12 +2986,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -3020,12 +3020,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -3054,12 +3054,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -3088,12 +3088,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -3126,12 +3126,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -3167,12 +3167,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -3216,12 +3216,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -3251,12 +3251,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -3285,12 +3285,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       },
       {
@@ -3320,12 +3320,12 @@
         },
         "trigger_script": {
           "args": [
-            "--gpu-trigger-configs",
+            "--multiple-trigger-configs",
             "[{\"gpu\": \"10de:1cb3-23.21.13.8792\", \"os\": \"Windows-2008ServerR2-SP1\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-23.21.13.8816\", \"os\": \"Windows-10\", \"pool\": \"Chrome-GPU\"}]",
-            "--gpu-trigger-script-verbose",
+            "--multiple-dimension-script-verbose",
             "True"
           ],
-          "script": "//content/test/gpu/trigger_gpu_test.py"
+          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
         }
       }
     ]
diff --git a/testing/libfuzzer/proto/skia_image_filter_proto_converter.cc b/testing/libfuzzer/proto/skia_image_filter_proto_converter.cc
index 6bb7f7a7..f1855eb 100644
--- a/testing/libfuzzer/proto/skia_image_filter_proto_converter.cc
+++ b/testing/libfuzzer/proto/skia_image_filter_proto_converter.cc
@@ -1302,7 +1302,7 @@
           break;
         case ValidVerb::kConic_Verb:
           num_conics += 1;
-        // fall-through
+          FALLTHROUGH;
         case ValidVerb::kQuad_Verb:
           num_points += 2;
           break;
diff --git a/testing/trigger_scripts/OWNERS b/testing/trigger_scripts/OWNERS
new file mode 100644
index 0000000..be9b88d
--- /dev/null
+++ b/testing/trigger_scripts/OWNERS
@@ -0,0 +1,5 @@
+eyaich@chromium.org
+jbudorick@chromium.org
+kbr@chromium.org
+martiniss@chromium.org
+maruel@chromium.org
diff --git a/testing/trigger_scripts/PRESUBMIT.py b/testing/trigger_scripts/PRESUBMIT.py
new file mode 100644
index 0000000..c666fc5
--- /dev/null
+++ b/testing/trigger_scripts/PRESUBMIT.py
@@ -0,0 +1,47 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Top-level presubmit script for testing/trigger_scripts.
+
+See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
+for more details about the presubmit API built into depot_tools.
+"""
+
+def CommonChecks(input_api, output_api):
+  commands = [
+    input_api.Command(
+      name='trigger_multiple_dimensions_unittest', cmd=[
+        input_api.python_executable, 'trigger_multiple_dimensions_unittest.py'],
+      kwargs={}, message=output_api.PresubmitError),
+  ]
+  return input_api.RunTests(commands)
+
+def CheckChangeOnUpload(input_api, output_api):
+  return CommonChecks(input_api, output_api)
+
+def CheckChangeOnCommit(input_api, output_api):
+  return CommonChecks(input_api, output_api)
+
+def PostUploadHook(cl, change, output_api):
+  """git cl upload will call this hook after the issue is created/modified.
+
+  This hook modifies the CL description in order to run extra GPU
+  tests (in particular, the WebGL 2.0 conformance tests) in addition
+  to the regular CQ try bots. This test suite is too large to run
+  against all Chromium commits, but should be run against changes
+  likely to affect these tests. The trigger_multiple_dimensions script
+  is used on the chromium.gpu.fyi waterfall and associated optional
+  tryservers, so it's desired to run extra tests when modifying these
+  scripts.
+  """
+  del change # for pylint
+  return output_api.EnsureCQIncludeTrybotsAreAdded(
+    cl,
+    [
+      'master.tryserver.chromium.linux:linux_optional_gpu_tests_rel',
+      'master.tryserver.chromium.mac:mac_optional_gpu_tests_rel',
+      'master.tryserver.chromium.win:win_optional_gpu_tests_rel',
+      'master.tryserver.chromium.android:android_optional_gpu_tests_rel',
+    ],
+    'Automatically added optional GPU tests to run on CQ.')
diff --git a/testing/trigger_scripts/README.md b/testing/trigger_scripts/README.md
new file mode 100644
index 0000000..836328ffc
--- /dev/null
+++ b/testing/trigger_scripts/README.md
@@ -0,0 +1,9 @@
+# Swarming trigger scripts
+
+This directory contains Swarming trigger scripts, which are trampoline
+scripts that provide finer-grained control of how tests are sharded
+and distributed on the Swarming fleet.
+
+Trigger scripts are documented here:
+
+https://cs.chromium.org/chromium/build/scripts/slave/recipe_modules/swarming/api.py?l=1292
diff --git a/content/test/gpu/trigger_gpu_test.py b/testing/trigger_scripts/trigger_multiple_dimensions.py
similarity index 70%
rename from content/test/gpu/trigger_gpu_test.py
rename to testing/trigger_scripts/trigger_multiple_dimensions.py
index d8371498..cb8723cf 100755
--- a/content/test/gpu/trigger_gpu_test.py
+++ b/testing/trigger_scripts/trigger_multiple_dimensions.py
@@ -4,22 +4,22 @@
 # found in the LICENSE file.
 """Custom swarming triggering script.
 
-This script does custom swarming triggering logic, to allow one GPU bot to
+This script does custom swarming triggering logic, to allow one bot to
 conceptually span multiple Swarming configurations, while lumping all trigger
 calls under one logical step.
 
 The reason this script is needed is to allow seamless upgrades of the GPU, OS
-version, or graphics driver. GPU tests are triggered with precise values for all
-of these Swarming dimensions. This ensures that if a machine is added to the
-Swarming pool with a slightly different configuration, tests don't fail for
-unexpected reasons.
+version, or graphics driver. Most Chromium tests, GPU tests in particular, are
+triggered with precise values for all of these Swarming dimensions. This ensures
+that if a machine is added to the Swarming pool with a slightly different
+configuration, tests don't fail for unexpected reasons.
 
 During an upgrade of the fleet, it's not feasible to take half of the machines
-offline. We had some experience with this during a recent upgrade of the GPUs in
-the main Windows and Linux NVIDIA bots. In the middle of the upgrade, only 50%
-of the capacity was available, and CQ jobs started to time out. Once the hurdle
-had been passed in the middle of the upgrade, capacity was sufficient, but it's
-crucial that this process remain seamless.
+offline. Some experience was gained with this during a recent upgrade of the
+GPUs in Chromium's main Windows and Linux NVIDIA bots. In the middle of the
+upgrade, only 50% of the capacity was available, and CQ jobs started to time
+out. Once the hurdle had been passed in the middle of the upgrade, capacity was
+sufficient, but it's crucial that this process remain seamless.
 
 This script receives multiple machine configurations on the command line in the
 form of quoted strings. These strings are JSON dictionaries that represent
@@ -44,10 +44,14 @@
 trigger. It modifies it in the following ways:
  * Intercepts the dump-json argument, and creates its own by combining the
    results from each trigger call.
- * Replaces the GPU-related Swarming dimensions with the ones chosen from the
-   gpu-trigger-configs list.
+ * Scans through the multiple-trigger-configs dictionaries. For any key found,
+   deletes that dimension from the originally triggered task's dimensions. This
+   is what allows the Swarming dimensions to be replaced.
+ * On a per-shard basis, adds the Swarming dimensions chosen from the
+   multiple-trigger-configs list to the dimensions for the shard.
 
 This script is normally called from the swarming recipe module in tools/build.
+
 """
 
 import argparse
@@ -61,8 +65,8 @@
 import urllib
 
 
-SRC_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(
-  os.path.abspath(__file__)))))
+SRC_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(
+  __file__))))
 
 SWARMING_PY = os.path.join(SRC_DIR, 'tools', 'swarming_client', 'swarming.py')
 
@@ -84,29 +88,20 @@
   return obj
 
 
-class GpuTestTriggerer(object):
+class MultiDimensionTestTriggerer(object):
   def __init__(self):
-    self._gpu_configs = None
+    self._bot_configs = None
     self._bot_statuses = []
     self._total_bots = 0
 
-  def filter_swarming_py_path_arg(self, args):
-    # TODO(kbr): remove this once the --swarming-py-path argument is
-    # no longer being passed by recipes. crbug.com/801346
-    try:
-      index = args.index('--swarming-py-path')
-      return args[:index] + args[index+2:]
-    except:
-      return args
-
-  def modify_args(self, all_args, gpu_index, shard_index, total_shards,
+  def modify_args(self, all_args, bot_index, shard_index, total_shards,
                   temp_file):
     """Modifies the given argument list.
 
     Specifically, it does the following:
       * Adds a --dump_json argument, to read in the results of the
         individual trigger command.
-      * Adds the dimensions associated with the GPU config at the given index.
+      * Adds the dimensions associated with the bot config at the given index.
       * If the number of shards is greater than one, adds --env
         arguments to set the GTEST_SHARD_INDEX and GTEST_TOTAL_SHARDS
         environment variables to _shard_index_ and _total_shards_,
@@ -121,38 +116,39 @@
     assert '--' in all_args, (
         'Malformed trigger command; -- argument expected but not found')
     dash_ind = all_args.index('--')
-    gpu_args = ['--dump-json', temp_file]
+    bot_args = ['--dump-json', temp_file]
     if total_shards > 1:
-      gpu_args.append('--env')
-      gpu_args.append('GTEST_SHARD_INDEX')
-      gpu_args.append(str(shard_index))
-      gpu_args.append('--env')
-      gpu_args.append('GTEST_TOTAL_SHARDS')
-      gpu_args.append(str(total_shards))
-    for key, val in sorted(self._gpu_configs[gpu_index].iteritems()):
-      gpu_args.append('--dimension')
-      gpu_args.append(key)
-      gpu_args.append(val)
-    return all_args[:dash_ind] + gpu_args + all_args[dash_ind:]
+      bot_args.append('--env')
+      bot_args.append('GTEST_SHARD_INDEX')
+      bot_args.append(str(shard_index))
+      bot_args.append('--env')
+      bot_args.append('GTEST_TOTAL_SHARDS')
+      bot_args.append(str(total_shards))
+    for key, val in sorted(self._bot_configs[bot_index].iteritems()):
+      bot_args.append('--dimension')
+      bot_args.append(key)
+      bot_args.append(val)
+    return all_args[:dash_ind] + bot_args + all_args[dash_ind:]
 
-  def parse_gpu_configs(self, args):
+  def parse_bot_configs(self, args):
     try:
-      self._gpu_configs = strip_unicode(json.loads(args.gpu_trigger_configs))
+      self._bot_configs = strip_unicode(json.loads(
+        args.multiple_trigger_configs))
     except Exception as e:
-      raise ValueError('Error while parsing JSON from gpu config string %s: %s'
-                       % (args.gpu_trigger_configs, str(e)))
+      raise ValueError('Error while parsing JSON from bot config string %s: %s'
+                       % (args.multiple_trigger_configs, str(e)))
     # Validate the input.
-    if not isinstance(self._gpu_configs, list):
-      raise ValueError('GPU configurations must be a list, were: %s' %
-                       args.gpu_trigger_configs)
-    if len(self._gpu_configs) < 1:
-      raise ValueError('GPU configuration list must have at least one entry')
-    if not all(isinstance(entry, dict) for entry in self._gpu_configs):
-      raise ValueError('GPU configurations must all be dictionaries')
+    if not isinstance(self._bot_configs, list):
+      raise ValueError('Bot configurations must be a list, were: %s' %
+                       args.multiple_trigger_configs)
+    if len(self._bot_configs) < 1:
+      raise ValueError('Bot configuration list must have at least one entry')
+    if not all(isinstance(entry, dict) for entry in self._bot_configs):
+      raise ValueError('Bot configurations must all be dictionaries')
 
-  def query_swarming_for_gpu_configs(self, verbose):
+  def query_swarming_for_bot_configs(self, verbose):
     # Query Swarming to figure out which bots are available.
-    for config in self._gpu_configs:
+    for config in self._bot_configs:
       values = []
       for key, value in sorted(config.iteritems()):
         values.append(('dimensions', '%s:%s' % (key, value)))
@@ -161,9 +157,8 @@
       values.append(('quarantined', 'FALSE'))
       query_arg = urllib.urlencode(values)
 
-      # This trick of closing the file handle is needed on Windows in
-      # order to make the file writeable.
-      temp_file = self.make_temp_file(prefix='trigger_gpu_test', suffix='.json')
+      temp_file = self.make_temp_file(prefix='trigger_multiple_dimensions',
+                                      suffix='.json')
       try:
         ret = self.run_swarming(['query',
                                  '-S',
@@ -185,7 +180,7 @@
         self._bot_statuses.append({'total': count, 'available': available})
         if verbose:
           idx = len(self._bot_statuses) - 1
-          print 'GPU config %d: %s' % (idx, str(self._bot_statuses[idx]))
+          print 'Bot config %d: %s' % (idx, str(self._bot_statuses[idx]))
       finally:
         self.delete_temp_file(temp_file)
     # Sum up the total count of all bots.
@@ -202,7 +197,7 @@
   def choose_random_int(self, max_num):
     return random.randint(1, max_num)
 
-  def pick_gpu_configuration(self, verbose):
+  def pick_bot_configuration(self, verbose):
     # These are the rules used:
     # 1. If any configuration has bots available, pick the configuration with
     #    the most bots available.
@@ -210,7 +205,7 @@
     #    based on the total number of bots in each configuration.
     #
     # This method updates bot_statuses_ in case (1), and in both cases, returns
-    # the index into gpu_configs_ that should be used.
+    # the index into bot_configs_ that should be used.
     if any(status['available'] > 0 for status in self._bot_statuses):
       # Case 1.
       max_index = 0
@@ -223,18 +218,18 @@
       self._bot_statuses[max_index]['available'] -= 1
       assert self._bot_statuses[max_index]['available'] >= 0
       if verbose:
-        print 'Chose GPU config %d because bots were available' % (max_index)
+        print 'Chose bot config %d because bots were available' % (max_index)
       return max_index
     # Case 2.
     # We want to choose a bot uniformly at random from all of the bots specified
-    # in the GPU configs. To do this, we conceptually group the bots into
+    # in the bot configs. To do this, we conceptually group the bots into
     # buckets, pick a random number between 1 and the total number of bots, and
     # figure out which bucket of bots it landed in.
     r = self.choose_random_int(self._total_bots)
     for i, status in enumerate(self._bot_statuses):
       if r <= status['total']:
         if verbose:
-          print 'Chose GPU config %d stochastically' % (i)
+          print 'Chose bot config %d stochastically' % (i)
         return i
       r -= status['total']
     raise Exception('Should not reach here')
@@ -274,17 +269,16 @@
     Returns:
       Exit code for the script.
     """
-    remaining = self.filter_swarming_py_path_arg(remaining)
-    verbose = args.gpu_trigger_script_verbose
-    self.parse_gpu_configs(args)
-    self.query_swarming_for_gpu_configs(verbose)
+    verbose = args.multiple_dimension_script_verbose
+    self.parse_bot_configs(args)
+    self.query_swarming_for_bot_configs(verbose)
 
     # In the remaining arguments, find the Swarming dimensions that are
-    # specified by the GPU configs and remove them, because for each shard,
-    # we're going to select one of the GPU configs and put all of its Swarming
+    # specified by the bot configs and remove them, because for each shard,
+    # we're going to select one of the bot configs and put all of its Swarming
     # dimensions on the command line.
     filtered_remaining_args = copy.deepcopy(remaining)
-    for config in self._gpu_configs:
+    for config in self._bot_configs:
       for k in config.iterkeys():
         filtered_remaining_args = self.remove_swarming_dimension(
           filtered_remaining_args, k)
@@ -293,15 +287,15 @@
 
     for i in xrange(args.shards):
       # For each shard that we're going to distribute, do the following:
-      # 1. Pick which GPU configuration to use.
-      # 2. Insert that GPU configuration's dimensions as command line
+      # 1. Pick which bot configuration to use.
+      # 2. Insert that bot configuration's dimensions as command line
       #    arguments, and invoke "swarming.py trigger".
-      gpu_index = self.pick_gpu_configuration(verbose)
+      bot_index = self.pick_bot_configuration(verbose)
       # Holds the results of the swarming.py trigger call.
       try:
-        json_temp = self.make_temp_file(prefix='trigger_gpu_test',
+        json_temp = self.make_temp_file(prefix='trigger_multiple_dimensions',
                                         suffix='.json')
-        args_to_pass = self.modify_args(filtered_remaining_args, gpu_index, i,
+        args_to_pass = self.modify_args(filtered_remaining_args, bot_index, i,
                                         args.shards, json_temp)
         ret = self.run_swarming(args_to_pass, verbose)
         if ret:
@@ -328,12 +322,13 @@
 
 def main():
   parser = argparse.ArgumentParser(description=__doc__)
-  parser.add_argument('--gpu-trigger-configs', type=str, required=True,
-                      help='The GPU configurations to trigger tasks on, in the'
-                      ' form of a JSON array of dictionaries. At least one'
-                      ' entry in this dictionary is required.')
-  parser.add_argument('--gpu-trigger-script-verbose', type=bool, default=False,
-                      help='Turn on verbose logging')
+  parser.add_argument('--multiple-trigger-configs', type=str, required=True,
+                      help='The Swarming configurations to trigger tasks on, '
+                      'in the form of a JSON array of dictionaries (these are '
+                      'Swarming dimension_sets). At least one entry in this '
+                      'dictionary is required.')
+  parser.add_argument('--multiple-dimension-script-verbose', type=bool,
+                      default=False, help='Turn on verbose logging')
   parser.add_argument('--dump-json', required=True,
                       help='(Swarming Trigger Script API) Where to dump the'
                       ' resulting json which indicates which tasks were'
@@ -344,7 +339,7 @@
 
   args, remaining = parser.parse_known_args()
 
-  return GpuTestTriggerer().trigger_tasks(args, remaining)
+  return MultiDimensionTestTriggerer().trigger_tasks(args, remaining)
 
 
 if __name__ == '__main__':
diff --git a/content/test/gpu/trigger_gpu_test_unittest.py b/testing/trigger_scripts/trigger_multiple_dimensions_unittest.py
similarity index 82%
rename from content/test/gpu/trigger_gpu_test_unittest.py
rename to testing/trigger_scripts/trigger_multiple_dimensions_unittest.py
index 7d485893..a0a3769 100755
--- a/content/test/gpu/trigger_gpu_test_unittest.py
+++ b/testing/trigger_scripts/trigger_multiple_dimensions_unittest.py
@@ -3,20 +3,25 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-"""Tests for trigger_gpu_test.py."""
+"""Tests for trigger_multiple_dimensions.py."""
 
 import unittest
 
-import trigger_gpu_test
+import trigger_multiple_dimensions
 
 class Args(object):
-  pass
+  def __init__(self):
+    self.shards = 1
+    self.dump_json = ''
+    self.multiple_trigger_configs = []
+    self.multiple_dimension_script_verbose = False
 
-class FakeTriggerer(trigger_gpu_test.GpuTestTriggerer):
-  def __init__(self, gpu_configs, bot_statuses,
+
+class FakeTriggerer(trigger_multiple_dimensions.MultiDimensionTestTriggerer):
+  def __init__(self, bot_configs, bot_statuses,
                use_superclass_random_number_generator, first_random_number):
     super(FakeTriggerer, self).__init__()
-    self._gpu_configs = gpu_configs
+    self._bot_configs = bot_configs
     self._bot_statuses = bot_statuses
     self._swarming_runs = []
     self._files = {}
@@ -50,10 +55,10 @@
   def write_json_to_file(self, merged_json, output_file):
     self._files[output_file] = merged_json
 
-  def parse_gpu_configs(self, args):
+  def parse_bot_configs(self, args):
     pass
 
-  def query_swarming_for_gpu_configs(self, verbose):
+  def query_swarming_for_bot_configs(self, verbose):
     # Sum up the total count of all bots.
     self._total_bots = sum(x['total'] for x in self._bot_statuses)
 
@@ -94,7 +99,7 @@
     # that produced by "swarming.py trigger". The unit tests only
     # verify that shard 0's JSON is preserved.
     triggerer.set_files({
-      'trigger_gpu_test0.json': {
+      'trigger_multiple_dimensions0.json': {
         'base_task_name': 'webgl_conformance_tests',
         'request': {
           'expiration_secs': 3600,
@@ -108,7 +113,7 @@
           },
         },
       },
-      'trigger_gpu_test1.json': {
+      'trigger_multiple_dimensions1.json': {
         'tasks': {
           'webgl_conformance_tests on NVIDIA GPU on Windows': {
             'task_id': 'f002',
@@ -119,7 +124,7 @@
     args = Args()
     args.shards = 2
     args.dump_json = 'output.json'
-    args.gpu_trigger_script_verbose = False
+    args.multiple_dimension_script_verbose = False
     triggerer.trigger_tasks(
       args,
       [
@@ -146,35 +151,26 @@
     return self.list_contains_sublist(triggerer._swarming_runs[shard_index],
                                       ['--dimension', 'os', os])
 
-  def test_swarming_py_filtering(self):
-    triggerer = trigger_gpu_test.GpuTestTriggerer()
-    full_args = ['--foo', '--swarming-py-path', 'bar', '--baz']
-    filtered_args = ['--foo', '--baz']
-    self.assertEqual(triggerer.filter_swarming_py_path_arg(full_args),
-                     filtered_args)
-    self.assertEqual(triggerer.filter_swarming_py_path_arg(filtered_args),
-                     filtered_args)
-
-  def test_parse_gpu_configs(self):
-    triggerer = trigger_gpu_test.GpuTestTriggerer()
+  def test_parse_bot_configs(self):
+    triggerer = trigger_multiple_dimensions.MultiDimensionTestTriggerer()
     args = Args()
-    args.gpu_trigger_configs = "{ foo }"
+    args.multiple_trigger_configs = "{ foo }"
     self.assertRaisesRegexp(ValueError, "Error while parsing JSON.*",
-                            triggerer.parse_gpu_configs, args)
-    args.gpu_trigger_configs = "{ \"foo\": \"bar\" }"
-    self.assertRaisesRegexp(ValueError, "GPU configurations must be a list.*",
-                            triggerer.parse_gpu_configs, args)
-    args.gpu_trigger_configs = "[]"
+                            triggerer.parse_bot_configs, args)
+    args.multiple_trigger_configs = "{ \"foo\": \"bar\" }"
+    self.assertRaisesRegexp(ValueError, "Bot configurations must be a list.*",
+                            triggerer.parse_bot_configs, args)
+    args.multiple_trigger_configs = "[]"
     self.assertRaisesRegexp(ValueError,
-                            "GPU configuration list must have at least.*",
-                            triggerer.parse_gpu_configs, args)
-    args.gpu_trigger_configs = "[{}, \"\"]"
+                            "Bot configuration list must have at least.*",
+                            triggerer.parse_bot_configs, args)
+    args.multiple_trigger_configs = "[{}, \"\"]"
     self.assertRaisesRegexp(ValueError,
-                            "GPU configurations must all be.*",
-                            triggerer.parse_gpu_configs, args)
-    args.gpu_trigger_configs = "[{}]"
-    triggerer.parse_gpu_configs(args)
-    self.assertEqual(triggerer._gpu_configs, [{}])
+                            "Bot configurations must all be.*",
+                            triggerer.parse_bot_configs, args)
+    args.multiple_trigger_configs = "[{}]"
+    triggerer.parse_bot_configs(args)
+    self.assertEqual(triggerer._bot_configs, [{}])
 
   def test_split_with_available_machines(self):
     triggerer = self.basic_win7_win10_setup(
@@ -309,7 +305,8 @@
 
   def test_superclass_random_number_generator_works(self):
     # Probe randomly a certain number of times.
-    for i in xrange(100):
+    num_runs = 0
+    for _ in xrange(100):
       triggerer = self.basic_win7_win10_setup(
         [
           {
@@ -323,9 +320,11 @@
         ],
         use_superclass_random_number_generator=True
       )
-      for s in xrange(2):
+      for _ in xrange(2):
         self.assertTrue(self.shard_runs_on_os(triggerer, 0, WIN7) or
                         self.shard_runs_on_os(triggerer, 0, WIN10))
+        num_runs += 1
+    self.assertEqual(num_runs, 200)
 
 if __name__ == '__main__':
   unittest.main()
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
index 6e9c340..8852e61e 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -24,11 +24,6 @@
 
 # Assert in ng_box_fragment_painter.cc(327)
 crbug.com/626703 fast/multicol/multicol-becomes-paged-auto-height.html [ Crash ]
-crbug.com/626703 fast/pagination/auto-height.html [ Crash ]
-crbug.com/626703 fast/pagination/caret-range-outside-paged-x-rtl-vertical-rl.html [ Crash ]
-crbug.com/626703 fast/pagination/caret-range-outside-paged-x-vertical-rl.html [ Crash ]
-crbug.com/626703 fast/pagination/first-letter-inherit-all-crash.html [ Crash ]
-crbug.com/626703 fast/parser/nested-fragment-parser-crash.html [ Crash ]
 
 # New passes
 crbug.com/626703 external/wpt/css/css-ui/text-overflow-021.html [ Failure ]
@@ -140,7 +135,7 @@
 crbug.com/591099 bindings/blink-in-js-asan-crash.html [ Failure ]
 crbug.com/714962 compositing/background-color/view-blending-base-background.html [ Failure ]
 crbug.com/591099 compositing/child-transform-layer-requires-box.html [ Failure ]
-crbug.com/591099 compositing/clip-path-with-composited-descendants.html [ Crash Failure ]
+crbug.com/591099 compositing/clip-path-with-composited-descendants.html [ Crash ]
 crbug.com/591099 compositing/compositing-visible-descendant.html [ Failure ]
 crbug.com/591099 compositing/contents-opaque/body-background-painted.html [ Failure ]
 crbug.com/591099 compositing/contents-opaque/body-background-skipped.html [ Failure ]
@@ -209,8 +204,8 @@
 crbug.com/591099 compositing/iframes/layout-on-compositing-change.html [ Failure ]
 crbug.com/591099 compositing/iframes/nested-iframe-scrolling.html [ Failure ]
 crbug.com/591099 compositing/images/direct-image-background-color.html [ Failure ]
-crbug.com/714962 compositing/images/direct-image-clip-path.html [ Crash Failure ]
-crbug.com/714962 compositing/images/direct-image-dynamic-clip-path.html [ Crash Failure ]
+crbug.com/714962 compositing/images/direct-image-clip-path.html [ Crash ]
+crbug.com/714962 compositing/images/direct-image-dynamic-clip-path.html [ Crash ]
 crbug.com/591099 compositing/images/direct-svg-image.html [ Failure ]
 crbug.com/591099 compositing/img-layer-object-fit.html [ Failure ]
 crbug.com/591099 compositing/layer-creation/fixed-position-nonscrollable-iframes-in-scrollable-page.html [ Failure ]
@@ -221,8 +216,8 @@
 crbug.com/591099 compositing/masks/mask-with-removed-filters.html [ Failure ]
 crbug.com/591099 compositing/masks/masked-ancestor.html [ Failure ]
 crbug.com/591099 compositing/massive-scale-interest-rect.html [ Failure ]
-crbug.com/591099 compositing/overflow/accelerated-scrolling-with-clip-path-text.html [ Crash Failure ]
-crbug.com/591099 compositing/overflow/accelerated-scrolling-with-clip-path.html [ Crash Failure ]
+crbug.com/591099 compositing/overflow/accelerated-scrolling-with-clip-path-text.html [ Crash ]
+crbug.com/591099 compositing/overflow/accelerated-scrolling-with-clip-path.html [ Crash ]
 crbug.com/591099 compositing/overflow/accelerated-scrolling-with-clip-reference.html [ Crash ]
 crbug.com/591099 compositing/overflow/ancestor-overflow.html [ Failure ]
 crbug.com/591099 compositing/overflow/ancestor-with-clip-path.html [ Crash ]
@@ -974,7 +969,6 @@
 crbug.com/591099 editing/inserting/4875189-2.html [ Failure ]
 crbug.com/591099 editing/inserting/4959067.html [ Failure ]
 crbug.com/591099 editing/inserting/4960120-1.html [ Failure ]
-crbug.com/591099 editing/inserting/4960120-2.html [ Failure Pass ]
 crbug.com/591099 editing/inserting/5002441.html [ Failure ]
 crbug.com/591099 editing/inserting/5058163-1.html [ Failure ]
 crbug.com/591099 editing/inserting/5058163-2.html [ Failure ]
@@ -997,6 +991,7 @@
 crbug.com/591099 editing/inserting/insert-space-in-empty-doc.html [ Failure ]
 crbug.com/591099 editing/inserting/insert-text-at-tabspan-001.html [ Failure ]
 crbug.com/591099 editing/inserting/insert-text-at-tabspan-003.html [ Failure ]
+crbug.com/591099 editing/inserting/insert_line_break_at_end_of_anonymous_block.html [ Failure Pass ]
 crbug.com/591099 editing/inserting/line-break.html [ Failure ]
 crbug.com/591099 editing/inserting/paragraph-separator-in-table-1.html [ Failure ]
 crbug.com/591099 editing/inserting/paragraph-separator-in-table-2.html [ Failure ]
@@ -1096,7 +1091,7 @@
 crbug.com/591099 editing/selection/extend-selection-bidi.html [ Failure ]
 crbug.com/591099 editing/selection/extend-selection-character.html [ Timeout ]
 crbug.com/591099 editing/selection/extend-selection-home-end.html [ Timeout ]
-crbug.com/591099 editing/selection/extend-selection-word.html [ Pass Timeout ]
+crbug.com/591099 editing/selection/extend-selection-word.html [ Timeout ]
 crbug.com/591099 editing/selection/focus-body.html [ Failure ]
 crbug.com/591099 editing/selection/home-end.html [ Timeout ]
 crbug.com/591099 editing/selection/inactive-selection.html [ Failure ]
@@ -1113,7 +1108,6 @@
 crbug.com/591099 editing/selection/mixed-editability-5.html [ Failure ]
 crbug.com/591099 editing/selection/mixed-editability-6.html [ Failure ]
 crbug.com/591099 editing/selection/mixed-editability-7.html [ Failure ]
-crbug.com/591099 editing/selection/mixed-editability-8.html [ Failure Pass ]
 crbug.com/591099 editing/selection/mixed-editability-9.html [ Failure ]
 crbug.com/591099 editing/selection/modify_extend/extend_by_character.html [ Failure ]
 crbug.com/714962 editing/selection/modify_extend/extend_forward_line_crash.html [ Failure ]
@@ -1251,7 +1245,7 @@
 crbug.com/714962 external/wpt/css/css-backgrounds/background-attachment-local/attachment-local-clipping-image-5.html [ Failure ]
 crbug.com/714962 external/wpt/css/css-backgrounds/background-image-003.html [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-backgrounds/background-image-004.html [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-backgrounds/background-image-005.html [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-backgrounds/background-image-005.html [ Failure ]
 crbug.com/714962 external/wpt/css/css-backgrounds/background-image-006.html [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-display/display-contents-details.html [ Crash ]
 crbug.com/714962 external/wpt/css/css-display/display-contents-dynamic-before-after-001.html [ Failure ]
@@ -1637,11 +1631,11 @@
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-053.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-055.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-057.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-059.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-059.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-061.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-063.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-065.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-067.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-067.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-069.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-071.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-073.xht [ Failure Pass ]
@@ -1649,7 +1643,7 @@
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-077.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-079.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-081.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-083.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-083.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-085.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-087.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-089.xht [ Failure ]
@@ -1666,7 +1660,7 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-115.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-117.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-119.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-121.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-121.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-123.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-125.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-127.xht [ Failure ]
@@ -1677,11 +1671,11 @@
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-137.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-139.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-141.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-143.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-143.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-145.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-147.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-149.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-151.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-149.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-151.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-153.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-155.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-157.xht [ Failure ]
@@ -1714,9 +1708,9 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-211.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-213.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-215.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-217.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-217.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-219.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-221.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-221.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-223.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-225.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-227.xht [ Failure ]
@@ -1751,7 +1745,7 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-056.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-058.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-060.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-062.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-062.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-064.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-066.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-068.xht [ Failure Pass ]
@@ -1764,7 +1758,7 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-082.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-084.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-086.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-088.xht [ Failure ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-088.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-090.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-092.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-094.xht [ Failure ]
@@ -1822,7 +1816,7 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-202.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-204.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-206.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-208.xht [ Failure Pass ]
+crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-208.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-210.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-212.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-214.xht [ Failure ]
@@ -1852,7 +1846,7 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/clearance-calculations-vrl-008.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/direction-vlr-003.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/direction-vlr-005.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/direction-vrl-002.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/direction-vrl-002.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/direction-vrl-004.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/float-contiguous-vrl-002.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/float-contiguous-vrl-004.xht [ Failure ]
@@ -1927,9 +1921,9 @@
 crbug.com/591099 external/wpt/css/css-writing-modes/table-column-order-004.xht [ Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/table-column-order-005.xht [ Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-003.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-005.xht [ Failure Pass ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-005.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-007.xht [ Failure ]
-crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-009.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-009.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-align-vlr-011.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-013.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-015.xht [ Failure Pass ]
@@ -1942,7 +1936,7 @@
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-010.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-012.xht [ Failure ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-014.xht [ Failure Pass ]
-crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-016.xht [ Failure ]
+crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-016.xht [ Failure Pass ]
 crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-018.xht [ Failure Pass ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-baseline-vlr-007.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/text-baseline-vrl-006.xht [ Failure ]
@@ -2283,7 +2277,7 @@
 crbug.com/591099 external/wpt/wasm/wasm_local_iframe_test.html [ Failure ]
 crbug.com/591099 external/wpt/webmessaging/broadcastchannel/sandbox.html [ Failure ]
 crbug.com/591099 external/wpt/webrtc/interfaces.html [ Pass Timeout ]
-crbug.com/591099 external/wpt/webrtc/interfaces.https.html [ Pass Timeout ]
+crbug.com/591099 external/wpt/webrtc/interfaces.https.html [ Timeout ]
 crbug.com/591099 external/wpt/websockets/binary/001.html?wss [ Pass ]
 crbug.com/591099 external/wpt/websockets/binary/002.html?wss [ Pass ]
 crbug.com/591099 external/wpt/websockets/binary/004.html?wss [ Pass ]
@@ -3234,7 +3228,7 @@
 crbug.com/591099 fast/events/keydown-keypress-preventDefault.html [ Failure ]
 crbug.com/591099 fast/events/keypress-focus-change.html [ Failure ]
 crbug.com/591099 fast/events/media-element-focus-tab.html [ Failure ]
-crbug.com/714962 fast/events/middleClickAutoscroll-latching.html [ Pass Timeout ]
+crbug.com/714962 fast/events/middleClickAutoscroll-latching.html [ Timeout ]
 crbug.com/714962 fast/events/mouse-down-on-pseudo-element-remove-crash.html [ Failure ]
 crbug.com/591099 fast/events/mouse-drag-from-frame-to-other-frame.html [ Failure ]
 crbug.com/591099 fast/events/mouse-event-buttons-attribute.html [ Timeout ]
@@ -4365,8 +4359,11 @@
 crbug.com/591099 fast/overflow/scrollbar-restored-and-then-locked.html [ Failure ]
 crbug.com/591099 fast/overflow/scrollbar-restored.html [ Failure ]
 crbug.com/591099 fast/pagination/auto-height-with-break.html [ Failure ]
+crbug.com/591099 fast/pagination/auto-height.html [ Crash ]
 crbug.com/591099 fast/pagination/break-in-paged-overflow.html [ Failure ]
+crbug.com/591099 fast/pagination/caret-range-outside-paged-x-rtl-vertical-rl.html [ Crash ]
 crbug.com/591099 fast/pagination/caret-range-outside-paged-x-rtl.html [ Failure ]
+crbug.com/591099 fast/pagination/caret-range-outside-paged-x-vertical-rl.html [ Crash ]
 crbug.com/591099 fast/pagination/caret-range-outside-paged-x.html [ Failure ]
 crbug.com/591099 fast/pagination/caret-range-outside-paged-y-rtl-vertical-rl.html [ Failure ]
 crbug.com/714962 fast/pagination/caret-range-outside-paged-y-rtl.html [ Failure ]
@@ -4382,6 +4379,7 @@
 crbug.com/591099 fast/pagination/div-y-vertical-lr-rtl.html [ Failure ]
 crbug.com/591099 fast/pagination/div-y-vertical-rl-ltr.html [ Failure ]
 crbug.com/591099 fast/pagination/div-y-vertical-rl-rtl.html [ Failure ]
+crbug.com/591099 fast/pagination/first-letter-inherit-all-crash.html [ Crash ]
 crbug.com/591099 fast/pagination/modal-dialog-crash.html [ Crash ]
 crbug.com/591099 fast/pagination/multicol.html [ Failure ]
 crbug.com/591099 fast/pagination/paged-x-column-gap.html [ Failure ]
@@ -4402,6 +4400,7 @@
 crbug.com/591099 fast/parser/entity-comment-in-style.html [ Failure ]
 crbug.com/591099 fast/parser/entity-comment-in-textarea.html [ Failure ]
 crbug.com/591099 fast/parser/fonts.html [ Failure ]
+crbug.com/591099 fast/parser/nested-fragment-parser-crash.html [ Crash ]
 crbug.com/591099 fast/parser/nofoo-tags-inside-paragraph.html [ Failure ]
 crbug.com/591099 fast/parser/noscript-with-javascript-disabled.html [ Failure ]
 crbug.com/591099 fast/parser/open-comment-in-style.html [ Failure ]
@@ -5211,15 +5210,12 @@
 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/animation/animation-KeyframeEffectReadOnly-crash.js [ Crash Pass ]
 crbug.com/714962 http/tests/devtools/animation/animation-group-matching-animations.js [ Crash ]
 crbug.com/714962 http/tests/devtools/animation/animation-group-matching-transitions.js [ Crash ]
-crbug.com/591099 http/tests/devtools/animation/animation-timeline.js [ Crash Pass ]
 crbug.com/591099 http/tests/devtools/console/console-functions.js [ Failure ]
 crbug.com/591099 http/tests/devtools/console/console-search.js [ Timeout ]
 crbug.com/591099 http/tests/devtools/console/console-uncaught-promise.js [ Failure ]
 crbug.com/591099 http/tests/devtools/console/console-viewport-control.js [ Failure ]
-crbug.com/591099 http/tests/devtools/console/shadow-element.js [ Crash Pass ]
 crbug.com/591099 http/tests/devtools/editor/text-editor-ctrl-d-1.js [ Timeout ]
 crbug.com/591099 http/tests/devtools/editor/text-editor-ctrl-d-2.js [ Timeout ]
 crbug.com/714962 http/tests/devtools/editor/text-editor-enter-behaviour.js [ Timeout ]
@@ -5245,7 +5241,6 @@
 crbug.com/714962 http/tests/devtools/elements/edit/undo-dom-edits.js [ Crash ]
 crbug.com/714962 http/tests/devtools/elements/edit/undo-set-outer-html-2.js [ Crash ]
 crbug.com/591099 http/tests/devtools/elements/edit/undo-set-outer-html.js [ Crash Pass ]
-crbug.com/591099 http/tests/devtools/elements/elements-delete-inline-style.js [ Crash Pass ]
 crbug.com/591099 http/tests/devtools/elements/elements-inspect-iframe-from-different-domain.js [ Pass ]
 crbug.com/714962 http/tests/devtools/elements/elements-linkify-attributes.js [ Crash Pass ]
 crbug.com/591099 http/tests/devtools/elements/elements-panel-limited-children.js [ Crash ]
@@ -5259,7 +5254,7 @@
 crbug.com/591099 http/tests/devtools/elements/event-listener-sidebar-remove.js [ Crash Pass ]
 crbug.com/591099 http/tests/devtools/elements/event-listener-sidebar.js [ Crash Pass ]
 crbug.com/591099 http/tests/devtools/elements/event-listeners-about-blank.js [ Crash Pass ]
-crbug.com/714962 http/tests/devtools/elements/hide-shortcut.js [ Crash Pass ]
+crbug.com/714962 http/tests/devtools/elements/hide-shortcut.js [ Crash ]
 crbug.com/591099 http/tests/devtools/elements/highlight/highlight-css-shapes-outside-scroll.js [ Failure ]
 crbug.com/591099 http/tests/devtools/elements/highlight/highlight-css-shapes-outside.js [ Failure ]
 crbug.com/714962 http/tests/devtools/elements/highlight/highlight-dom-updates.js [ Crash ]
@@ -5268,7 +5263,6 @@
 crbug.com/714962 http/tests/devtools/elements/inspect-pseudo-element.js [ Timeout ]
 crbug.com/714962 http/tests/devtools/elements/modify-chardata.js [ Crash Pass ]
 crbug.com/714962 http/tests/devtools/elements/shadow/create-shadow-root.js [ Crash ]
-crbug.com/714962 http/tests/devtools/elements/shadow/inspect-deep-shadow-element.js [ Crash Pass ]
 crbug.com/714962 http/tests/devtools/elements/shadow/shadow-distribution.js [ Crash ]
 crbug.com/714962 http/tests/devtools/elements/shadow/shadow-host-display-modes.js [ Crash ]
 crbug.com/714962 http/tests/devtools/elements/styles-1/add-new-rule-with-style-after-body.js [ Crash Pass ]
@@ -5295,13 +5289,12 @@
 crbug.com/714962 http/tests/devtools/elements/styles-4/undo-add-new-rule.js [ Crash ]
 crbug.com/714962 http/tests/devtools/elements/styles-4/undo-add-property.js [ Crash ]
 crbug.com/591099 http/tests/devtools/elements/styles/styles-mouse-test.js [ Failure ]
-crbug.com/714962 http/tests/devtools/elements/styles/stylesheet-tracking.js [ Crash ]
+crbug.com/714962 http/tests/devtools/elements/styles/stylesheet-tracking.js [ Crash Pass ]
 crbug.com/714962 http/tests/devtools/elements/styles/undo-change-property.js [ Crash Pass ]
 crbug.com/714962 http/tests/devtools/elements/styles/undo-property-toggle.js [ Crash Pass ]
 crbug.com/714962 http/tests/devtools/elements/styles/undo-set-selector-text.js [ Crash ]
 crbug.com/591099 http/tests/devtools/extensions/extensions-sidebar.js [ Crash ]
 crbug.com/591099 http/tests/devtools/indexeddb/resources-panel.js [ Failure ]
-crbug.com/591099 http/tests/devtools/inspect-element.js [ Crash Pass ]
 crbug.com/714962 http/tests/devtools/jump-to-previous-editing-location.js [ Failure ]
 crbug.com/714962 http/tests/devtools/layers/layer-canvas-log.js [ Failure ]
 crbug.com/591099 http/tests/devtools/network/network-datareceived.js [ Failure ]
@@ -5321,7 +5314,7 @@
 crbug.com/591099 http/tests/devtools/sources/debugger-step/debugger-step-out-custom-element-callbacks.js [ Crash Pass ]
 crbug.com/591099 http/tests/devtools/sources/debugger-step/debugger-step-out-event-listener.js [ Crash Pass ]
 crbug.com/591099 http/tests/devtools/sources/debugger-ui/debugger-inline-values.js [ Crash ]
-crbug.com/591099 http/tests/devtools/sources/debugger-ui/watch-expressions-panel-switch.js [ Crash Pass ]
+crbug.com/591099 http/tests/devtools/sources/debugger-ui/watch-expressions-panel-switch.js [ Crash ]
 crbug.com/591099 http/tests/devtools/text-autosizing-override.js [ Failure ]
 crbug.com/591099 http/tests/devtools/tracing/scroll-invalidations.js [ Failure ]
 crbug.com/591099 http/tests/devtools/tracing/timeline-misc/timeline-bound-function.js [ Failure ]
@@ -5583,7 +5576,7 @@
 crbug.com/591099 images/webp-flip.html [ Failure ]
 crbug.com/591099 inspector-protocol/accessibility/accessibility-ignoredNodes.js [ Timeout ]
 crbug.com/714962 inspector-protocol/accessibility/accessibility-ignoredNodesModal.js [ Failure ]
-crbug.com/591099 inspector-protocol/accessibility/accessibility-nameSources-img-figure.js [ Pass Timeout ]
+crbug.com/591099 inspector-protocol/accessibility/accessibility-nameSources-img-figure.js [ Timeout ]
 crbug.com/591099 inspector-protocol/accessibility/accessibility-nameSources-input-buttons.js [ Timeout ]
 crbug.com/591099 inspector-protocol/accessibility/accessibility-nameSources-input.js [ Timeout ]
 crbug.com/591099 inspector-protocol/accessibility/accessibility-nameSources-labelledby.js [ Timeout ]
@@ -5646,7 +5639,7 @@
 crbug.com/591099 overflow/overflow-position-003.html [ Failure ]
 crbug.com/714962 paint/clipath/clip-path-bigger-than-border-box-visual-rect.html [ Failure ]
 crbug.com/714962 paint/clipath/clip-path-bigger-than-visual-overflow.html [ Failure ]
-crbug.com/591099 paint/clipath/clip-path-with-background-and-box-behind.html [ Crash Failure ]
+crbug.com/591099 paint/clipath/clip-path-with-background-and-box-behind.html [ Crash ]
 crbug.com/591099 paint/filters/clip-filter-overflow-clip.html [ Failure ]
 crbug.com/714962 paint/float/float-text-clip.html [ Crash ]
 crbug.com/591099 paint/frames/frameset-with-stacking-context-and-not-stacking-context-children.html [ Failure ]
@@ -6453,7 +6446,7 @@
 crbug.com/714962 svg/W3C-SVG-1.1/filters-light-04-f.svg [ Failure ]
 crbug.com/714962 svg/W3C-SVG-1.1/filters-turb-02-f.svg [ Failure ]
 crbug.com/714962 svg/W3C-SVG-1.1/masking-intro-01-f.svg [ Failure ]
-crbug.com/714962 svg/W3C-SVG-1.1/masking-mask-01-b.svg [ Failure ]
+crbug.com/714962 svg/W3C-SVG-1.1/masking-mask-01-b.svg [ Failure Pass ]
 crbug.com/714962 svg/W3C-SVG-1.1/masking-opacity-01-b.svg [ Failure ]
 crbug.com/714962 svg/W3C-SVG-1.1/masking-path-01-b.svg [ Failure ]
 crbug.com/714962 svg/W3C-SVG-1.1/masking-path-02-b.svg [ Failure ]
@@ -6597,6 +6590,7 @@
 crbug.com/591099 svg/custom/getscreenctm-in-scrollable-div-area-nested.xhtml [ Failure ]
 crbug.com/591099 svg/custom/getscreenctm-in-scrollable-div-area.xhtml [ Failure ]
 crbug.com/591099 svg/custom/getsvgdocument.html [ Failure ]
+crbug.com/591099 svg/custom/grayscale-gradient-mask.svg [ Failure ]
 crbug.com/714962 svg/custom/group-opacity.svg [ Failure ]
 crbug.com/591099 svg/custom/hit-test-path-stroke.svg [ Failure ]
 crbug.com/591099 svg/custom/hit-test-path.svg [ Failure ]
@@ -6654,13 +6648,13 @@
 crbug.com/714962 svg/dynamic-updates/SVG-dynamic-css-transform.html [ Failure ]
 crbug.com/714962 svg/dynamic-updates/SVGMaskElement-dom-height-attr.html [ Failure ]
 crbug.com/714962 svg/dynamic-updates/SVGMaskElement-dom-maskContentUnits-attr.html [ Failure ]
-crbug.com/714962 svg/dynamic-updates/SVGMaskElement-dom-maskUnits-attr.html [ Failure ]
+crbug.com/714962 svg/dynamic-updates/SVGMaskElement-dom-maskUnits-attr.html [ Failure Pass ]
 crbug.com/714962 svg/dynamic-updates/SVGMaskElement-dom-width-attr.html [ Failure ]
 crbug.com/714962 svg/dynamic-updates/SVGMaskElement-dom-x-attr.html [ Failure ]
 crbug.com/714962 svg/dynamic-updates/SVGMaskElement-dom-y-attr.html [ Failure ]
 crbug.com/714962 svg/dynamic-updates/SVGMaskElement-svgdom-height-prop.html [ Failure ]
 crbug.com/714962 svg/dynamic-updates/SVGMaskElement-svgdom-maskContentUnits-prop.html [ Failure ]
-crbug.com/714962 svg/dynamic-updates/SVGMaskElement-svgdom-maskUnits-prop.html [ Failure ]
+crbug.com/714962 svg/dynamic-updates/SVGMaskElement-svgdom-maskUnits-prop.html [ Failure Pass ]
 crbug.com/714962 svg/dynamic-updates/SVGMaskElement-svgdom-width-prop.html [ Failure ]
 crbug.com/714962 svg/dynamic-updates/SVGMaskElement-svgdom-x-prop.html [ Failure ]
 crbug.com/714962 svg/dynamic-updates/SVGMaskElement-svgdom-y-prop.html [ Failure ]
@@ -6702,7 +6696,7 @@
 crbug.com/591099 svg/overflow/overflow-on-outermost-svg-element-in-xhtml-scroll.xhtml [ Failure ]
 crbug.com/591099 svg/overflow/overflow-on-outermost-svg-element-in-xhtml-visible.xhtml [ Failure ]
 crbug.com/591099 svg/parser/whitespace-length-invalid-1.html [ Pass Timeout ]
-crbug.com/591099 svg/parser/whitespace-length-invalid-2.html [ Pass Timeout ]
+crbug.com/591099 svg/parser/whitespace-length-invalid-2.html [ Timeout ]
 crbug.com/591099 svg/parser/whitespace-length-invalid-3.html [ Pass Timeout ]
 crbug.com/591099 svg/parser/whitespace-length-invalid-4.html [ Pass Timeout ]
 crbug.com/591099 svg/parser/whitespace-number.html [ Timeout ]
@@ -6806,7 +6800,7 @@
 crbug.com/591099 tables/mozilla/bugs/bug27038-1.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug27038-2.html [ Failure ]
 crbug.com/714962 tables/mozilla/bugs/bug2757.html [ Failure ]
-crbug.com/714962 tables/mozilla/bugs/bug2886-2.html [ Failure ]
+crbug.com/591099 tables/mozilla/bugs/bug2886-2.html [ Failure ]
 crbug.com/714962 tables/mozilla/bugs/bug2947.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug2962.html [ Failure ]
 crbug.com/591099 tables/mozilla/bugs/bug2973.html [ Failure ]
@@ -7094,7 +7088,7 @@
 crbug.com/591099 virtual/gpu-rasterization/images/webp-flip.html [ Failure ]
 crbug.com/591099 virtual/gpu/fast/canvas/canvas-createImageBitmap-colorClamping.html [ Pass ]
 crbug.com/591099 virtual/gpu/fast/canvas/canvas-createImageBitmap-recursive.html [ Pass Timeout ]
-crbug.com/714962 virtual/gpu/fast/canvas/canvas-css-clip-path.html [ Crash Failure ]
+crbug.com/714962 virtual/gpu/fast/canvas/canvas-css-clip-path.html [ Crash ]
 crbug.com/591099 virtual/gpu/fast/canvas/canvas-drawImage-animated-images.html [ Failure ]
 crbug.com/591099 virtual/gpu/fast/canvas/canvas-drawImage-video-imageSmoothingEnabled.html [ Pass ]
 crbug.com/591099 virtual/gpu/fast/canvas/canvas-filter-units-em-liveness.html [ Pass Timeout ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v175 b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v175
index 999d37c..85cefdcf 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v175
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v175
@@ -1,6 +1,5 @@
 # Skip tests that we are running under virtual/spv175
 Bug(none) compositing/ [ Skip ]
-Bug(none) virtual/prefer_compositing_to_lcd_text/compositing [ Skip ]
 Bug(none) paint/ [ Skip ]
 Bug(none) fast/borders/ [ Skip ]
 Bug(none) fast/multicol/ [ Skip ]
@@ -87,21 +86,21 @@
 crbug.com/769942 fast/clip/clip-path-inline-element-crash.html [ Skip ]
 crbug.com/769942 hittesting/image-with-clip-path.html [ Skip ]
 crbug.com/769942 virtual/gpu/fast/canvas/canvas-css-clip-path.html [ Skip ]
+crbug.com/769942 virtual/prefer_compositing_to_lcd_text/compositing/overflow/accelerated-scrolling-with-clip-path-text.html [ Skip ]
+crbug.com/769942 virtual/prefer_compositing_to_lcd_text/compositing/overflow/accelerated-scrolling-with-clip-path.html [ Skip ]
+crbug.com/769942 virtual/prefer_compositing_to_lcd_text/compositing/overflow/accelerated-scrolling-with-clip-reference.html [ Skip ]
+crbug.com/769942 virtual/prefer_compositing_to_lcd_text/compositing/overflow/ancestor-with-clip-path.html [ Skip ]
+crbug.com/769942 virtual/prefer_compositing_to_lcd_text/compositing/overflow/descendant-with-clip-path.html [ Skip ]
 
 # Subpixel differences
 crbug.com/771643 external/wpt/css/css-backgrounds/background-attachment-local/attachment-local-clipping-color-5.html [ Failure ]
 crbug.com/771643 external/wpt/css/css-backgrounds/background-attachment-local/attachment-local-clipping-image-5.html [ Failure ]
 # This will pass with --root-layer-scrolls.
 crbug.com/771643 scrollbars/custom-scrollbars-paint-outside-iframe.html [ Failure ]
-# A few (sub?)-pixels clipped off.
-crbug.com/771643 svg/as-background-image/svg-as-background-6.html [ Failure ]
-# Mask clip issue.
-crbug.com/771643 svg/batik/masking/maskRegions.svg [ Failure ]
-crbug.com/771643 svg/zoom/page/zoom-mask-with-percentages.svg [ Failure ]
-# Incorect LocalBorderBoxProperties for absolute-pos under transformed table section. 
-crbug.com/771643 tables/table-transform-absolute-position-child.html [ Failure ]
 # Others.
 crbug.com/771643 virtual/threaded/printing/fixed-positioned-scrolled.html [ Failure ]
+# Difficult ancestor clip mask issue.
+crbug.com/771643 virtual/prefer_compositing_to_lcd_text/compositing/overflow/nested-border-radius-clipping.html [ Failure ]
 
 crbug.com/805134 http/tests/devtools/tracing/scroll-invalidations.js [ Failure ]
 crbug.com/805134 virtual/threaded/http/tests/devtools/tracing/scroll-invalidations.js [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/MSANExpectations b/third_party/WebKit/LayoutTests/MSANExpectations
index 9ce4faf..55fac30 100644
--- a/third_party/WebKit/LayoutTests/MSANExpectations
+++ b/third_party/WebKit/LayoutTests/MSANExpectations
@@ -35,7 +35,7 @@
 # Times out on MSAN
 crbug.com/462190 [ Linux ] inspector-protocol/heap-profiler/heap-samples-in-snapshot.js [ Timeout ]
 crbug.com/462190 [ Linux ] inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object.js [ Timeout ]
-crbug.com/462190 [ Linux ] inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree.js [ Timeout ]
+crbug.com/462190 [ Linux ] inspector-protocol/heap-profiler/heap-snapshot-with-iframe.js [ Timeout ]
 crbug.com/462190 [ Linux ] inspector-protocol/heap-profiler/heap-snapshot-with-event-listener.js [ Timeout ]
 
 crbug.com/667560 [ Linux ] http/tests/devtools/startup/console/console-format-startup.js [ Timeout Pass ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 3323699..b9de5ad 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -84,11 +84,8 @@
 crbug.com/769942 virtual/spv175/paint/invalidation/clip/clip-path-constant-repaint.html [ Skip ]
 
 crbug.com/771643 virtual/spv175/compositing/overflow/nested-border-radius-clipping.html [ Failure ]
-crbug.com/771643 virtual/spv175/fast/multicol/border-radius-clipped-layer.html [ Failure ]
-crbug.com/771643 virtual/spv175/fast/multicol/mixed-opacity-test.html [ Failure ]
-crbug.com/771643 virtual/spv175/fast/multicol/multicol-svg.html [ Failure ]
-crbug.com/771643 virtual/spv175/paint/invalidation/svg/absolute-sized-content-with-resources.xhtml [ Failure ]
-
+crbug.com/807395 virtual/spv175/fast/multicol/mixed-opacity-test.html [ Failure ]
+crbug.com/807382 virtual/spv175/fast/multicol/multicol-svg.html [ Failure ]
 crbug.com/805049 [ Mac ] virtual/spv175/compositing/iframes/fixed-position-iframe.html [ Pass Crash ]
 
 # spv175+root-layer-scrolls failures. They also fail with root-layer-scrolls without enable-slimming-paint-v175.
@@ -1732,9 +1729,6 @@
 crbug.com/803200 external/wpt/websockets/cookies/006.html?wss [ Failure ]
 crbug.com/803200 external/wpt/websockets/opening-handshake/005.html?wss [ Pass Failure ]
 
-# DCHECK failure.
-crbug.com/805061 external/wpt/custom-elements/upgrading/Node-cloneNode.html [ Crash ]
-
 crbug.com/805463 external/wpt/acid/acid3/numbered-tests.html [ Skip ]
 
 # ====== New tests from wpt-importer added here ======
@@ -2233,6 +2227,9 @@
 crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/margin-collapsing-quirks/multicol-quirks-mode.html [ Pass Crash ]
 crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/margin-collapsing-quirks/multicol-standards-mode.html [ Pass Crash Failure ]
 crbug.com/762017 external/wpt/html/semantics/embedded-content/media-elements/video_loop_base.html [ Pass Crash ]
+crbug.com/805061 external/wpt/custom-elements/upgrading/Node-cloneNode.html [ Crash ]
+crbug.com/807954 external/wpt/service-workers/service-worker/fetch-event-respond-with-readable-stream-chunk.https.html [ Crash ]
+crbug.com/807954 virtual/outofblink-cors/external/wpt/service-workers/service-worker/fetch-event-respond-with-readable-stream-chunk.https.html [ Crash ]
 
 # Other untriaged test failures, timeouts and crashes from newly-imported WPT tests.
 crbug.com/666703 external/wpt/html/browsers/sandboxing/sandbox-disallow-same-origin.html [ Timeout ]
@@ -3324,7 +3321,3 @@
 crbug.com/806748 [ Win7 ] virtual/mouseevent_fractional/fast/events/touch/gesture/gesture-tap-hover-state-iframe.html [ Pass Failure ]
 # Flaky on Linux
 crbug.com/806017 [ Linux ] virtual/gpu/fast/canvas/canvas-strokePath-shadow.html [ Pass Timeout ]
-
-# Sheriff failures 2018-01-31
-# Failing on Windows, Mac, Linux Trusty.
-crbug.com/807791 [ Mac Linux Win ] external/wpt/html/dom/interfaces.html [ Pass Failure ]
diff --git a/third_party/WebKit/LayoutTests/bindings/idl-dictionary-unittest-expected.txt b/third_party/WebKit/LayoutTests/bindings/idl-dictionary-unittest-expected.txt
index 579aa207..118e3705 100644
--- a/third_party/WebKit/LayoutTests/bindings/idl-dictionary-unittest-expected.txt
+++ b/third_party/WebKit/LayoutTests/bindings/idl-dictionary-unittest-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE WARNING: line 234: 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
+CONSOLE WARNING: line 266: 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
 IDL dictionary unittest
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
@@ -29,6 +29,7 @@
 PASS dict.doubleOrStringMember is undefined.
 PASS dict.doubleOrStringSequenceMember is undefined.
 PASS dict.eventTargetOrNullMember is null
+PASS dict.anyMember is undefined.
 
 Test for setting undefined
 PASS dict.longMember is undefined.
@@ -50,6 +51,7 @@
 PASS dict.objectMember is undefined.
 PASS dict.objectOrNullMemberWithDefault is null
 PASS dict.eventTargetOrNullMember is null
+PASS dict.anyMember is undefined.
 
 Test for setting valid values
 PASS dict.longMember is 1
@@ -77,6 +79,7 @@
 PASS dict.doubleOrStringSequenceMember is [3.14, "Hello"]
 PASS dict.eventTargetOrNullMember is element1
 PASS dict.internalEnumOrInternalEnumSequenceMember is "foo"
+PASS dict.anyMember is 42
 
 Additional test for union type members
 PASS dict.doubleOrStringMember is "foo"
@@ -92,6 +95,13 @@
 PASS dict.longOrNullMember is null
 PASS dict.longOrNullMemberWithDefault is null
 
+Test for different values for the any type
+PASS dict.anyMember is ""
+PASS dict.anyMember is 0
+PASS dict.anyMember is undefined.
+PASS dict.anyMember is false
+PASS dict.anyMember is null
+
 Test for setting invalid member
 PASS dict.invalidMember is undefined.
 
diff --git a/third_party/WebKit/LayoutTests/bindings/idl-dictionary-unittest.html b/third_party/WebKit/LayoutTests/bindings/idl-dictionary-unittest.html
index 76cfc00..3c9d778c 100644
--- a/third_party/WebKit/LayoutTests/bindings/idl-dictionary-unittest.html
+++ b/third_party/WebKit/LayoutTests/bindings/idl-dictionary-unittest.html
@@ -36,6 +36,7 @@
     shouldBeUndefined('dict.doubleOrStringMember');
     shouldBeUndefined('dict.doubleOrStringSequenceMember');
     shouldBeNull('dict.eventTargetOrNullMember');
+    shouldBeUndefined('dict.anyMember');
     debug('');
 
     debug('Test for setting undefined');
@@ -60,6 +61,7 @@
     shouldBeUndefined('dict.objectMember');
     shouldBeNull('dict.objectOrNullMemberWithDefault');
     shouldBeNull('dict.eventTargetOrNullMember');
+    shouldBeUndefined('dict.anyMember');
     debug('');
 
     var element1 = document.createElement('div');
@@ -91,6 +93,7 @@
         doubleOrStringSequenceMember: [3.14, 'Hello'],
         eventTargetOrNullMember: element1,
         internalEnumOrInternalEnumSequenceMember: 'foo',
+        anyMember: 42
     });
     dict = dictionaryTest.get();
     shouldBe('dict.longMember', '1');
@@ -119,6 +122,7 @@
     shouldBe('dict.doubleOrStringSequenceMember', '[3.14, "Hello"]');
     shouldBe('dict.eventTargetOrNullMember', 'element1');
     shouldBeEqualToString('dict.internalEnumOrInternalEnumSequenceMember', 'foo');
+    shouldBe('dict.anyMember', '42');
     debug('');
 
     debug('Additional test for union type members');
@@ -172,6 +176,34 @@
     shouldBeNull('dict.longOrNullMemberWithDefault');
     debug('');
 
+    debug('Test for different values for the any type');
+    dictionaryTest.set({
+        anyMember: '',
+    });
+    dict = dictionaryTest.get();
+    shouldBeEmptyString('dict.anyMember');
+    dictionaryTest.set({
+        anyMember: 0,
+    });
+    dict = dictionaryTest.get();
+    shouldBeZero('dict.anyMember');
+    dictionaryTest.set({
+        anyMember: undefined,
+    });
+    dict = dictionaryTest.get();
+    shouldBeUndefined('dict.anyMember');
+    dictionaryTest.set({
+        anyMember: false,
+    });
+    dict = dictionaryTest.get();
+    shouldBeFalse('dict.anyMember');
+    dictionaryTest.set({
+        anyMember: null,
+    });
+    dict = dictionaryTest.get();
+    shouldBeNull('dict.anyMember');
+    debug('');
+
     debug('Test for setting invalid member');
     dictionaryTest.set({invalidMember: 'shouldNotBeSet'});
     dict = dictionaryTest.get();
diff --git a/third_party/WebKit/LayoutTests/css3/font-feature-settings-parsing-expected.txt b/third_party/WebKit/LayoutTests/css3/font-feature-settings-parsing-expected.txt
index 4b59cfe..9c5c493 100644
--- a/third_party/WebKit/LayoutTests/css3/font-feature-settings-parsing-expected.txt
+++ b/third_party/WebKit/LayoutTests/css3/font-feature-settings-parsing-expected.txt
@@ -5,16 +5,16 @@
 
 - Tests valid inputs.
 PASS parseResultOf("valid_normal") is "normal"
-PASS parseResultOf("valid_value_1") is "\"dlig\" 1"
+PASS parseResultOf("valid_value_1") is "\"dlig\""
 PASS parseResultOf("valid_value_2") is "\"swsh\" 2"
-PASS parseResultOf("valid_value_on") is "\"smcp\" 1"
+PASS parseResultOf("valid_value_on") is "\"smcp\""
 PASS parseResultOf("valid_value_off") is "\"liga\" 0"
-PASS parseResultOf("valid_value_omit") is "\"c2sc\" 1"
-PASS parseResultOf("valid_valuelist") is "\"tnum\" 1, \"hist\" 1"
-PASS parseResultOf("valid_singlequote") is "\"PKRN\" 1"
-PASS parseResultOf("valid_unusual_tag") is "\"!@#$\" 1"
-PASS parseResultOf("valid_tag_space") is "\"a bc\" 1"
-PASS parseResultOf("valid_composite") is "\"dlig\" 1, \"smcp\" 1, \"lig \" 0"
+PASS parseResultOf("valid_value_omit") is "\"c2sc\""
+PASS parseResultOf("valid_valuelist") is "\"tnum\", \"hist\""
+PASS parseResultOf("valid_singlequote") is "\"PKRN\""
+PASS parseResultOf("valid_unusual_tag") is "\"!@#$\""
+PASS parseResultOf("valid_tag_space") is "\"a bc\""
+PASS parseResultOf("valid_composite") is "\"dlig\", \"smcp\", \"lig \" 0"
 - Tests invalid inputs.  Results should be "normal".
 PASS parseResultOf("invalid_ident") is "normal"
 PASS parseResultOf("invalid_cases") is "normal"
@@ -34,10 +34,10 @@
 PASS parseResultOf("invalid_on") is "normal"
 PASS parseResultOf("invalid_0") is "normal"
 - Tests inherit.
-PASS parseResultOf("outer") is "\"dlig\" 1"
-PASS parseResultOf("inner") is "\"dlig\" 1"
+PASS parseResultOf("outer") is "\"dlig\""
+PASS parseResultOf("inner") is "\"dlig\""
 - Tests @font-face.
-PASS fontFaceRuleValid is "\"liga\" 1"
+PASS fontFaceRuleValid is "\"liga\""
 PASS fontFaceRuleInvalid is ""
 PASS successfullyParsed is true
 
diff --git a/third_party/WebKit/LayoutTests/css3/font-feature-settings-parsing.html b/third_party/WebKit/LayoutTests/css3/font-feature-settings-parsing.html
index 973c9a07..81d614d 100644
--- a/third_party/WebKit/LayoutTests/css3/font-feature-settings-parsing.html
+++ b/third_party/WebKit/LayoutTests/css3/font-feature-settings-parsing.html
@@ -175,16 +175,16 @@
 
 debug('- Tests valid inputs.');
 shouldBeEqualToString('parseResultOf("valid_normal")', "normal");
-shouldBeEqualToString('parseResultOf("valid_value_1")', '"dlig" 1');
+shouldBeEqualToString('parseResultOf("valid_value_1")', '"dlig"');
 shouldBeEqualToString('parseResultOf("valid_value_2")', '"swsh" 2');
-shouldBeEqualToString('parseResultOf("valid_value_on")', '"smcp" 1');
+shouldBeEqualToString('parseResultOf("valid_value_on")', '"smcp"');
 shouldBeEqualToString('parseResultOf("valid_value_off")', '"liga" 0');
-shouldBeEqualToString('parseResultOf("valid_value_omit")', '"c2sc" 1');
-shouldBeEqualToString('parseResultOf("valid_valuelist")', '"tnum" 1, "hist" 1');
-shouldBeEqualToString('parseResultOf("valid_singlequote")', '"PKRN" 1');
-shouldBeEqualToString('parseResultOf("valid_unusual_tag")', '"!@#$" 1');
-shouldBeEqualToString('parseResultOf("valid_tag_space")', '"a bc" 1');
-shouldBeEqualToString('parseResultOf("valid_composite")', '"dlig" 1, "smcp" 1, "lig " 0');
+shouldBeEqualToString('parseResultOf("valid_value_omit")', '"c2sc"');
+shouldBeEqualToString('parseResultOf("valid_valuelist")', '"tnum", "hist"');
+shouldBeEqualToString('parseResultOf("valid_singlequote")', '"PKRN"');
+shouldBeEqualToString('parseResultOf("valid_unusual_tag")', '"!@#$"');
+shouldBeEqualToString('parseResultOf("valid_tag_space")', '"a bc"');
+shouldBeEqualToString('parseResultOf("valid_composite")', '"dlig", "smcp", "lig " 0');
 
 debug('- Tests invalid inputs.  Results should be "normal".');
 shouldBe('parseResultOf("invalid_ident")', '"normal"');
@@ -206,13 +206,13 @@
 shouldBe('parseResultOf("invalid_0")', '"normal"');
 
 debug('- Tests inherit.');
-shouldBeEqualToString('parseResultOf("outer")', '"dlig" 1');
-shouldBeEqualToString('parseResultOf("inner")', '"dlig" 1');
+shouldBeEqualToString('parseResultOf("outer")', '"dlig"');
+shouldBeEqualToString('parseResultOf("inner")', '"dlig"');
 
 debug('- Tests @font-face.');
 var fontFaceRuleValid = document.styleSheets[1].cssRules[0].style['-webkit-font-feature-settings'];
 var fontFaceRuleInvalid = document.styleSheets[1].cssRules[1].style['-webkit-font-feature-settings'];
-shouldBeEqualToString('fontFaceRuleValid', '"liga" 1');
+shouldBeEqualToString('fontFaceRuleValid', '"liga"');
 shouldBeEqualToString('fontFaceRuleInvalid', "");
 
 </script>
diff --git a/third_party/WebKit/LayoutTests/css3/fonts/font-feature-settings-parsing-prefixed-expected.txt b/third_party/WebKit/LayoutTests/css3/fonts/font-feature-settings-parsing-prefixed-expected.txt
index e4952f3..f1fe2f5 100644
--- a/third_party/WebKit/LayoutTests/css3/fonts/font-feature-settings-parsing-prefixed-expected.txt
+++ b/third_party/WebKit/LayoutTests/css3/fonts/font-feature-settings-parsing-prefixed-expected.txt
@@ -1,14 +1,14 @@
 This is a testharness.js-based test.
-Harness Error. harness_status.status = 1 , harness_status.message = 2 duplicate test names: "fontFeatureSettings of '@font-face { font-feature-settings: "smcp" 1; }' should be '"smcp" 1'", "webkitFontFeatureSettings of '@font-face { font-feature-settings: "smcp" 1; }' should be '"smcp" 1'"
+Harness Error. harness_status.status = 1 , harness_status.message = 2 duplicate test names: "fontFeatureSettings of '@font-face { font-feature-settings: "smcp"; }' should be '"smcp"'", "webkitFontFeatureSettings of '@font-face { font-feature-settings: "smcp"; }' should be '"smcp"'"
 PASS 'fontFeatureSettings' in style
 PASS 'webkitFontFeatureSettings' in style
-PASS fontFeatureSettings of '@font-face { font-feature-settings: "smcp" 1; }' should be '"smcp" 1'
-PASS webkitFontFeatureSettings of '@font-face { font-feature-settings: "smcp" 1; }' should be '"smcp" 1'
-PASS fontFeatureSettings of '@font-face { font-feature-settings: "smcp" 1; }' should be '"smcp" 1'
-PASS webkitFontFeatureSettings of '@font-face { font-feature-settings: "smcp" 1; }' should be '"smcp" 1'
-PASS fontFeatureSettings of 'font-feature-settings:"smcp" 1' should be '"smcp" 1'
-PASS webkitFontFeatureSettings of 'font-feature-settings:"smcp" 1' should be '"smcp" 1'
-PASS fontFeatureSettings of '-webkit-font-feature-settings:"smcp" 1' should be '"smcp" 1'
-PASS webkitFontFeatureSettings of '-webkit-font-feature-settings:"smcp" 1' should be '"smcp" 1'
+PASS fontFeatureSettings of '@font-face { font-feature-settings: "smcp"; }' should be '"smcp"'
+PASS webkitFontFeatureSettings of '@font-face { font-feature-settings: "smcp"; }' should be '"smcp"'
+PASS fontFeatureSettings of '@font-face { font-feature-settings: "smcp"; }' should be '"smcp"'
+PASS webkitFontFeatureSettings of '@font-face { font-feature-settings: "smcp"; }' should be '"smcp"'
+PASS fontFeatureSettings of 'font-feature-settings:"smcp" 1' should be '"smcp"'
+PASS webkitFontFeatureSettings of 'font-feature-settings:"smcp" 1' should be '"smcp"'
+PASS fontFeatureSettings of '-webkit-font-feature-settings:"smcp" 1' should be '"smcp"'
+PASS webkitFontFeatureSettings of '-webkit-font-feature-settings:"smcp" 1' should be '"smcp"'
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/css3/fonts/font-feature-settings-parsing-prefixed.html b/third_party/WebKit/LayoutTests/css3/fonts/font-feature-settings-parsing-prefixed.html
index 60dc75e..e30660f4 100644
--- a/third_party/WebKit/LayoutTests/css3/fonts/font-feature-settings-parsing-prefixed.html
+++ b/third_party/WebKit/LayoutTests/css3/fonts/font-feature-settings-parsing-prefixed.html
@@ -12,7 +12,7 @@
 <div style='font-feature-settings:"smcp" 1'></div>
 <div style='-webkit-font-feature-settings:"smcp" 1'></div>
 <script>
-var expected = '"smcp" 1';
+var expected = '"smcp"';
 
 var style = document.createElement("foo").style;
 test(function () {
diff --git a/third_party/WebKit/LayoutTests/custom-elements/spec/create-element.html b/third_party/WebKit/LayoutTests/custom-elements/spec/create-element.html
index 596941d..3fc2a4ea 100644
--- a/third_party/WebKit/LayoutTests/custom-elements/spec/create-element.html
+++ b/third_party/WebKit/LayoutTests/custom-elements/spec/create-element.html
@@ -47,9 +47,8 @@
   setup(w);
 
   assert_equals(w.document.createElement('A-a').constructor, w.A);
-  assert_throws_dom_exception(w, 'NotFoundError', () => {
-    w.document.createElement('div', {is: 'b-B'});
-  }, 'The \'is\' option should not be converted to ASCII lowercase');
+  let div = w.document.createElement('div', {is: 'b-B'});
+  assert_false(div instanceof w.B);
 }, 'createElement   2. If context object is an HTML document, let localName be converted to ASCII lowercase');
 
 test_with_window((w) => {
@@ -60,21 +59,16 @@
   assert_equals(w.document.createElement('a-a', {is: 'b-b'}).constructor, w.A,
   'Setting \'is\' attribute for defined autonomous element \'a-a\' has no effect');
 
-  assert_throws_dom_exception(w, 'NotFoundError', () => {
-    w.document.createElement('div', {is: 'a-a'});
-  }, 'Custom element definition named \'a-a\' is not a customized built-in element');
-  assert_throws_dom_exception(w, 'NotFoundError', () => {
-    w.document.createElement('button', {is: 'b-b'});
-  }, 'Custom element definition named \'b-b\' is not an HTMLButtonElement');
-  assert_throws_dom_exception(w, 'NotFoundError', () => {
-    w.document.createElement('div', {id: 'b-b'});
-  }, 'An \'is\' attribute is needed to create a customized built-in element');
-  assert_throws_dom_exception(w, 'NotFoundError', () => {
-    w.document.createElement('div', {is: ''});
-  }, 'There is no custom element definition named with an empty string');
-  assert_throws_dom_exception(w, 'NotFoundError', () => {
-    w.document.createElement('div', {});
-  }, 'There is no custom element definition named with null');
+  assert_false(w.document.createElement('div', {is: 'a-a'}) instanceof w.A,
+               'Custom element definition named \'a-a\' is not a customized built-in element');
+  assert_false(w.document.createElement('button', {is: 'b-b'}) instanceof w.B,
+               'Custom element definition named \'b-b\' is not an HTMLButtonElement');
+  assert_false(w.document.createElement('div', {id: 'b-b'}) instanceof w.B,
+               'An \'is\' attribute is needed to create a customized built-in element');
+  assert_equals(w.document.createElement('div', {is: ''}).constructor, w.HTMLDivElement,
+               'There is no custom element definition named with an empty string');
+  assert_equals(w.document.createElement('div', {}).constructor, w.HTMLDivElement,
+                'There is no custom element definition named with null');
 }, 'createElement   5. If \'is\' is non-null and definition is null, then throw a NotFoundError');
 
 test_with_window((w) => {
@@ -86,9 +80,7 @@
 test_with_window((w) => {
   setup(w);
   assert_equals(w.document.createElementNS('http://www.w3.org/1999/xhtml', 'a-A').constructor, w.HTMLElement);
-  assert_throws_dom_exception(w, 'NotFoundError', () => {
-    w.document.createElementNS('http://www.w3.org/1999/xhtml', 'dIv', {is: 'b-b'});
-  });
+  assert_true(w.document.createElementNS('http://www.w3.org/1999/xhtml', 'dIv', {is: 'b-b'}) instanceof w.HTMLUnknownElement);
 }, 'createElementNS 4. If \'is\' is non-null and definition is null, then throw a NotFoundError');
 
 test_with_window((w) => {
diff --git a/third_party/WebKit/LayoutTests/custom-elements/v0-v1-interop.html b/third_party/WebKit/LayoutTests/custom-elements/v0-v1-interop.html
index 19eaf29..11d0a3a 100644
--- a/third_party/WebKit/LayoutTests/custom-elements/v0-v1-interop.html
+++ b/third_party/WebKit/LayoutTests/custom-elements/v0-v1-interop.html
@@ -32,9 +32,9 @@
 
   assert_true(a instanceof A,
               'V0 createElement syntax works with V0 registerElement');
-  assert_throws_dom_exception(w, 'NotFoundError', () => {
-    w.document.createElement('div', {is: 'a-a'});
-  }, 'V1 createElement syntax does not work with V0 registerElement');
+  assert_equals(w.document.createElement('div', {is: 'a-a'}).constructor,
+                w.HTMLDivElement,
+                'V1 createElement syntax does not work with V0 registerElement');
 
   class B extends w.HTMLDivElement {
     constructor() {
diff --git a/third_party/WebKit/LayoutTests/editing/inserting/4875189-2.html b/third_party/WebKit/LayoutTests/editing/inserting/4875189-2.html
index ad9c104e..270c4a7 100644
--- a/third_party/WebKit/LayoutTests/editing/inserting/4875189-2.html
+++ b/third_party/WebKit/LayoutTests/editing/inserting/4875189-2.html
@@ -1,12 +1,14 @@
-<p>This tests for a bug when replacing the contents of a floating element.  Just its contents should be removed during the replace.</p>
-<div contenteditable="true">This shouldn't be in the bordered div.<div id="div" style="float:left; border: 1px solid blue;">You shouldn't see this.</div></div>
-
+<!doctype html>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="../assert_selection.js"></script>
 <script>
-var r = document.createRange();
-var div = document.getElementById("div");
-r.setStart(div, 0);
-r.setEnd(div, div.childNodes.length);
-var selection = window.getSelection();
-selection.addRange(r);
-document.execCommand("InsertHTML", false, "This should be in a floating blue bordered div.")
+// This tests for a bug when replacing the contents of a floating element. Just
+// its contents should be removed during the replace.
+const kStyle = 'float:left; border: 1px solid blue;';
+selection_test(
+  '<div contenteditable>abc<div style="${kStyle}">^def|</div></div>',
+  'insertHTML XYZ',
+  '<div contenteditable>abc<div style="${kStyle}">XYZ|</div></div>',
+  'Replace HTML in float:left');
 </script>
diff --git a/third_party/WebKit/LayoutTests/editing/inserting/4960120-2.html b/third_party/WebKit/LayoutTests/editing/inserting/insert_line_break_at_end_of_anonymous_block.html
similarity index 100%
rename from third_party/WebKit/LayoutTests/editing/inserting/4960120-2.html
rename to third_party/WebKit/LayoutTests/editing/inserting/insert_line_break_at_end_of_anonymous_block.html
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
index 4da9f2a1..080a3ba 100644
--- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
+++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -34660,7 +34660,7 @@
      "/css/css-flexbox/anonymous-flex-item-004.html",
      [
       [
-       "/css/css-flexbox/anonymous-flex-item-ref.html",
+       "/css/css-flexbox/anonymous-flex-item-split-ref.html",
        "=="
       ]
      ],
@@ -34672,7 +34672,7 @@
      "/css/css-flexbox/anonymous-flex-item-005.html",
      [
       [
-       "/css/css-flexbox/anonymous-flex-item-ref.html",
+       "/css/css-flexbox/anonymous-flex-item-split-ref.html",
        "=="
       ]
      ],
@@ -34684,7 +34684,7 @@
      "/css/css-flexbox/anonymous-flex-item-006.html",
      [
       [
-       "/css/css-flexbox/anonymous-flex-item-ref.html",
+       "/css/css-flexbox/anonymous-flex-item-split-ref.html",
        "=="
       ]
      ],
@@ -101154,6 +101154,11 @@
      {}
     ]
    ],
+   "css/css-flexbox/anonymous-flex-item-split-ref.html": [
+    [
+     {}
+    ]
+   ],
    "css/css-flexbox/auto-margins-001-ref.html": [
     [
      {}
@@ -112179,11 +112184,6 @@
      {}
     ]
    ],
-   "css/css-scoping/slotted-invalidation-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "css/css-scoping/slotted-with-pseudo-element-ref.html": [
     [
      {}
@@ -117164,11 +117164,6 @@
      {}
     ]
    ],
-   "css/css-typed-om/stylevalue-serialization/cssMathValue.tentative-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "css/css-typed-om/stylevalue-subclasses/cssUnparsedValue-interface-expected.txt": [
     [
      {}
@@ -125819,21 +125814,6 @@
      {}
     ]
    ],
-   "custom-elements/reactions/CSSStyleDeclaration-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/reactions/HTMLElement-expected.txt": [
-    [
-     {}
-    ]
-   ],
-   "custom-elements/reactions/HTMLInputElement-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "custom-elements/reactions/resources/reactions.js": [
     [
      {}
@@ -149624,6 +149604,11 @@
      {}
     ]
    ],
+   "service-workers/service-worker/resources/fetch-event-respond-with-body-loaded-in-chunk-worker.js": [
+    [
+     {}
+    ]
+   ],
    "service-workers/service-worker/resources/fetch-event-respond-with-custom-response-worker.js": [
     [
      {}
@@ -149634,6 +149619,11 @@
      {}
     ]
    ],
+   "service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-chunk-worker.js": [
+    [
+     {}
+    ]
+   ],
    "service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-worker.js": [
     [
      {}
@@ -153644,11 +153634,6 @@
      {}
     ]
    ],
-   "webstorage/storage_string_conversion-expected.txt": [
-    [
-     {}
-    ]
-   ],
    "webusb/OWNERS": [
     [
      {}
@@ -162047,6 +162032,12 @@
      {}
     ]
    ],
+   "FileAPI/reading-data-section/filereader_readAsBinaryString.html": [
+    [
+     "/FileAPI/reading-data-section/filereader_readAsBinaryString.html",
+     {}
+    ]
+   ],
    "FileAPI/reading-data-section/filereader_readAsDataURL.html": [
     [
      "/FileAPI/reading-data-section/filereader_readAsDataURL.html",
@@ -215393,6 +215384,12 @@
      {}
     ]
    ],
+   "service-workers/service-worker/fetch-event-respond-with-body-loaded-in-chunk.https.html": [
+    [
+     "/service-workers/service-worker/fetch-event-respond-with-body-loaded-in-chunk.https.html",
+     {}
+    ]
+   ],
    "service-workers/service-worker/fetch-event-respond-with-custom-response.https.html": [
     [
      "/service-workers/service-worker/fetch-event-respond-with-custom-response.https.html",
@@ -215405,6 +215402,12 @@
      {}
     ]
    ],
+   "service-workers/service-worker/fetch-event-respond-with-readable-stream-chunk.https.html": [
+    [
+     "/service-workers/service-worker/fetch-event-respond-with-readable-stream-chunk.https.html",
+     {}
+    ]
+   ],
    "service-workers/service-worker/fetch-event-respond-with-readable-stream.https.html": [
     [
      "/service-workers/service-worker/fetch-event-respond-with-readable-stream.https.html",
@@ -232607,7 +232610,7 @@
    "testharness"
   ],
   "2dcontext/drawing-images-to-the-canvas/2d.drawImage.zerosource.image-expected.txt": [
-   "9a724594c0003fad4f1d8ee50f1db97fa4800c07",
+   "106aee54107cc9c3daa47f4c4197b140d258d59f",
    "support"
   ],
   "2dcontext/drawing-images-to-the-canvas/2d.drawImage.zerosource.image.html": [
@@ -234047,7 +234050,7 @@
    "testharness"
   ],
   "2dcontext/fill-and-stroke-styles/2d.pattern.image.broken-expected.txt": [
-   "f23e40370c7f0a09266efa4bd7a136dab578c4e0",
+   "2fefc3e4cc3c2f3dd1d44f4cbcf819a191ecb5a9",
    "support"
   ],
   "2dcontext/fill-and-stroke-styles/2d.pattern.image.broken.html": [
@@ -235011,7 +235014,7 @@
    "testharness"
   ],
   "2dcontext/pixel-manipulation/2d.imageData.create2.nonfinite-expected.txt": [
-   "0f1d12b5b09d53acab60f61a613ba6d189b65301",
+   "3eda53fb6b6d43f76939c2e67f9be01a97bcef18",
    "support"
   ],
   "2dcontext/pixel-manipulation/2d.imageData.create2.nonfinite.html": [
@@ -235047,7 +235050,7 @@
    "testharness"
   ],
   "2dcontext/pixel-manipulation/2d.imageData.get.nonfinite-expected.txt": [
-   "e5a5f047ae82b6b4ab7dbfd11de379743568c8bc",
+   "8c5714174f4494e2398556911efa9f4cf9418b11",
    "support"
   ],
   "2dcontext/pixel-manipulation/2d.imageData.get.nonfinite.html": [
@@ -235107,7 +235110,7 @@
    "testharness"
   ],
   "2dcontext/pixel-manipulation/2d.imageData.object.ctor.array.bounds-expected.txt": [
-   "057218f179a6a849bde7822d754986a54a3db35d",
+   "75c2e9df62343716de0e24bdd3368bb52469c16e",
    "support"
   ],
   "2dcontext/pixel-manipulation/2d.imageData.object.ctor.array.bounds.html": [
@@ -235203,7 +235206,7 @@
    "testharness"
   ],
   "2dcontext/pixel-manipulation/2d.imageData.put.nonfinite-expected.txt": [
-   "e8d32d96231d0347ba88ff3df3afeb71b55046ca",
+   "f8bb41a5ae9b6af5ce5d8c6025473a789f9cdcf6",
    "support"
   ],
   "2dcontext/pixel-manipulation/2d.imageData.put.nonfinite.html": [
@@ -235971,7 +235974,7 @@
    "testharness"
   ],
   "FileAPI/blob/Blob-constructor-expected.txt": [
-   "bb753161fd7480a13a745dcdd42c78bedb5110b7",
+   "1b853208a8e79f35fa085d7f9b98b569dbf66e81",
    "support"
   ],
   "FileAPI/blob/Blob-constructor.html": [
@@ -235995,7 +235998,7 @@
    "testharness"
   ],
   "FileAPI/file/File-constructor-expected.txt": [
-   "588431d9ea28f035b3f95ad163cdcef609bc0218",
+   "cd401692058497cb393ce9ab0285939e8235b153",
    "support"
   ],
   "FileAPI/file/File-constructor.html": [
@@ -236082,6 +236085,10 @@
    "66422d5cf81ba73c6bf700eb2e2d755f4d105a54",
    "testharness"
   ],
+  "FileAPI/reading-data-section/filereader_readAsBinaryString.html": [
+   "9fc79f63665d48495059542fcb8250f6eb06f17d",
+   "testharness"
+  ],
   "FileAPI/reading-data-section/filereader_readAsDataURL.html": [
    "52371f9c51952984ea5cb07e2a6e3d8dfcf50d16",
    "testharness"
@@ -242395,7 +242402,7 @@
    "testharness"
   ],
   "cors/allow-headers-expected.txt": [
-   "04a8af31b6312bd7009cd9c393698a7c19ed2296",
+   "1754c3b17ec5939809788eaf6701c14bfef5f6bf",
    "support"
   ],
   "cors/allow-headers.htm": [
@@ -242415,7 +242422,7 @@
    "testharness"
   ],
   "cors/origin-expected.txt": [
-   "d1d3ec37eabc5d79f55200c898ee2fdca21e5d2e",
+   "3d066625d0f658873f30ff523e1c896afa788865",
    "support"
   ],
   "cors/origin.htm": [
@@ -261379,21 +261386,25 @@
    "reftest"
   ],
   "css/css-flexbox/anonymous-flex-item-004.html": [
-   "d27625d34f2efa147415ef4e78f01cdc154ea579",
+   "bb323a9ae5e802fb892d8c462bbd733837a6ddf0",
    "reftest"
   ],
   "css/css-flexbox/anonymous-flex-item-005.html": [
-   "c967afaa14aff2a6d2a32346c12b3c1b4fbdc7c6",
+   "a6e054f825e7378729188f39a57b801113f7130f",
    "reftest"
   ],
   "css/css-flexbox/anonymous-flex-item-006.html": [
-   "d3d0c005dc2b121906f40e9a093d0feec9182355",
+   "75b57bad81da6c233d359e7a78a0e7c94f6b8a9b",
    "reftest"
   ],
   "css/css-flexbox/anonymous-flex-item-ref.html": [
    "e8b1580d36b15778ca903fefa1ccccaef31b099f",
    "support"
   ],
+  "css/css-flexbox/anonymous-flex-item-split-ref.html": [
+   "b248e78a0255b923c4ed4aa269e65f53b6386bf4",
+   "support"
+  ],
   "css/css-flexbox/auto-margins-001-ref.html": [
    "dfc6fe046906c564110225d01572aa6aa1e40858",
    "support"
@@ -264551,7 +264562,7 @@
    "support"
   ],
   "css/css-fonts/font-feature-settings-serialization-001.html": [
-   "51a64b41a9a6bc085804710cf3ab80d860964c71",
+   "d1032e08aee1e9a7d1309ad94bd5633535ce9315",
    "testharness"
   ],
   "css/css-fonts/font-features-across-space-1-ref.html": [
@@ -275694,10 +275705,6 @@
    "46913ea7e47811b11be898de5c3bd0a330ea6637",
    "testharness"
   ],
-  "css/css-scoping/slotted-invalidation-expected.txt": [
-   "ba0ab97c9e166125c81cf46fba09387c5333b874",
-   "support"
-  ],
   "css/css-scoping/slotted-invalidation.html": [
    "c500e1ceba1b293d45df5f66fd89d4a5d9ceb952",
    "testharness"
@@ -287798,12 +287805,8 @@
    "004752ad2e9682845697d668af158679031f65dc",
    "testharness"
   ],
-  "css/css-typed-om/stylevalue-serialization/cssMathValue.tentative-expected.txt": [
-   "11864594c531e22f5e798701524ee1c8fda0b77d",
-   "support"
-  ],
   "css/css-typed-om/stylevalue-serialization/cssMathValue.tentative.html": [
-   "4c5bf7630548c90a1397b6f1f215bd3be76b6cf6",
+   "a71f7f5afdd97a55eeef2adc89914194ad5ecb0a",
    "testharness"
   ],
   "css/css-typed-om/stylevalue-serialization/cssPositionValue.html": [
@@ -298587,7 +298590,7 @@
    "testharness"
   ],
   "css/geometry/DOMPoint-001-expected.txt": [
-   "c970d0a5fa9353543cf522b7bb55b8bc974687a7",
+   "d165fd957627bbc2e3ce06e908d0c46d1cc6d813",
    "support"
   ],
   "css/geometry/DOMPoint-001.html": [
@@ -303366,12 +303369,8 @@
    "f16c4bfdb097fbcaa4a039eaa25bc83ed72b2081",
    "testharness"
   ],
-  "custom-elements/reactions/CSSStyleDeclaration-expected.txt": [
-   "a5504b1f055047e8a7a5e00e79b4aed9131671d5",
-   "support"
-  ],
   "custom-elements/reactions/CSSStyleDeclaration.html": [
-   "11d4f8979af248f2c4d5dc28e93e5d15822d2c78",
+   "cbd44b985a25eeee1c00b5c8e58a6fc0080d2551",
    "testharness"
   ],
   "custom-elements/reactions/ChildNode.html": [
@@ -303402,20 +303401,12 @@
    "c26787be32eb45aabd9f378a647e4abfa003dc9c",
    "testharness"
   ],
-  "custom-elements/reactions/HTMLElement-expected.txt": [
-   "e2f4e777264c8631648e28877283cfba555c4fce",
-   "support"
-  ],
   "custom-elements/reactions/HTMLElement.html": [
-   "4c54b3e179c23375334d2b6d667ab17781c2c127",
+   "4682575e319941a1ccd62a3e1c8c97ac092bdbcc",
    "testharness"
   ],
-  "custom-elements/reactions/HTMLInputElement-expected.txt": [
-   "a4654c97eea8d1021e9aa7bd271523ecd0380f39",
-   "support"
-  ],
   "custom-elements/reactions/HTMLInputElement.html": [
-   "ad2bdba330235b320eda6636cd30b320d607d74f",
+   "ee56f4ab2948a3c536a80c9d8954f7e8baee06a4",
    "testharness"
   ],
   "custom-elements/reactions/HTMLOptionElement.html": [
@@ -303543,7 +303534,7 @@
    "testharness"
   ],
   "dom/collections/HTMLCollection-supported-property-indices-expected.txt": [
-   "c6ca31a85eaae770bbf21ca86c216eae555b89f6",
+   "232176736c41a5e49e7870d439d6ccc936a71ee4",
    "support"
   ],
   "dom/collections/HTMLCollection-supported-property-indices.html": [
@@ -305179,7 +305170,7 @@
    "testharness"
   ],
   "domparsing/innerhtml-01-expected.txt": [
-   "3932429de1f3718737d3be52085a51050ef1584a",
+   "fb1e0c99ab5396293e80c436f8e108e64c435d39",
    "support"
   ],
   "domparsing/innerhtml-01.xhtml": [
@@ -307843,7 +307834,7 @@
    "testharness"
   ],
   "eventsource/eventsource-constructor-url-bogus-expected.txt": [
-   "88518a210aabe94fd5bb5501d469e54f69b8a24e",
+   "f580f85201078efe9c5c6e3889c8a6be8eb04480",
    "support"
   ],
   "eventsource/eventsource-constructor-url-bogus.htm": [
@@ -308607,7 +308598,7 @@
    "testharness"
   ],
   "fetch/api/headers/headers-record-expected.txt": [
-   "22f7a26bd5457081904642b8375756cc58512c13",
+   "e365ec40ee231de754fc7d2a10afb01636a3b57b",
    "support"
   ],
   "fetch/api/headers/headers-record.html": [
@@ -311595,7 +311586,7 @@
    "testharness"
   ],
   "html/browsers/history/the-location-interface/location-prototype-setting-same-origin-domain.sub-expected.txt": [
-   "b2aaf9072eec83d984475b6138a86e14b4a16841",
+   "715fcc91a85dcc7f35fe11d3de1a646c4e43b2a4",
    "support"
   ],
   "html/browsers/history/the-location-interface/location-prototype-setting-same-origin-domain.sub.html": [
@@ -311603,7 +311594,7 @@
    "testharness"
   ],
   "html/browsers/history/the-location-interface/location-prototype-setting-same-origin-expected.txt": [
-   "b71485cafe9a4a3878d2a1a5b1ff3b9f4435c751",
+   "72985e913d57664f1ef5960c1fde4c2c50124c1b",
    "support"
   ],
   "html/browsers/history/the-location-interface/location-prototype-setting-same-origin.html": [
@@ -314591,7 +314582,7 @@
    "support"
   ],
   "html/dom/interfaces-expected.txt": [
-   "ef910b9201c1cedb8dd0f2ff730b22aef0823086",
+   "8fe328e6c6084f2ea99b2dcfb14a8751ca3fa9b1",
    "support"
   ],
   "html/dom/interfaces.html": [
@@ -317915,7 +317906,7 @@
    "support"
   ],
   "html/editing/dnd/synthetic/001-expected.txt": [
-   "e1e7352a59d44251c9fb0a17f2dd0c6e6de49b71",
+   "fa9b38f977bedc8c38645b8b9576bd2cb8f17a7e",
    "support"
   ],
   "html/editing/dnd/synthetic/001.html": [
@@ -318487,7 +318478,7 @@
    "testharness"
   ],
   "html/infrastructure/common-dom-interfaces/collections/htmlallcollection-expected.txt": [
-   "34452eb94a2b4b64b98a00502995dd05943c0a33",
+   "7dc8b3bfea089cd4b7f649d5a1bc40f3976c16ae",
    "support"
   ],
   "html/infrastructure/common-dom-interfaces/collections/htmlallcollection.html": [
@@ -320811,7 +320802,7 @@
    "testharness"
   ],
   "html/semantics/embedded-content/media-elements/interfaces/TrackEvent/createEvent-expected.txt": [
-   "5cfbc0d4f1e88974f74794306a7ec14212f61831",
+   "4dbd380cef14d839f07c9fd705cf31ab13db8668",
    "support"
   ],
   "html/semantics/embedded-content/media-elements/interfaces/TrackEvent/createEvent.html": [
@@ -322111,7 +322102,7 @@
    "testharness"
   ],
   "html/semantics/embedded-content/the-canvas-element/imagedata-expected.txt": [
-   "fac860d26146b83176d0f7a01cff9f21457118e5",
+   "2501b2e9fdbf7df1cfc5720d699e7741a5346140",
    "support"
   ],
   "html/semantics/embedded-content/the-canvas-element/imagedata.html": [
@@ -323995,7 +323986,7 @@
    "testharness"
   ],
   "html/semantics/forms/the-form-element/form-indexed-element-expected.txt": [
-   "ffd7c43e8d023e538fb994933c95cc279e74cc15",
+   "d2ac65c06d75476e2ce6e17f1202900e4eb7867c",
    "support"
   ],
   "html/semantics/forms/the-form-element/form-indexed-element.html": [
@@ -328851,7 +328842,7 @@
    "testharness"
   ],
   "html/webappapis/scripting/events/messageevent-constructor.https-expected.txt": [
-   "aa851d26731628a6afbb11b7e5e63cecf95b5f55",
+   "d25c3b239af7b9ab97671bd5940c2c7c8e21714a",
    "support"
   ],
   "html/webappapis/scripting/events/messageevent-constructor.https.html": [
@@ -329103,7 +329094,7 @@
    "testharness"
   ],
   "html/webappapis/scripting/processing-model-2/unhandled-promise-rejections/promise-rejection-event-constructor.html": [
-   "8bbb29655a28bc76708e802d617a5a6046b4e4b0",
+   "98839f498553aba4667c2dce4503f8ccc5189895",
    "testharness"
   ],
   "html/webappapis/scripting/processing-model-2/unhandled-promise-rejections/promise-rejection-events-attached-in-event.html": [
@@ -329931,7 +329922,7 @@
    "support"
   ],
   "keyboard-lock/idlharness.https-expected.txt": [
-   "91c34bcea13f87b60767638ac7c75f22af165aa7",
+   "c341109e1391b66ebc458f24aa74ddcaa730b203",
    "support"
   ],
   "keyboard-lock/idlharness.https.html": [
@@ -330119,7 +330110,7 @@
    "testharness"
   ],
   "media-capabilities/idlharness-expected.txt": [
-   "41bca77b1075198390a83c09f1dd145ed09ac94a",
+   "d1352e29204a303c6c1788550df8284677f887e7",
    "support"
   ],
   "media-capabilities/idlharness.html": [
@@ -337075,7 +337066,7 @@
    "testharness"
   ],
   "offscreen-canvas/pixel-manipulation/2d.imageData.create2.nonfinite-expected.txt": [
-   "d34a41f92e79be55b110472a264dada6d184b757",
+   "8c4a63ecd2f74dbf6c6fa454235c76dabf8dafc7",
    "support"
   ],
   "offscreen-canvas/pixel-manipulation/2d.imageData.create2.nonfinite.html": [
@@ -337127,7 +337118,7 @@
    "testharness"
   ],
   "offscreen-canvas/pixel-manipulation/2d.imageData.get.nonfinite-expected.txt": [
-   "e5a5f047ae82b6b4ab7dbfd11de379743568c8bc",
+   "8c5714174f4494e2398556911efa9f4cf9418b11",
    "support"
   ],
   "offscreen-canvas/pixel-manipulation/2d.imageData.get.nonfinite.html": [
@@ -337391,7 +337382,7 @@
    "testharness"
   ],
   "offscreen-canvas/pixel-manipulation/2d.imageData.put.nonfinite-expected.txt": [
-   "e8d32d96231d0347ba88ff3df3afeb71b55046ca",
+   "f8bb41a5ae9b6af5ce5d8c6025473a789f9cdcf6",
    "support"
   ],
   "offscreen-canvas/pixel-manipulation/2d.imageData.put.nonfinite.html": [
@@ -338223,7 +338214,7 @@
    "testharness"
   ],
   "offscreen-canvas/the-offscreen-canvas/offscreencanvas.commit-expected.txt": [
-   "448a1b848526f47f8b8afe6ae181fe18785d3e6d",
+   "07d5816feafe77c71269ae2c81b961d6c1e7bc96",
    "support"
   ],
   "offscreen-canvas/the-offscreen-canvas/offscreencanvas.commit.html": [
@@ -338283,7 +338274,7 @@
    "testharness"
   ],
   "offscreen-canvas/the-offscreen-canvas/offscreencanvas.transferrable-expected.txt": [
-   "7cc1f5c62ef84a0ebeaae607e6a2bf81748e9bc4",
+   "a30bc461a32b55fa99d70d49d947488d749fe457",
    "support"
   ],
   "offscreen-canvas/the-offscreen-canvas/offscreencanvas.transferrable.html": [
@@ -339271,7 +339262,7 @@
    "manual"
   ],
   "payment-request/rejects_if_not_active.https-expected.txt": [
-   "bbf53033e840dd8c2ab1c4e62f8c006cec8bdc91",
+   "ba129eb4e9de98beec9ee048dd658b8888582dcc",
    "support"
   ],
   "payment-request/rejects_if_not_active.https.html": [
@@ -348091,7 +348082,7 @@
    "testharness"
   ],
   "screen-orientation/lock-bad-argument-expected.txt": [
-   "a27f6264d5dce06d487ff4f8bf06766b96082dfa",
+   "bf614ed2fb505fe5843b1be1b82f63517af526a7",
    "support"
   ],
   "screen-orientation/lock-bad-argument.html": [
@@ -348395,7 +348386,7 @@
    "testharness"
   ],
   "selection/removeRange-expected.txt": [
-   "01f7714e79a308a4532df00512bfc313ca9ce4d4",
+   "2103a0ede3382030caefe808306c2a83b14333b2",
    "support"
   ],
   "selection/removeRange.html": [
@@ -349670,6 +349661,10 @@
    "ce7e7cf76aace24a92d455cdb6b54fc9048960e8",
    "testharness"
   ],
+  "service-workers/service-worker/fetch-event-respond-with-body-loaded-in-chunk.https.html": [
+   "ce480de45a03c7c9f6b58cf4a91359ffb9a29e74",
+   "testharness"
+  ],
   "service-workers/service-worker/fetch-event-respond-with-custom-response.https.html": [
    "fc304fa03a33021e4141d940835824883415279e",
    "testharness"
@@ -349678,6 +349673,10 @@
    "c0e976149cf49c09f52b81159d2a48c301a4aa4b",
    "testharness"
   ],
+  "service-workers/service-worker/fetch-event-respond-with-readable-stream-chunk.https.html": [
+   "3d70e8ed429f0711f480bb3f0c6e01b49cefffa1",
+   "testharness"
+  ],
   "service-workers/service-worker/fetch-event-respond-with-readable-stream.https.html": [
    "37c7959e58af70f3feea0f4fb46d778734a0296b",
    "testharness"
@@ -349707,7 +349706,7 @@
    "testharness"
   ],
   "service-workers/service-worker/fetch-event.https-expected.txt": [
-   "c42bbbba561b3e04c038abd74f6179c2d145f61c",
+   "69e228db59d2442da8d5f20887cf91cc93162225",
    "support"
   ],
   "service-workers/service-worker/fetch-event.https.html": [
@@ -349759,7 +349758,7 @@
    "testharness"
   ],
   "service-workers/service-worker/fetch-request-resources.https.html": [
-   "cb072581704868845fe1ec57b3e7c70d53bac543",
+   "d21ef5a4263e26cd3053a89171e2597424eaad82",
    "testharness"
   ],
   "service-workers/service-worker/fetch-request-xhr-sync.https-expected.txt": [
@@ -349839,7 +349838,7 @@
    "testharness"
   ],
   "service-workers/service-worker/interfaces-sw.https-expected.txt": [
-   "4f18c979aec831e80747fbe3f64c25caab5acb30",
+   "fc3c4f747d5af8ff7bec1ac9484a94f12d4f3963",
    "support"
   ],
   "service-workers/service-worker/interfaces-sw.https.html": [
@@ -350151,7 +350150,7 @@
    "testharness"
   ],
   "service-workers/service-worker/request-end-to-end.https.html": [
-   "ee9f8140b492daf89cb715643ee40557f6ed904e",
+   "e93efe04f35ff8c9ce15969a7b3f6373b098c4a8",
    "testharness"
   ],
   "service-workers/service-worker/resource-timing.https-expected.txt": [
@@ -350259,7 +350258,7 @@
    "support"
   ],
   "service-workers/service-worker/resources/client-navigate-worker.js": [
-   "876f60f8c7112cc0a7a2df2fe2b298a3c9504214",
+   "6d4712b6398cdafa95fc5101e9fffe10eb43311f",
    "support"
   ],
   "service-workers/service-worker/resources/client-navigated-frame.html": [
@@ -350438,6 +350437,10 @@
    "b58b92a145a89f71c414de5e837c1db026beb1d6",
    "support"
   ],
+  "service-workers/service-worker/resources/fetch-event-respond-with-body-loaded-in-chunk-worker.js": [
+   "b044c62224d56bfd1e3b25ce4e2700ed6231f0ed",
+   "support"
+  ],
   "service-workers/service-worker/resources/fetch-event-respond-with-custom-response-worker.js": [
    "a5d0d55ccfa7c3c4c285153aa14b81ef205329c9",
    "support"
@@ -350446,6 +350449,10 @@
    "6054d723ad0d0d310b02841b696d2357e7137398",
    "support"
   ],
+  "service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-chunk-worker.js": [
+   "fc2c81a984f43bb1a83ed1e830c7a35c0b5f7538",
+   "support"
+  ],
   "service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-worker.js": [
    "052da5a0a6b26098fe745fd6d9ca8de0f4dfdc5b",
    "support"
@@ -350563,7 +350570,7 @@
    "support"
   ],
   "service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html": [
-   "72a1a0895f9b511075f77c618c8ab0aabd177346",
+   "2879ba75fc0135aa9220f5eb5d7e00b8bcf1cbcc",
    "support"
   ],
   "service-workers/service-worker/resources/fetch-request-xhr-sync-iframe.html": [
@@ -350875,7 +350882,7 @@
    "support"
   ],
   "service-workers/service-worker/resources/register-closed-window-iframe.html": [
-   "18ee27c8d6a5497bf16b3315ba9eee2b474154b5",
+   "aa9a0825844b3bc13eee96dc6eeffcf887ee2b72",
    "support"
   ],
   "service-workers/service-worker/resources/register-iframe.html": [
@@ -354251,7 +354258,7 @@
    "support"
   ],
   "uievents/legacy/Event-subclasses-init-expected.txt": [
-   "b8a1228034b788e414e42708d220e7a69f0c7936",
+   "67fa6e9ce00df522fa80744da30ec5114a54942b",
    "support"
   ],
   "uievents/legacy/Event-subclasses-init.html": [
@@ -354459,7 +354466,7 @@
    "testharness"
   ],
   "url/historical.any-expected.txt": [
-   "641ea29f1a7600d512948a6d531611ecb82d9da4",
+   "0314b5c6f42fe0e69026a4faf35951eb98dcb073",
    "support"
   ],
   "url/historical.any.js": [
@@ -354467,7 +354474,7 @@
    "testharness"
   ],
   "url/historical.any.worker-expected.txt": [
-   "7064d6d5d2e7c9c7f783b2378b00f597469890e7",
+   "f0d00a1a71c4075b3094d9e630618f4e577575bf",
    "support"
   ],
   "url/interfaces.any-expected.txt": [
@@ -354611,7 +354618,7 @@
    "testharness"
   ],
   "user-timing/invoke_with_timing_attributes-expected.txt": [
-   "7eca5396e846104a93f5f1bbe5fac51129611d56",
+   "f173e3e46373df00331ab86e0c613621fac41003",
    "support"
   ],
   "user-timing/invoke_with_timing_attributes.html": [
@@ -355503,7 +355510,7 @@
    "testharness"
   ],
   "web-nfc/nfc_push.https-expected.txt": [
-   "096b7e40292a0862c645a166cd017b8674d7c94a",
+   "3e7308ae77368bbc6a200c3d9a03f1588583b04f",
    "support"
   ],
   "web-nfc/nfc_push.https.html": [
@@ -355567,7 +355574,7 @@
    "manual"
   ],
   "web-nfc/nfc_watch.https-expected.txt": [
-   "97bdffaf68f153c2f74349b8fa867f8dcb7e0aeb",
+   "7303b2495774a142ede015c7583d3dbd9d5cc3e5",
    "support"
   ],
   "web-nfc/nfc_watch.https.html": [
@@ -358378,10 +358385,6 @@
    "74fb62c4369f7929bb9387d8fadb1341e30eb90f",
    "testharness"
   ],
-  "webstorage/storage_string_conversion-expected.txt": [
-   "c0b3a51a27cbd52e962ef1dcdb905433f844a45f",
-   "support"
-  ],
   "webstorage/storage_string_conversion.html": [
    "33c748773a518af29ea2ef8cbbc859fe988fb88a",
    "testharness"
@@ -358607,7 +358610,7 @@
    "testharness"
   ],
   "webvtt/api/VTTRegion/constructor.html": [
-   "c002fac0ad6077fe44987393159f7d86c1226e84",
+   "501828089ebb3d3521045c392230379668529f42",
    "testharness"
   ],
   "webvtt/api/VTTRegion/id.html": [
@@ -358615,7 +358618,7 @@
    "testharness"
   ],
   "webvtt/api/VTTRegion/lines.html": [
-   "590cec0b814df0bca2760cde94b2f74b4c9defca",
+   "ac35f25e77c0430b4776435c07f908f990de1fb0",
    "testharness"
   ],
   "webvtt/api/VTTRegion/non-visible-cue-with-region.html": [
@@ -358975,7 +358978,7 @@
    "testharness"
   ],
   "webvtt/parsing/file-parsing/tests/regions-lines-expected.txt": [
-   "47949a8cb64bdb4fd05340f688382ad69c5f1e3a",
+   "34e66bd4adc32c2df07a1afba82e2dd45572e2fd",
    "support"
   ],
   "webvtt/parsing/file-parsing/tests/regions-lines.html": [
@@ -362039,7 +362042,7 @@
    "testharness"
   ],
   "workers/interfaces/WorkerUtils/importScripts/002.worker-expected.txt": [
-   "1deca0f6f12464c79e8741736f9cf0b4fda1f105",
+   "50b2e70ef5908dc31626a950f89120dffa2eb4e0",
    "support"
   ],
   "workers/interfaces/WorkerUtils/importScripts/002.worker.js": [
@@ -363355,7 +363358,7 @@
    "testharness"
   ],
   "xhr/open-url-multi-window-2-expected.txt": [
-   "320baf425910398a9987500be3cd8714ecebe30d",
+   "aa468b8b3ae9bf38397973677bfe3b576507bb9c",
    "support"
   ],
   "xhr/open-url-multi-window-2.htm": [
@@ -363363,7 +363366,7 @@
    "testharness"
   ],
   "xhr/open-url-multi-window-3-expected.txt": [
-   "0ac8d75185d4394ff869eda9580f511ec2eda031",
+   "7cbd84f4349472bb5078b700677f431ca4e08c30",
    "support"
   ],
   "xhr/open-url-multi-window-3.htm": [
@@ -363379,7 +363382,7 @@
    "testharness"
   ],
   "xhr/open-url-multi-window-5-expected.txt": [
-   "437da3b34abf3fdd4b7c99085b5e7b1770612140",
+   "83637eb267380b0a13c3e04c4be933895f921bd0",
    "support"
   ],
   "xhr/open-url-multi-window-5.htm": [
@@ -363387,7 +363390,7 @@
    "testharness"
   ],
   "xhr/open-url-multi-window-6-expected.txt": [
-   "dc8d9fbe1e0dc7c015743fa851ef756f945b1794",
+   "4f6c91620d0cc9337076560c8ac3bcbfc4fa16f1",
    "support"
   ],
   "xhr/open-url-multi-window-6.htm": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/FileAPI/reading-data-section/filereader_readAsBinaryString.html b/third_party/WebKit/LayoutTests/external/wpt/FileAPI/reading-data-section/filereader_readAsBinaryString.html
new file mode 100644
index 0000000..b550e4d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/FileAPI/reading-data-section/filereader_readAsBinaryString.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>FileAPI Test: filereader_readAsBinaryString</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<link rel="help" href="https://w3c.github.io/FileAPI/#readAsBinaryString">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+
+async_test(t => {
+  const blob = new Blob(["σ"]);
+  const reader = new FileReader();
+
+  reader.onload = t.step_func_done(() => {
+    assert_equals(typeof reader.result, "string", "The result is string");
+    assert_equals(reader.result.length, 2, "The result length is 2");
+    assert_equals(reader.result, "\xcf\x83", "The result is \xcf\x83");
+    assert_equals(reader.readyState, reader.DONE);
+  });
+
+  reader.onloadstart = t.step_func(() => {
+    assert_equals(reader.readyState, reader.LOADING);
+  });
+
+  reader.onprogress = t.step_func(() => {
+    assert_equals(reader.readyState, reader.LOADING);
+  });
+
+  reader.readAsBinaryString(blob);
+});
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/font-feature-settings-serialization-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/font-feature-settings-serialization-001.html
index 025afa2..bccc3cf 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/font-feature-settings-serialization-001.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-fonts/font-feature-settings-serialization-001.html
@@ -20,7 +20,7 @@
     const div = document.querySelector("#test");
     const div1 = document.querySelector("#test1");
     test(function() {
-        assert_equals(getComputedStyle(div).fontFeatureSettings, '"vert" 1');
-        assert_equals(getComputedStyle(div1).fontFeatureSettings, '"vert" 1');
-    }, "font-feature-settings should have its feature tag serialized with double quotes");
+        assert_equals(getComputedStyle(div).fontFeatureSettings, '"vert"');
+        assert_equals(getComputedStyle(div1).fontFeatureSettings, '"vert"');
+    }, "font-feature-settings should be serialized with double quotes, and the default value of 1 should be omitted");
 </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/Document-createElement.html b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/Document-createElement.html
index 52a68e8..97a5659 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/Document-createElement.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/Document-createElement.html
@@ -342,6 +342,18 @@
 
 }, 'document.createElement must report an exception thrown by a custom element constructor');
 
+test(() => {
+  class MyElement extends HTMLDivElement {}
+
+  // createElement with unknown 'is' should not throw.
+  // https://github.com/w3c/webcomponents/issues/608
+  let div = document.createElement('div', { is: 'my-div' });
+  assert_false(div instanceof MyElement);
+
+  customElements.define('my-div', MyElement, { extends: 'div' });
+  document.body.appendChild(div);
+  assert_true(div instanceof MyElement, 'Undefined element is upgraded on connecting to a document');
+}, 'document.createElement with unknown "is" value should create "undefined" state element');
 </script>
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/reactions/CSSStyleDeclaration-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/reactions/CSSStyleDeclaration-expected.txt
deleted file mode 100644
index 0adf2338..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/reactions/CSSStyleDeclaration-expected.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-This is a testharness.js-based test.
-PASS cssText on CSSStyleDeclaration must enqueue an attributeChanged reaction when it adds the observed style attribute
-PASS cssText on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it adds the style attribute but the style attribute is not observed
-PASS cssText on CSSStyleDeclaration must enqueue an attributeChanged reaction when it mutates the observed style attribute
-PASS cssText on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it mutates the style attribute but the style attribute is not observed
-PASS setProperty on CSSStyleDeclaration must enqueue an attributeChanged reaction when it adds the observed style attribute
-PASS setProperty on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it adds the style attribute but the style attribute is not observed
-PASS setProperty on CSSStyleDeclaration must enqueue an attributeChanged reaction when it mutates the observed style attribute
-PASS setProperty on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it mutates the style attribute but the style attribute is not observed
-PASS setProperty on CSSStyleDeclaration must enqueue an attributeChanged reaction when it makes a property important and the style attribute is observed
-PASS setProperty on CSSStyleDeclaration must enqueue an attributeChanged reaction when it makes a property important but the style attribute is not observed
-FAIL setPropertyValue on CSSStyleDeclaration must enqueue an attributeChanged reaction when it adds the observed style attribute instance.style.setPropertyValue is not a function
-FAIL setPropertyValue on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it adds the style attribute but the style attribute is not observed instance.style.setPropertyValue is not a function
-FAIL setPropertyValue on CSSStyleDeclaration must enqueue an attributeChanged reaction when it mutates the observed style attribute instance.style.setPropertyValue is not a function
-FAIL setPropertyValue on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it mutates the style attribute but the style attribute is not observed instance.style.setPropertyValue is not a function
-FAIL setPropertyPriority on CSSStyleDeclaration must enqueue an attributeChanged reaction when it makes a property important and the style attribute is observed instance.style.setPropertyPriority is not a function
-FAIL setPropertyPriority on CSSStyleDeclaration must enqueue an attributeChanged reaction when it makes a property important but the style attribute is not observed instance.style.setPropertyPriority is not a function
-PASS removeProperty on CSSStyleDeclaration must enqueue an attributeChanged reaction when it removes a property from the observed style attribute
-PASS removeProperty on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it removes a property from the style attribute but the style attribute is not observed
-PASS cssFloat on CSSStyleDeclaration must enqueue an attributeChanged reaction when it adds the observed style attribute
-PASS cssFloat on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it adds the style attribute but the style attribute is not observed
-PASS A camel case attribute (borderWidth) on CSSStyleDeclaration must enqueue an attributeChanged reaction when it adds the observed style attribute
-PASS A camel case attribute (borderWidth) on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it adds the style attribute but the style attribute is not observed
-PASS A camel case attribute (borderWidth) on CSSStyleDeclaration must enqueue an attributeChanged reaction when it mutates the observed style attribute
-PASS A camel case attribute (borderWidth) on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it mutates the style attribute but the style attribute is not observed
-PASS A dashed property (border-width) on CSSStyleDeclaration must enqueue an attributeChanged reaction when it adds the observed style attribute
-PASS A dashed property (border-width) on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it adds the style attribute but the style attribute is not observed
-PASS A dashed property (border-width) on CSSStyleDeclaration must enqueue an attributeChanged reaction when it mutates the observed style attribute
-PASS A dashed property (border-width) on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it mutates the style attribute but the style attribute is not observed
-PASS A webkit prefixed camel case attribute (webkitFilter) on CSSStyleDeclaration must enqueue an attributeChanged reaction when it adds the observed style attribute
-PASS A webkit prefixed camel case attribute (webkitFilter) on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it adds the style attribute but the style attribute is not observed
-PASS A webkit prefixed camel case attribute (webkitFilter) on CSSStyleDeclaration must enqueue an attributeChanged reaction when it mutates the observed style attribute
-PASS A webkit prefixed camel case attribute (webkitFilter) on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it mutates the style attribute but the style attribute is not observed
-PASS A webkit prefixed dashed property (-webkit-filter) on CSSStyleDeclaration must enqueue an attributeChanged reaction when it adds the observed style attribute
-PASS A webkit prefixed dashed property (-webkit-filter) on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it adds the style attribute but the style attribute is not observed
-PASS A webkit prefixed dashed property (-webkit-filter) on CSSStyleDeclaration must enqueue an attributeChanged reaction when it mutates the observed style attribute
-PASS A webkit prefixed dashed property (-webkit-filter) on CSSStyleDeclaration must not enqueue an attributeChanged reaction when it mutates the style attribute but the style attribute is not observed
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/reactions/CSSStyleDeclaration.html b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/reactions/CSSStyleDeclaration.html
index bf9e00a..95274d8 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/reactions/CSSStyleDeclaration.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/reactions/CSSStyleDeclaration.html
@@ -26,13 +26,17 @@
     instance.style.setProperty(propertyName, instance.style[idlName], isImportant ? 'important': '');
 }, 'setProperty on CSSStyleDeclaration');
 
-test_mutating_style_property_value(function (instance, propertyName, idlName, value) {
-    instance.style.setPropertyValue(propertyName, value);
-}, 'setPropertyValue on CSSStyleDeclaration');
+if (CSSStyleDeclaration.prototype.setPropertyValue) {
+    test_mutating_style_property_value(function (instance, propertyName, idlName, value) {
+        instance.style.setPropertyValue(propertyName, value);
+    }, 'setPropertyValue on CSSStyleDeclaration');
+}
 
-test_mutating_style_property_priority(function (instance, propertyName, idlName, isImportant) {
-    instance.style.setPropertyPriority(propertyName, isImportant ? 'important': '');
-}, 'setPropertyPriority on CSSStyleDeclaration');
+if (CSSStyleDeclaration.prototype.setPropertyPriority) {
+    test_mutating_style_property_priority(function (instance, propertyName, idlName, isImportant) {
+        instance.style.setPropertyPriority(propertyName, isImportant ? 'important': '');
+    }, 'setPropertyPriority on CSSStyleDeclaration');
+}
 
 test_removing_style_property_value(function (instance, propertyName, idlName) {
     instance.style.removeProperty(propertyName);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/reactions/HTMLElement-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/reactions/HTMLElement-expected.txt
deleted file mode 100644
index e1a92f5..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/reactions/HTMLElement-expected.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-This is a testharness.js-based test.
-PASS title on HTMLElement must enqueue an attributeChanged reaction when adding title content attribute
-PASS title on HTMLElement must enqueue an attributeChanged reaction when replacing an existing attribute
-PASS lang on HTMLElement must enqueue an attributeChanged reaction when adding lang content attribute
-PASS lang on HTMLElement must enqueue an attributeChanged reaction when replacing an existing attribute
-PASS translate on HTMLElement must enqueue an attributeChanged reaction when adding translate content attribute
-PASS translate on HTMLElement must enqueue an attributeChanged reaction when replacing an existing attribute
-PASS dir on HTMLElement must enqueue an attributeChanged reaction when adding dir content attribute
-PASS dir on HTMLElement must enqueue an attributeChanged reaction when replacing an existing attribute
-PASS hidden on HTMLElement must enqueue an attributeChanged reaction when adding hidden content attribute
-PASS hidden on HTMLElement must enqueue an attributeChanged reaction when replacing an existing attribute
-PASS tabIndex on HTMLElement must enqueue an attributeChanged reaction when adding tabindex content attribute
-PASS tabIndex on HTMLElement must enqueue an attributeChanged reaction when replacing an existing attribute
-PASS accessKey on HTMLElement must enqueue an attributeChanged reaction when adding accesskey content attribute
-PASS accessKey on HTMLElement must enqueue an attributeChanged reaction when replacing an existing attribute
-PASS draggable on HTMLElement must enqueue an attributeChanged reaction when adding draggable content attribute
-PASS draggable on HTMLElement must enqueue an attributeChanged reaction when replacing an existing attribute
-FAIL dropzone on HTMLElement must enqueue an attributeChanged reaction when adding dropzone content attribute assert_array_equals: lengths differ, expected 1 got 0
-FAIL dropzone on HTMLElement must enqueue an attributeChanged reaction when replacing an existing attribute assert_array_equals: lengths differ, expected 2 got 1
-FAIL contextMenu on HTMLElement must enqueue an attributeChanged reaction when adding contextmenu content attribute assert_array_equals: lengths differ, expected 1 got 0
-FAIL contextMenu on HTMLElement must enqueue an attributeChanged reaction when replacing an existing attribute assert_array_equals: lengths differ, expected 2 got 1
-PASS spellcheck on HTMLElement must enqueue an attributeChanged reaction when adding spellcheck content attribute
-PASS spellcheck on HTMLElement must enqueue an attributeChanged reaction when replacing an existing attribute
-PASS innerText on HTMLElement must enqueue a disconnected reaction
-PASS outerText on HTMLElement must enqueue a disconnected reaction
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/reactions/HTMLElement.html b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/reactions/HTMLElement.html
index bce4ef16..5fe422c 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/reactions/HTMLElement.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/reactions/HTMLElement.html
@@ -22,8 +22,6 @@
 testReflectAttribute('tabIndex', 'tabindex', '0', '1', 'tabIndex on HTMLElement');
 testReflectAttribute('accessKey', 'accesskey', 'a', 'b', 'accessKey on HTMLElement');
 testReflectAttributeWithContentValues('draggable', 'draggable', true, 'true', false, 'false', 'draggable on HTMLElement');
-testReflectAttribute('dropzone', 'dropzone', 'copy', 'move', 'dropzone on HTMLElement');
-testReflectAttribute('contextMenu', 'contextmenu', 'menu1', 'menu2', 'contextMenu on HTMLElement');
 testReflectAttributeWithContentValues('spellcheck', 'spellcheck', true, 'true', false, 'false', 'spellcheck on HTMLElement');
 
 testNodeDisconnector(function (customElement) {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/reactions/HTMLInputElement-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/reactions/HTMLInputElement-expected.txt
deleted file mode 100644
index 470e146..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/reactions/HTMLInputElement-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-FAIL capture on HTMLInputElement must enqueue an attributeChanged reaction when adding new attribute assert_array_equals: lengths differ, expected 1 got 0
-FAIL capture on HTMLInputElement must enqueue an attributeChanged reaction when replacing an existing attribute assert_array_equals: lengths differ, expected 2 got 1
-FAIL capture on HTMLInputElement must enqueue an attributeChanged reaction when adding invalid value default assert_array_equals: lengths differ, expected 1 got 0
-FAIL capture on HTMLInputElement must enqueue an attributeChanged reaction when removing the attribute assert_array_equals: lengths differ, expected 2 got 1
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/reactions/HTMLInputElement.html b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/reactions/HTMLInputElement.html
index 8193d2c..dc4b22a2 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/reactions/HTMLInputElement.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/reactions/HTMLInputElement.html
@@ -11,51 +11,56 @@
 <script src="./resources/reactions.js"></script>
 <body>
 <script>
-test(() => {
-    const element = define_build_in_custom_element(['capture'], HTMLInputElement, 'input');
-    const instance = document.createElement('input', { is: element.name });
+if (HTMLInputElement.prototype.capture) {
+    test(() => {
+        const element = define_build_in_custom_element(['capture'], HTMLInputElement, 'input');
+        const instance = document.createElement('input', { is: element.name });
 
-    assert_array_equals(element.takeLog().types(), ['constructed']);
-    instance['capture'] = 'user';
-    const logEntries = element.takeLog();
-    assert_array_equals(logEntries.types(), ['attributeChanged']);
-    assert_attribute_log_entry(logEntries.last(), {name: 'capture', oldValue: '', newValue: 'user', namespace: null});
-}, 'capture on HTMLInputElement must enqueue an attributeChanged reaction when adding new attribute');
+        assert_array_equals(element.takeLog().types(), ['constructed']);
+        instance['capture'] = 'user';
+        const logEntries = element.takeLog();
+        assert_array_equals(logEntries.types(), ['attributeChanged']);
+        assert_attribute_log_entry(logEntries.last(), {name: 'capture', oldValue: '', newValue: 'user', namespace: null});
+    }, 'capture on HTMLInputElement must enqueue an attributeChanged reaction when adding new attribute');
 
-test(() => {
-    const element = define_build_in_custom_element(['capture'], HTMLInputElement, 'input');
-    const instance = document.createElement('input', { is: element.name });
+    test(() => {
+        const element = define_build_in_custom_element(['capture'], HTMLInputElement, 'input');
+        const instance = document.createElement('input', { is: element.name });
 
-    instance['capture'] = 'user';
-    assert_array_equals(element.takeLog().types(), ['constructed', 'attributeChanged']);
-    instance['capture'] = 'environment';
-    const logEntries = element.takeLog();
-    assert_array_equals(logEntries.types(), ['attributeChanged']);
-    assert_attribute_log_entry(logEntries.last(), {name: 'capture', oldValue: 'user', newValue: 'environment', namespace: null});
-}, 'capture on HTMLInputElement must enqueue an attributeChanged reaction when replacing an existing attribute');
+        instance['capture'] = 'user';
+        assert_array_equals(element.takeLog().types(), ['constructed', 'attributeChanged']);
+        instance['capture'] = 'environment';
+        const logEntries = element.takeLog();
+        assert_array_equals(logEntries.types(), ['attributeChanged']);
+        assert_attribute_log_entry(logEntries.last(), {name: 'capture', oldValue: 'user', newValue: 'environment', namespace: null});
+    }, 'capture on HTMLInputElement must enqueue an attributeChanged reaction when replacing an existing attribute');
 
-test(() => {
-    const element = define_build_in_custom_element(['capture'], HTMLInputElement, 'input');
-    const instance = document.createElement('input', { is: element.name });
+    test(() => {
+        const element = define_build_in_custom_element(['capture'], HTMLInputElement, 'input');
+        const instance = document.createElement('input', { is: element.name });
 
-    assert_array_equals(element.takeLog().types(), ['constructed']);
-    instance['capture'] = 'asdf';
-    const logEntries = element.takeLog();
-    assert_array_equals(logEntries.types(), ['attributeChanged']);
-    assert_attribute_log_entry(logEntries.last(), {name: 'capture', oldValue: '', newValue: 'asdf', namespace: null});
-}, 'capture on HTMLInputElement must enqueue an attributeChanged reaction when adding invalid value default');
+        assert_array_equals(element.takeLog().types(), ['constructed']);
+        instance['capture'] = 'asdf';
+        const logEntries = element.takeLog();
+        assert_array_equals(logEntries.types(), ['attributeChanged']);
+        assert_attribute_log_entry(logEntries.last(), {name: 'capture', oldValue: '', newValue: 'asdf', namespace: null});
+    }, 'capture on HTMLInputElement must enqueue an attributeChanged reaction when adding invalid value default');
 
+    test(() => {
+        const element = define_build_in_custom_element(['capture'], HTMLInputElement, 'input');
+        const instance = document.createElement('input', { is: element.name });
 
-test(() => {
-    const element = define_build_in_custom_element(['capture'], HTMLInputElement, 'input');
-    const instance = document.createElement('input', { is: element.name });
-
-    instance['capture'] = 'user';
-    assert_array_equals(element.takeLog().types(), ['constructed', 'attributeChanged']);
-    instance['capture'] = '';
-    const logEntries = element.takeLog();
-    assert_array_equals(logEntries.types(), ['attributeChanged']);
-    assert_attribute_log_entry(logEntries.last(), {name: 'capture', oldValue: 'user', newValue: '', namespace: null});
-}, 'capture on HTMLInputElement must enqueue an attributeChanged reaction when removing the attribute');
+        instance['capture'] = 'user';
+        assert_array_equals(element.takeLog().types(), ['constructed', 'attributeChanged']);
+        instance['capture'] = '';
+        const logEntries = element.takeLog();
+        assert_array_equals(logEntries.types(), ['attributeChanged']);
+        assert_attribute_log_entry(logEntries.last(), {name: 'capture', oldValue: 'user', newValue: '', namespace: null});
+    }, 'capture on HTMLInputElement must enqueue an attributeChanged reaction when removing the attribute');
+} else {
+    // testharness.js doesn't allow a test file with no tests.
+    test(() => {
+    }, 'No tests if HTMLInputEement has no "capture" IDL attribute');
+}
 </script>
 </body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/dom/interfaces-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/dom/interfaces-expected.txt
index 598bf3a..0e968dd8 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/html/dom/interfaces-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/dom/interfaces-expected.txt
@@ -4296,7 +4296,7 @@
 PASS OffscreenCanvas interface: existence and properties of interface prototype object's "constructor" property
 PASS OffscreenCanvas interface: attribute width
 PASS OffscreenCanvas interface: attribute height
-PASS OffscreenCanvas interface: operation getContext(OffscreenRenderingContextType, any)
+PASS OffscreenCanvas interface: operation getContext(OffscreenRenderingContextId, any)
 PASS OffscreenCanvas interface: operation transferToImageBitmap()
 PASS OffscreenCanvas interface: operation convertToBlob(ImageEncodeOptions)
 PASS OffscreenCanvasRenderingContext2D interface: existence and properties of interface object
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/the-input-element/image-click-form-data.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/the-input-element/image-click-form-data.html
new file mode 100644
index 0000000..908bf05f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/the-input-element/image-click-form-data.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Check form-data for image submit button with non-empty 'value' attribute</title>
+<link rel="author" title="Shanmuga Pandi" href="mailto:shanmuga.m@samsung.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#constructing-form-data-set">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<body>
+<script>
+"use strict";
+
+// promise_test instead of async_test because this test use window.success, and so can't run at the same time.
+
+promise_test(t => {
+  return new Promise(resolve => {
+    window.success = t.step_func(locationLoaded => {
+      const expected = (new URL("resources/image-submit-click.html?name.x=0&name.y=0", location.href)).href;
+      assert_equals(locationLoaded, expected);
+      resolve();
+    });
+
+    const iframe = document.createElement("iframe");
+    iframe.src = "resources/image-submit-click.html";
+    document.body.appendChild(iframe);
+  });
+}, "Image submit button should not add extra form data if 'value' attribute is present with non-empty value");
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/the-input-element/resources/image-submit-click.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/the-input-element/resources/image-submit-click.html
new file mode 100644
index 0000000..6db0a49
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/the-input-element/resources/image-submit-click.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<form>
+  <input type="image" name="name" value="value">
+</form>
+
+<script>
+"use strict";
+if (window.location.search.startsWith("?name.x")) {
+  // The action pointed to ourself, so the form submitted something
+  window.parent.success(window.location.href);
+} else {
+  const input = document.querySelector("input");
+  input.click();
+}
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/scripting/processing-model-2/unhandled-promise-rejections/promise-rejection-event-constructor.html b/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/scripting/processing-model-2/unhandled-promise-rejections/promise-rejection-event-constructor.html
index 109b10ead..17cc35c2 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/scripting/processing-model-2/unhandled-promise-rejections/promise-rejection-event-constructor.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/webappapis/scripting/processing-model-2/unhandled-promise-rejections/promise-rejection-event-constructor.html
@@ -33,7 +33,7 @@
   // reason is passed.
   var r = new Error();
   assert_equals(new PromiseRejectionEvent('eventType', { promise: p, reason: r }).reason, r);
-
+  assert_equals(new PromiseRejectionEvent('eventType', { promise: p, reason: null }).reason, null);
 
   // All initializers are passed.
   assert_equals(new PromiseRejectionEvent('eventType', { bubbles: true, cancelable: true, promise: p, reason: r }).bubbles, true);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event-respond-with-body-loaded-in-chunk.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event-respond-with-body-loaded-in-chunk.https.html
new file mode 100644
index 0000000..824b6f32
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event-respond-with-body-loaded-in-chunk.https.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>respondWith with a response whose body is being loaded from the network by chunks</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+'use strict';
+
+const WORKER = 'resources/fetch-event-respond-with-body-loaded-in-chunk-worker.js';
+const SCOPE = 'resources/fetch-event-respond-with-body-loaded-in-chunk-iframe.html';
+
+promise_test(async t => {
+    var reg = await service_worker_unregister_and_register(t, WORKER, SCOPE);
+    add_completion_callback(() => reg.unregister());
+    await wait_for_state(t, reg.installing, 'activated');
+    let iframe = await with_iframe(SCOPE);
+    t.add_cleanup(() => iframe.remove());
+
+    let response = await iframe.contentWindow.fetch('body-in-chunk');
+    assert_equals(await response.text(), 'TEST_TRICKLE\nTEST_TRICKLE\nTEST_TRICKLE\nTEST_TRICKLE\n');
+}, 'Respond by chunks with a Response being loaded');
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event-respond-with-readable-stream-chunk.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event-respond-with-readable-stream-chunk.https.html
new file mode 100644
index 0000000..4544a9e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event-respond-with-readable-stream-chunk.https.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>respondWith with a response built from a ReadableStream</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+'use strict';
+
+const WORKER = 'resources/fetch-event-respond-with-readable-stream-chunk-worker.js';
+const SCOPE = 'resources/fetch-event-respond-with-readable-stream-chunk-iframe.html';
+
+promise_test(async t => {
+    var reg = await service_worker_unregister_and_register(t, WORKER, SCOPE);
+    add_completion_callback(() => reg.unregister());
+    await wait_for_state(t, reg.installing, 'activated');
+    let iframe = await with_iframe(SCOPE);
+    t.add_cleanup(() => iframe.remove());
+
+    let response = await iframe.contentWindow.fetch('body-stream');
+    assert_equals(await response.text(), 'chunk #1 chunk #2 chunk #3 chunk #4');
+}, 'Respond by chunks with a Response built from a ReadableStream');
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt
index 2eea3cb..8a9c737 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt
@@ -3,7 +3,7 @@
 PASS Service Worker responds to fetch event with string
 PASS Service Worker responds to fetch event with blob body
 PASS Service Worker responds to fetch event with the referrer URL
-FAIL Service Worker responds to fetch event with an existing client id assert_unreached: unexpected rejection: assert_equals: Service Worker should respond to fetch with a client id expected "Client ID Not Found" but got "Client ID Found: null" Reached unreachable code
+PASS Service Worker responds to fetch event with an existing client id
 PASS Service Worker does not respond to fetch event
 PASS Service Worker responds to fetch event with null response body
 PASS Service Worker fetches other file in fetch event
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-request-resources.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-request-resources.https.html
index 92ef468..336e6ed8 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-request-resources.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/fetch-request-resources.https.html
@@ -8,6 +8,14 @@
 var url_count = 0;
 var expected_results = {};
 
+function add_promise_to_test(url)
+{
+  var expected = expected_results[url];
+  return new Promise((resolve) => {
+    expected.resolve = resolve;
+  });
+}
+
 function image_test(frame, url, cross_origin, expected_mode,
                     expected_credentials) {
   var actual_url = url + (++url_count);
@@ -20,7 +28,8 @@
       message: 'Image load (url:' +
                actual_url + ' cross_origin:' + cross_origin + ')'
     };
-  return frame.contentWindow.load_image(actual_url, cross_origin);
+  frame.contentWindow.load_image(actual_url, cross_origin);
+  return add_promise_to_test(actual_url);
 }
 
 function script_test(frame, url, cross_origin, expected_mode,
@@ -35,7 +44,8 @@
       message: 'Script load (url:' +
                actual_url + ' cross_origin:' + cross_origin + ')'
     };
-  return frame.contentWindow.load_script(actual_url, cross_origin);
+  frame.contentWindow.load_script(actual_url, cross_origin);
+  return add_promise_to_test(actual_url);
 }
 
 function css_test(frame, url, cross_origin, expected_mode,
@@ -50,7 +60,8 @@
       message: 'CSS load (url:' +
                actual_url + ' cross_origin:' + cross_origin + ')'
     };
-  return frame.contentWindow.load_css(actual_url, cross_origin);
+  frame.contentWindow.load_css(actual_url, cross_origin);
+  return add_promise_to_test(actual_url);
 }
 
 function font_face_test(frame, url, expected_mode, expected_credentials) {
@@ -63,7 +74,8 @@
       integrity: '',
       message: 'FontFace load (url:' + actual_url + ')'
     };
-  return frame.contentWindow.load_font(actual_url);
+  frame.contentWindow.load_font(actual_url);
+  return add_promise_to_test(actual_url);
 }
 
 function script_integrity_test(frame, url, integrity, expected_integrity) {
@@ -76,7 +88,8 @@
       integrity: expected_integrity,
       message: 'Script load (url:' + actual_url + ')'
     };
-  return frame.contentWindow.load_script_with_integrity(actual_url, integrity);
+  frame.contentWindow.load_script_with_integrity(actual_url, integrity);
+  return add_promise_to_test(actual_url);
 }
 
 function css_integrity_test(frame, url, integrity, expected_integrity) {
@@ -89,7 +102,8 @@
       integrity: expected_integrity,
       message: 'CSS load (url:' + actual_url + ')'
     };
-  return frame.contentWindow.load_css_with_integrity(actual_url, integrity);
+  frame.contentWindow.load_css_with_integrity(actual_url, integrity);
+  return add_promise_to_test(actual_url);
 }
 
 function fetch_test(frame, url, mode, credentials,
@@ -103,8 +117,10 @@
       message: 'fetch (url:' + actual_url + ' mode:' + mode + ' credentials:' +
                credentials + ')'
     };
-  return frame.contentWindow.fetch(
-      new Request(actual_url, {mode: mode, credentials: credentials}));
+  frame.contentWindow.fetch(
+      new Request(actual_url, {mode: mode, credentials: credentials})).then(() => {
+      }, () => { });
+  return add_promise_to_test(actual_url);
 }
 
 function audio_test(frame, url, cross_origin,
@@ -118,10 +134,11 @@
       message: 'Audio load (url:' + actual_url + ' cross_origin:' +
                cross_origin + ')'
     };
-  return frame.contentWindow.load_audio(actual_url, cross_origin);
+  frame.contentWindow.load_audio(actual_url, cross_origin);
+  return add_promise_to_test(actual_url);
 }
 
-async_test(function(t) {
+promise_test(function(t) {
     var SCOPE = 'resources/fetch-request-resources-iframe.https.html';
     var SCRIPT = 'resources/fetch-request-resources-worker.js';
     var host_info = get_host_info();
@@ -131,13 +148,13 @@
       host_info['HTTPS_REMOTE_ORIGIN'] + base_path() + 'resources/dummy?test';
     var worker;
     var frame;
-    service_worker_unregister_and_register(t, SCRIPT, SCOPE)
+    return service_worker_unregister_and_register(t, SCRIPT, SCOPE)
       .then(function(registration) {
           worker = registration.installing;
           return wait_for_state(t, worker, 'activated');
         })
       .then(function() {
-          return new Promise(function(resolve) {
+          return new Promise(function(resolve, reject) {
               var channel = new MessageChannel();
               channel.port1.onmessage = t.step_func(function(msg) {
                 if (msg.data.ready) {
@@ -149,110 +166,110 @@
                 if (!expected) {
                   return;
                 }
-                assert_equals(
+                test(() => {
+                  assert_equals(
                     result.mode, expected.mode,
                     'mode of ' + expected.message +  ' must be ' +
                     expected.mode + '.');
-                assert_equals(
+                  assert_equals(
                     result.credentials, expected.credentials,
                     'credentials of ' + expected.message +  ' must be ' +
                     expected.credentials + '.');
-                 assert_equals(
+                   assert_equals(
                     result.redirect, expected.redirect,
                     'redirect mode of ' + expected.message +  ' must be ' +
                     expected.redirect + '.');
-                assert_equals(
+                  assert_equals(
                     result.integrity, expected.integrity,
                     'integrity of ' + expected.message +  ' must be ' +
                     expected.integrity + '.');
-                --url_count;
+                }, expected.message);
+                expected.resolve();
                 delete expected_results[result.url];
-                if (url_count == 0) {
-                  frame.remove();
-                  service_worker_unregister_and_done(t, SCOPE);
-                }
               });
               worker.postMessage(
                 {port: channel.port2}, [channel.port2]);
             });
         })
       .then(function() { return with_iframe(SCOPE); })
-      .then(function(f) {
+      .then(async function(f) {
         frame = f;
 
-        image_test(f, LOCAL_URL, '', 'no-cors', 'include');
-        image_test(f, REMOTE_URL, '', 'no-cors', 'include');
-        css_test(f, LOCAL_URL, '', 'no-cors', 'include');
-        css_test(f, REMOTE_URL, '', 'no-cors', 'include');
+        await image_test(f, LOCAL_URL, '', 'no-cors', 'include');
+        await image_test(f, REMOTE_URL, '', 'no-cors', 'include');
+        await css_test(f, LOCAL_URL, '', 'no-cors', 'include');
+        await css_test(f, REMOTE_URL, '', 'no-cors', 'include');
 
-        image_test(f, LOCAL_URL, 'anonymous', 'cors', 'same-origin');
-        image_test(f, LOCAL_URL, 'use-credentials', 'cors', 'include');
-        image_test(f, REMOTE_URL, '', 'no-cors', 'include');
-        image_test(f, REMOTE_URL, 'anonymous', 'cors', 'same-origin');
-        image_test(f, REMOTE_URL, 'use-credentials', 'cors', 'include');
+        await image_test(f, LOCAL_URL, 'anonymous', 'cors', 'same-origin');
+        await image_test(f, LOCAL_URL, 'use-credentials', 'cors', 'include');
+        await image_test(f, REMOTE_URL, '', 'no-cors', 'include');
+        await image_test(f, REMOTE_URL, 'anonymous', 'cors', 'same-origin');
+        await image_test(f, REMOTE_URL, 'use-credentials', 'cors', 'include');
 
-        script_test(f, LOCAL_URL, '', 'no-cors', 'include');
-        script_test(f, LOCAL_URL, 'anonymous', 'cors', 'same-origin');
-        script_test(f, LOCAL_URL, 'use-credentials', 'cors', 'include');
-        script_test(f, REMOTE_URL, '', 'no-cors', 'include');
-        script_test(f, REMOTE_URL, 'anonymous', 'cors', 'same-origin');
-        script_test(f, REMOTE_URL, 'use-credentials', 'cors', 'include');
+        await script_test(f, LOCAL_URL, '', 'no-cors', 'include');
+        await script_test(f, LOCAL_URL, 'anonymous', 'cors', 'same-origin');
+        await script_test(f, LOCAL_URL, 'use-credentials', 'cors', 'include');
+        await script_test(f, REMOTE_URL, '', 'no-cors', 'include');
+        await script_test(f, REMOTE_URL, 'anonymous', 'cors', 'same-origin');
+        await script_test(f, REMOTE_URL, 'use-credentials', 'cors', 'include');
 
-        css_test(f, LOCAL_URL, '', 'no-cors', 'include');
-        css_test(f, LOCAL_URL, 'anonymous', 'cors', 'same-origin');
-        css_test(f, LOCAL_URL, 'use-credentials', 'cors', 'include');
-        css_test(f, REMOTE_URL, '', 'no-cors', 'include');
-        css_test(f, REMOTE_URL, 'anonymous', 'cors', 'same-origin');
-        css_test(f, REMOTE_URL, 'use-credentials', 'cors', 'include');
+        await css_test(f, LOCAL_URL, '', 'no-cors', 'include');
+        await css_test(f, LOCAL_URL, 'anonymous', 'cors', 'same-origin');
+        await css_test(f, LOCAL_URL, 'use-credentials', 'cors', 'include');
+        await css_test(f, REMOTE_URL, '', 'no-cors', 'include');
+        await css_test(f, REMOTE_URL, 'anonymous', 'cors', 'same-origin');
+        await css_test(f, REMOTE_URL, 'use-credentials', 'cors', 'include');
 
-        font_face_test(f, LOCAL_URL, 'cors', 'same-origin');
-        font_face_test(f, REMOTE_URL, 'cors', 'same-origin');
+        await font_face_test(f, LOCAL_URL, 'cors', 'same-origin');
+        await font_face_test(f, REMOTE_URL, 'cors', 'same-origin');
 
-        script_integrity_test(f, LOCAL_URL, '     ', '     ');
-        script_integrity_test(f, LOCAL_URL,
-                              'This is not a valid integrity because it has no dashes',
-                              'This is not a valid integrity because it has no dashes');
-        script_integrity_test(f, LOCAL_URL, 'sha256-', 'sha256-');
-        script_integrity_test(f, LOCAL_URL, 'sha256-foo?123', 'sha256-foo?123');
-        script_integrity_test(f, LOCAL_URL, 'sha256-foo sha384-abc ', 'sha256-foo sha384-abc ');
-        script_integrity_test(f, LOCAL_URL, 'sha256-foo sha256-abc', 'sha256-foo sha256-abc');
+        await script_integrity_test(f, LOCAL_URL, '     ', '     ');
+        await script_integrity_test(f, LOCAL_URL,
+                               'This is not a valid integrity because it has no dashes',
+                               'This is not a valid integrity because it has no dashes');
+        await script_integrity_test(f, LOCAL_URL, 'sha256-', 'sha256-');
+        await script_integrity_test(f, LOCAL_URL, 'sha256-foo?123', 'sha256-foo?123');
+        await script_integrity_test(f, LOCAL_URL, 'sha256-foo sha384-abc ', 'sha256-foo sha384-abc ');
+        await script_integrity_test(f, LOCAL_URL, 'sha256-foo sha256-abc', 'sha256-foo sha256-abc');
 
-        css_integrity_test(f, LOCAL_URL, '     ', '     ');
-        css_integrity_test(f, LOCAL_URL,
-                           'This is not a valid integrity because it has no dashes',
-                           'This is not a valid integrity because it has no dashes');
-        css_integrity_test(f, LOCAL_URL, 'sha256-', 'sha256-');
-        css_integrity_test(f, LOCAL_URL, 'sha256-foo?123', 'sha256-foo?123');
-        css_integrity_test(f, LOCAL_URL, 'sha256-foo sha384-abc ', 'sha256-foo sha384-abc ');
-        css_integrity_test(f, LOCAL_URL, 'sha256-foo sha256-abc', 'sha256-foo sha256-abc');
+        await css_integrity_test(f, LOCAL_URL, '     ', '     ');
+        await css_integrity_test(f, LOCAL_URL,
+                            'This is not a valid integrity because it has no dashes',
+                            'This is not a valid integrity because it has no dashes');
+        await css_integrity_test(f, LOCAL_URL, 'sha256-', 'sha256-');
+        await css_integrity_test(f, LOCAL_URL, 'sha256-foo?123', 'sha256-foo?123');
+        await css_integrity_test(f, LOCAL_URL, 'sha256-foo sha384-abc ', 'sha256-foo sha384-abc ');
+        await css_integrity_test(f, LOCAL_URL, 'sha256-foo sha256-abc', 'sha256-foo sha256-abc');
 
-        fetch_test(f, LOCAL_URL, 'same-origin', 'omit', 'same-origin', 'omit');
-        fetch_test(f, LOCAL_URL, 'same-origin', 'same-origin',
-                   'same-origin', 'same-origin');
-        fetch_test(f, LOCAL_URL, 'same-origin', 'include',
-                   'same-origin', 'include');
-        fetch_test(f, LOCAL_URL, 'no-cors', 'omit', 'no-cors', 'omit');
-        fetch_test(f, LOCAL_URL, 'no-cors', 'same-origin',
-                   'no-cors', 'same-origin');
-        fetch_test(f, LOCAL_URL, 'no-cors', 'include', 'no-cors', 'include');
-        fetch_test(f, LOCAL_URL, 'cors', 'omit', 'cors', 'omit');
-        fetch_test(f, LOCAL_URL, 'cors', 'same-origin', 'cors', 'same-origin');
-        fetch_test(f, LOCAL_URL, 'cors', 'include', 'cors', 'include');
-        fetch_test(f, REMOTE_URL, 'no-cors', 'omit', 'no-cors', 'omit');
-        fetch_test(f, REMOTE_URL, 'no-cors', 'same-origin',
-                   'no-cors', 'same-origin');
-        fetch_test(f, REMOTE_URL, 'no-cors', 'include', 'no-cors', 'include');
-        fetch_test(f, REMOTE_URL, 'cors', 'omit', 'cors', 'omit');
-        fetch_test(f, REMOTE_URL, 'cors', 'same-origin', 'cors', 'same-origin');
-        fetch_test(f, REMOTE_URL, 'cors', 'include', 'cors', 'include');
+        await fetch_test(f, LOCAL_URL, 'same-origin', 'omit', 'same-origin', 'omit');
+        await fetch_test(f, LOCAL_URL, 'same-origin', 'same-origin',
+                    'same-origin', 'same-origin');
+        await fetch_test(f, LOCAL_URL, 'same-origin', 'include',
+                    'same-origin', 'include');
+        await fetch_test(f, LOCAL_URL, 'no-cors', 'omit', 'no-cors', 'omit');
+        await fetch_test(f, LOCAL_URL, 'no-cors', 'same-origin',
+                    'no-cors', 'same-origin');
+        await fetch_test(f, LOCAL_URL, 'no-cors', 'include', 'no-cors', 'include');
+        await fetch_test(f, LOCAL_URL, 'cors', 'omit', 'cors', 'omit');
+        await fetch_test(f, LOCAL_URL, 'cors', 'same-origin', 'cors', 'same-origin');
+        await fetch_test(f, LOCAL_URL, 'cors', 'include', 'cors', 'include');
+        await fetch_test(f, REMOTE_URL, 'no-cors', 'omit', 'no-cors', 'omit');
+        await fetch_test(f, REMOTE_URL, 'no-cors', 'same-origin',
+                    'no-cors', 'same-origin');
+        await fetch_test(f, REMOTE_URL, 'no-cors', 'include', 'no-cors', 'include');
+        await fetch_test(f, REMOTE_URL, 'cors', 'omit', 'cors', 'omit');
+        await fetch_test(f, REMOTE_URL, 'cors', 'same-origin', 'cors', 'same-origin');
+        await fetch_test(f, REMOTE_URL, 'cors', 'include', 'cors', 'include');
 
-        audio_test(f, LOCAL_URL, '', 'no-cors', 'include');
-        audio_test(f, LOCAL_URL, 'anonymous', 'cors', 'same-origin');
-        audio_test(f, LOCAL_URL, 'use-credentials', 'cors', 'include');
-        audio_test(f, REMOTE_URL, '', 'no-cors', 'include');
-        audio_test(f, REMOTE_URL, 'anonymous', 'cors', 'same-origin');
-        audio_test(f, REMOTE_URL, 'use-credentials', 'cors', 'include');
-      })
-      .catch(unreached_rejection(t));
+        await audio_test(f, LOCAL_URL, '', 'no-cors', 'include');
+        await audio_test(f, LOCAL_URL, 'anonymous', 'cors', 'same-origin');
+        await audio_test(f, LOCAL_URL, 'use-credentials', 'cors', 'include');
+        await audio_test(f, REMOTE_URL, '', 'no-cors', 'include');
+        await audio_test(f, REMOTE_URL, 'anonymous', 'cors', 'same-origin');
+        await audio_test(f, REMOTE_URL, 'use-credentials', 'cors', 'include');
+
+        frame.remove();
+        service_worker_unregister(t, SCOPE);
+      }).catch(unreached_rejection(t));
   }, 'Verify FetchEvent for resources.');
 </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/interfaces-sw.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/interfaces-sw.https-expected.txt
index cb96af7..d8dd6b5 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/interfaces-sw.https-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/interfaces-sw.https-expected.txt
@@ -1,7 +1,7 @@
 This is a testharness.js-based test.
 PASS Interfaces and attributes in ServiceWorkerGlobalScope
 PASS test setup (cache creation)
-FAIL Event constructors assert_equals: Default FetchEvent.clientId should be the empty string expected (string) "" but got (object) null
+FAIL Event constructors assert_equals: FetchEvent.isReload should not exist expected (undefined) undefined but got (boolean) false
 PASS xhr is not exposed
 PASS ServiceWorkerGlobalScope interface: existence and properties of interface object
 PASS ServiceWorkerGlobalScope interface object length
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/request-end-to-end.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/request-end-to-end.https.html
index 7b594aa..a39cead 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/request-end-to-end.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/request-end-to-end.https.html
@@ -23,9 +23,9 @@
           assert_equals(result.method, 'GET', 'request.method');
           assert_equals(result.referrer, location.href, 'request.referrer');
           assert_equals(result.mode, 'navigate', 'request.mode');
-          assert_equals(result.request_construct_error, 'TypeError',
+          assert_equals(result.request_construct_error, '',
                         'Constructing a Request with a Request whose mode ' +
-                        'is navigate and non-empty RequestInit must throw a ' +
+                        'is navigate and non-empty RequestInit must not throw a ' +
                         'TypeError.')
           assert_equals(result.credentials, 'include', 'request.credentials');
           assert_equals(result.redirect, 'manual', 'request.redirect');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/client-navigate-worker.js b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/client-navigate-worker.js
index 09d11fe..aff2b37a 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/client-navigate-worker.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/client-navigate-worker.js
@@ -5,11 +5,6 @@
 
 self.onfetch = function(e) {
   if (e.request.url.indexOf("client-navigate-frame.html") >= 0) {
-    if (e.clientId === null) {
-      e.respondWith(fetch(e.request));
-    } else {
-      e.respondWith(Response.error());
-    }
     return;
   }
   e.respondWith(new Response(e.clientId));
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-event-respond-with-body-loaded-in-chunk-worker.js b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-event-respond-with-body-loaded-in-chunk-worker.js
new file mode 100644
index 0000000..d3ba8a8d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-event-respond-with-body-loaded-in-chunk-worker.js
@@ -0,0 +1,7 @@
+'use strict';
+
+self.addEventListener('fetch', event => {
+    if (!event.request.url.match(/body-in-chunk$/))
+        return;
+    event.respondWith(fetch("../../../fetch/api/resources/trickle.py?count=4&delay=50"));
+});
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-chunk-worker.js b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-chunk-worker.js
new file mode 100644
index 0000000..f954e3a1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-event-respond-with-readable-stream-chunk-worker.js
@@ -0,0 +1,40 @@
+'use strict';
+
+self.addEventListener('fetch', event => {
+    if (!event.request.url.match(/body-stream$/))
+        return;
+
+    var counter = 0;
+    const encoder = new TextEncoder();
+    const stream = new ReadableStream({ pull: controller => {
+        switch (++counter) {
+        case 1:
+            controller.enqueue(encoder.encode(''));
+            return;
+        case 2:
+            controller.enqueue(encoder.encode('chunk #1'));
+            return;
+        case 3:
+            controller.enqueue(encoder.encode(' '));
+            return;
+        case 4:
+            controller.enqueue(encoder.encode('chunk #2'));
+            return;
+        case 5:
+            controller.enqueue(encoder.encode(' '));
+            return;
+        case 6:
+            controller.enqueue(encoder.encode('chunk #3'));
+            return;
+        case 7:
+            controller.enqueue(encoder.encode(' '));
+            return;
+        case 8:
+            controller.enqueue(encoder.encode('chunk #4'));
+            return;
+        default:
+            controller.close();
+        }
+    }});
+    event.respondWith(new Response(stream));
+});
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html
index 867bf238..ab3e2a1 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html
@@ -179,7 +179,7 @@
           '\r\n' +
           'file content\r\n' +
           '--' + boundary + '--\r\n';
-        assert_equals(response.body, expected_body);
+        assert_true(response.body === expected_body, "form data response content is as expected");
       });
 }
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/register-closed-window-iframe.html b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/register-closed-window-iframe.html
index ed743ea..117f254 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/register-closed-window-iframe.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/service-workers/service-worker/resources/register-closed-window-iframe.html
@@ -1,14 +1,17 @@
 <html>
 <head>
 <script>
-window.addEventListener('message', function(evt) {
+window.addEventListener('message', async function(evt) {
   if (evt.data === 'START') {
     var w = window.open('./');
     var sw = w.navigator.serviceWorker;
     w.close();
     w = null;
-    sw.register('doesntmatter.js');
-    parent.postMessage('OK', '*');
+    try {
+      await sw.register('doesntmatter.js');
+    } finally {
+      parent.postMessage('OK', '*');
+    }
   }
 });
 </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https-expected.txt
index 9f83b47..35a4800 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-tracks.https-expected.txt
@@ -12,6 +12,6 @@
 PASS stream.onremovetrack fires before setRemoteDescription resolves.
 PASS removeTrack() makes track.onmute fire and the track to be muted.
 PASS track.onmute fires before setRemoteDescription resolves.
-PASS removeTrack() twice is safe.
+FAIL removeTrack() twice is safe. Failed to execute 'removeTrack' on 'RTCPeerConnection': The sender was not created by this peer connection.
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webvtt/api/VTTRegion/constructor.html b/third_party/WebKit/LayoutTests/external/wpt/webvtt/api/VTTRegion/constructor.html
index 59eeaf8..cddde0a0 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webvtt/api/VTTRegion/constructor.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webvtt/api/VTTRegion/constructor.html
@@ -40,7 +40,6 @@
         }
     }
 
-    assert_throws("IndexSizeError", function() { region.lines = -1; });
     assert_equals(region.lines, 3);
 
     region.lines = 130;
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webvtt/api/VTTRegion/lines.html b/third_party/WebKit/LayoutTests/external/wpt/webvtt/api/VTTRegion/lines.html
index a9be610..90e08b4 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webvtt/api/VTTRegion/lines.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webvtt/api/VTTRegion/lines.html
@@ -17,8 +17,12 @@
     // https://heycam.github.io/webidl/#abstract-opdef-converttoint
     [[0, 0],
      [-0, 0],
+     [-1, 4294967295],
+     [-100, 4294967196],
      [101, 101],
+     [-2147483648, 2147483648],
      [2147483647, 2147483647],
+     [2147483648, 2147483648],
      [NaN, 0],
      [Infinity, 0],
      [-Infinity, 0]].forEach(function (pair) {
@@ -28,10 +32,5 @@
         assert_equals(region.lines, expected);
     });
 
-    [-1, -100, -2147483648, 2147483648 /* wraps to -2147483648 */].forEach(function (invalid) {
-        assert_throws('IndexSizeError', function() {
-          region.lines = invalid;
-        }, invalid);
-    });
 }, document.title + ' script-created region');
 </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webvtt/parsing/file-parsing/tests/regions-lines-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/webvtt/parsing/file-parsing/tests/regions-lines-expected.txt
index 1044a37..281a7b0c 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webvtt/parsing/file-parsing/tests/regions-lines-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/webvtt/parsing/file-parsing/tests/regions-lines-expected.txt
@@ -1,4 +1,4 @@
 This is a testharness.js-based test.
-FAIL regions, lines assert_equals: Failed with region 5 expected 4294967296 but got 2147483647
+FAIL regions, lines assert_equals: Failed with region 5 expected 4294967296 but got 4294967295
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/fast/css/fontface-properties-expected.txt b/third_party/WebKit/LayoutTests/fast/css/fontface-properties-expected.txt
index 541e3a0c..44c0cd73 100644
--- a/third_party/WebKit/LayoutTests/fast/css/fontface-properties-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/css/fontface-properties-expected.txt
@@ -8,7 +8,7 @@
 PASS ahemFace.weight is "300"
 PASS ahemFace.unicodeRange is "U+0-3FF"
 PASS ahemFace.variant is "small-caps"
-PASS ahemFace.featureSettings is "\"dlig\" 1"
+PASS ahemFace.featureSettings is "\"dlig\""
 PASS ahemFace.display is "block"
 
 PASS defaultFace.family is "defaultFace"
@@ -33,7 +33,7 @@
 PASS modifiedFace.weight is "900"
 PASS modifiedFace.unicodeRange is "U+0-3FF"
 PASS modifiedFace.variant is "small-caps"
-PASS modifiedFace.featureSettings is "\"dlig\" 1, \"liga\" 0"
+PASS modifiedFace.featureSettings is "\"dlig\", \"liga\" 0"
 PASS modifiedFace.display is "fallback"
 
 PASS face.style = '' threw exception SyntaxError: Failed to set the 'style' property on 'FontFace': Failed to set '' as a property value..
diff --git a/third_party/WebKit/LayoutTests/fast/css/fontface-properties.html b/third_party/WebKit/LayoutTests/fast/css/fontface-properties.html
index 79430704a..97659680 100644
--- a/third_party/WebKit/LayoutTests/fast/css/fontface-properties.html
+++ b/third_party/WebKit/LayoutTests/fast/css/fontface-properties.html
@@ -31,7 +31,7 @@
     shouldBeEqualToString('ahemFace.weight', '300');
     shouldBeEqualToString('ahemFace.unicodeRange', 'U+0-3FF');
     shouldBeEqualToString('ahemFace.variant', 'small-caps');
-    shouldBeEqualToString('ahemFace.featureSettings', '"dlig" 1');
+    shouldBeEqualToString('ahemFace.featureSettings', '"dlig"');
     shouldBeEqualToString('ahemFace.display', 'block');
 
     debug('');
@@ -76,7 +76,7 @@
     shouldBeEqualToString('modifiedFace.weight', '900');
     shouldBeEqualToString('modifiedFace.unicodeRange', 'U+0-3FF');
     shouldBeEqualToString('modifiedFace.variant', 'small-caps');
-    shouldBeEqualToString('modifiedFace.featureSettings', '"dlig" 1, "liga" 0');
+    shouldBeEqualToString('modifiedFace.featureSettings', '"dlig", "liga" 0');
     shouldBeEqualToString('modifiedFace.display', 'fallback');
 
     debug('');
diff --git a/third_party/WebKit/LayoutTests/fast/css/inherited-properties-rare-text-expected.txt b/third_party/WebKit/LayoutTests/fast/css/inherited-properties-rare-text-expected.txt
index 9cd7fb9..b3cef6f4 100644
--- a/third_party/WebKit/LayoutTests/fast/css/inherited-properties-rare-text-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/css/inherited-properties-rare-text-expected.txt
@@ -1,4 +1,4 @@
-test1 -webkit-font-feature-settings: "dlig" 1
+test1 -webkit-font-feature-settings: "dlig"
 test2 -webkit-font-feature-settings: normal
 test1 -webkit-font-smoothing: antialiased
 test2 -webkit-font-smoothing: auto
diff --git a/third_party/WebKit/LayoutTests/fast/dom/custom/crash-in-getTypeExtension.html b/third_party/WebKit/LayoutTests/fast/dom/custom/crash-in-getTypeExtension.html
index dd759ff..a1426453 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/custom/crash-in-getTypeExtension.html
+++ b/third_party/WebKit/LayoutTests/fast/dom/custom/crash-in-getTypeExtension.html
@@ -6,9 +6,7 @@
   // TODO(a.obzhirov): Use customElements.define when customized built-in elements are supported.
   document.registerElement('x-foo', { prototype: Object.create(HTMLDivElement.prototype) });
   var toStringCalled = false;
-  assert_throws('NotFoundError', () => {
-    document.createElement('div', { toString: () => { toStringCalled = true; return 'x-foo'; } })
-  });
+  document.createElement('div', { toString: () => { toStringCalled = true; return 'x-foo'; } })
   assert_false(toStringCalled, 'toString should not have been called.');
 }, 'Test for crbug/666610: Crash in blink::getTypeExtension');
 </script>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/image/input-image-submit.html b/third_party/WebKit/LayoutTests/fast/forms/image/input-image-submit.html
index 8bc2368..1b5e9c64 100644
--- a/third_party/WebKit/LayoutTests/fast/forms/image/input-image-submit.html
+++ b/third_party/WebKit/LayoutTests/fast/forms/image/input-image-submit.html
@@ -62,8 +62,8 @@
         state.value = 'normal';
         image.dispatchEvent(clickEvent);
     } else if (query.indexOf('state=normal') != -1) {
-        // Should have image.x=7&image.y=11&image=value.
-        if (query.indexOf('image.x=7&image.y=11&image=value') == -1) {
+        // Should have image.x=7&image.y=11.
+        if (query.indexOf('image.x=7&image.y=11') == -1) {
             failAndDone('Normal submission failed: ' + query);
             return;
         }
@@ -72,7 +72,7 @@
         state.value = 'click-method';
         image.click();
     } else if (query.indexOf('state=click-method') != -1) {
-        if (query.indexOf('image.x=0&image.y=0&image=value') == -1) {
+        if (query.indexOf('image.x=0&image.y=0') == -1) {
             failAndDone('Click method failed: ' + query);
             return;
         }
@@ -87,7 +87,7 @@
             return;
         }
     } else if (query.indexOf('state=keyboard') != -1) {
-        if (query.indexOf('image.x=0&image.y=0&image=value') == -1) {
+        if (query.indexOf('image.x=0&image.y=0') == -1) {
             failAndDone('Activating with keyboard failed: ' + query);
             return;
         }
@@ -109,7 +109,7 @@
         eventSender.keyDown('Enter');
     } else if (query.indexOf('state=to-image-on-submit') != -1) {
         // Should have image.x and image.y, but their values are 0.
-        if (query.indexOf('image.x=0&image.y=0&image=value') == -1) {
+        if (query.indexOf('image.x=0&image.y=0') == -1) {
             failAndDone('Changing to image on submit failed: ' + query);
             return;
         }
@@ -120,7 +120,7 @@
         image.dispatchEvent(clickEvent);
     } else if (query.indexOf('state=to-image-on-click') != -1) {
         // Same as the normal submission.
-        if (query.indexOf('image.x=7&image.y=11&image=value') == -1) {
+        if (query.indexOf('image.x=7&image.y=11') == -1) {
             failAndDone('Changing to image on click failed: ' + query);
             return;
         }
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/border-radius-clipped-layer-expected.html b/third_party/WebKit/LayoutTests/fast/multicol/border-radius-clipped-layer-expected.html
index fa00094..7a9042c1 100644
--- a/third_party/WebKit/LayoutTests/fast/multicol/border-radius-clipped-layer-expected.html
+++ b/third_party/WebKit/LayoutTests/fast/multicol/border-radius-clipped-layer-expected.html
@@ -1,8 +1,8 @@
 <!DOCTYPE html>
 <p>There should be a box with a rounded border and yellow background below. The start should be in
     the first column. The end should be in the third column.</p>
-<div style="width:41em; height:10.5em; line-height:2em;">
-    <div style="float:left; width:13em; height:100%; overflow:hidden;">
+<div style="width:41em; height:10.5em; line-height:2em; position:absolute; clip:rect(0,42em,10.5em,-1em);">
+    <div style="float:left; width:13em; height:100%;">
         <br>
         <div style="border-radius:3em; border:1em solid black; padding:0 2em; background:yellow;">
             first column<br>
@@ -13,7 +13,7 @@
         </div>
     </div>
     <div style="float:left; width:1em; height:100%;"></div>
-    <div style="float:left; width:13em; height:100%; overflow:hidden;">
+    <div style="float:left; width:13em; height:100%;">
         <div style="margin-top:-7em; border-radius:3em; border:1em solid black; padding:0 2em; background:yellow;">
             first column<br>
             first column<br>
@@ -28,7 +28,7 @@
         </div>
     </div>
     <div style="float:left; width:1em; height:100%;"></div>
-    <div style="float:left; width:13em; height:100%; overflow:hidden;">
+    <div style="float:left; width:13em; height:100%;">
         <div style="margin-top:-17em; border-radius:3em; border:1em solid black; padding:0 2em; background:yellow;">
             first column<br>
             first column<br>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/border-radius-clipped-layer.html b/third_party/WebKit/LayoutTests/fast/multicol/border-radius-clipped-layer.html
index c4d74688..f08e03b 100644
--- a/third_party/WebKit/LayoutTests/fast/multicol/border-radius-clipped-layer.html
+++ b/third_party/WebKit/LayoutTests/fast/multicol/border-radius-clipped-layer.html
@@ -3,7 +3,7 @@
     the first column. The end should be in the third column.</p>
 <div style="-webkit-columns:3; -webkit-column-gap:1em; column-fill:auto; width:41em; height:10.5em; line-height:2em; orphans:1; widows:1;">
     <br>
-    <div style="position:relative; overflow:hidden; border-radius:3em; border:1em solid black; padding:0 2em; background:yellow;">
+    <div style="position:relative; border-radius:3em; border:1em solid black; padding:0 2em; background:yellow;">
         first column<br>
         first column<br>
         first column<br>
diff --git a/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-AddRemoveTrack.html b/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-AddRemoveTrack.html
index 830cfdc..b494625 100644
--- a/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-AddRemoveTrack.html
+++ b/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-AddRemoveTrack.html
@@ -27,10 +27,7 @@
       let track = stream.getAudioTracks()[0];
       let sender = pc.addTrack(track, stream);
       assert_equals(sender.track, track);
-      // TODO(hbos): |addTrack| does not add to the set of local streams. When
-      // |getLocalStreams| is updated to return the streams of all senders this
-      // would have an observable effect here. https://crbug.com/738918
-      assert_array_equals(pc.getLocalStreams(), []);
+      assert_array_equals(pc.getLocalStreams(), [ stream ]);
     });
 }, 'addTrack() for a single track and its stream.');
 
@@ -43,10 +40,7 @@
       let streamB = streams[1];
       let sender = pc.addTrack(trackA, streamB);
       assert_equals(sender.track, trackA);
-      // TODO(hbos): |addTrack| does not add to the set of local streams. When
-      // |getLocalStreams| is updated to return the streams of all senders this
-      // would have an observable effect here. https://crbug.com/738918
-      assert_array_equals(pc.getLocalStreams(), []);
+      assert_array_equals(pc.getLocalStreams(), [ streamB ]);
     });
 }, 'addTrack() for a single track and a different stream.');
 
@@ -120,11 +114,12 @@
       assert_equals(sender.track, track);
       assert_array_equals(pc.getSenders(), [ sender ]);
       assert_array_equals(pc.getLocalStreams(), []);
+      // This is a NO-OP because there already is a sender for this track.
       pc.addStream(stream);
-      assert_array_equals(pc.getLocalStreams(), [ stream ]);
-      // The interaction between |addStream| and |addTrack| is not standardized
-      // (|addStream| is non-standard). In our implementation, the existing
-      // sender is reused by |addStream|.
+      // The sender is not associated with the stream, so |addStream| has no
+      // effect in this case. Otherwise it would already have been part of
+      // getLocalStreams().
+      assert_array_equals(pc.getLocalStreams(), []);
       assert_array_equals(pc.getSenders(), [ sender ]);
     });
 }, 'addTrack() before addStream() works.');
diff --git a/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-legacy-stream-APIs-expected.txt b/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-legacy-stream-APIs-expected.txt
new file mode 100644
index 0000000..dac419c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-legacy-stream-APIs-expected.txt
@@ -0,0 +1,17 @@
+This is a testharness.js-based test.
+PASS addStream() adds to local streams and senders.
+PASS addTrack() adds to local streams and senders.
+PASS addTrack() fails after addStream().
+PASS addStream() after addTrack() adds the remaining track.
+PASS Adding a track to an addStream()-stream adds it to the PC.
+PASS Removing a track from an addStream()-stream removes it from the PC.
+PASS The PC stops observing the stream after removeStream().
+PASS removeStream() after addStream() removes from local streams and senders.
+FAIL removeStream() after addTrack() removes from local streams and senders. assert_array_equals: lengths differ, expected 0 got 1
+PASS removeStream() after removeTrack() removes remaining tracks.
+PASS removeTrack() after addStream() removes from local streams and senders.
+PASS removeTrack() after addTrack() removes from local streams and senders.
+PASS createDTMFSender() with addStream()-track.
+FAIL createDTMFSender() with addTrack()-track. promise_test: Unhandled rejection with value: object "SyntaxError: Failed to execute 'createDTMFSender' on 'RTCPeerConnection': No local stream is available for the track provided."
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-legacy-stream-APIs.html b/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-legacy-stream-APIs.html
new file mode 100644
index 0000000..b88da76
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-legacy-stream-APIs.html
@@ -0,0 +1,185 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+</head>
+<body>
+<script>
+// This is not an external/wpt/webrtc/ test because it tests APIs and behaviors
+// that are not in the spec.
+
+promise_test(async function() {
+  let pc = new RTCPeerConnection();
+  let stream = await navigator.mediaDevices.getUserMedia({audio:true});
+  pc.addStream(stream);
+  assert_array_equals(pc.getLocalStreams(), [ stream ]);
+  assert_equals(pc.getSenders().length, 1);
+  assert_equals(pc.getSenders()[0].track, stream.getTracks()[0]);
+}, 'addStream() adds to local streams and senders.');
+
+promise_test(async function() {
+  let pc = new RTCPeerConnection();
+  let stream = await navigator.mediaDevices.getUserMedia({audio:true});
+  let sender = pc.addTrack(stream.getTracks()[0], stream);
+  assert_array_equals(pc.getLocalStreams(), [ stream ]);
+  assert_array_equals(pc.getSenders(), [ sender ]);
+}, 'addTrack() adds to local streams and senders.');
+
+promise_test(async function() {
+  let pc = new RTCPeerConnection();
+  let stream = await navigator.mediaDevices.getUserMedia({audio:true});
+  pc.addStream(stream);
+  try {
+    pc.addTrack(stream.getTracks()[0])
+    assert_unreached('addTrack() should have failed.');
+  } catch (e) {
+    assert_equals(e.name, 'InvalidAccessError');
+    assert_array_equals(pc.getLocalStreams(), [ stream ]);
+  };
+}, 'addTrack() fails after addStream().');
+
+promise_test(async function() {
+  let pc = new RTCPeerConnection();
+  let stream = await navigator.mediaDevices.getUserMedia({audio:true,
+                                                          video:true});
+  let sender = pc.addTrack(stream.getTracks()[0]);
+  assert_array_equals(pc.getLocalStreams(), []);
+  assert_array_equals(pc.getSenders(), [ sender ]);
+  pc.addStream(stream);
+  assert_array_equals(pc.getLocalStreams(), [ stream ]);
+  let otherSender = pc.getSenders().find(s => {
+    return s.track == stream.getTracks()[1];
+  });
+  assert_true(otherSender != null);
+  assert_equals(pc.getSenders().length, 2);
+}, 'addStream() after addTrack() adds the remaining track.');
+
+promise_test(async function() {
+  let pc = new RTCPeerConnection();
+  let stream = await navigator.mediaDevices.getUserMedia({audio:true,
+                                                          video:true});
+  let videoTrack = stream.getVideoTracks()[0];
+  stream.removeTrack(videoTrack);
+
+  pc.addStream(stream);
+  assert_true(
+      pc.getSenders().find(s => { return s.track == videoTrack; }) == null,
+      'PC does not know about the videoTrack before stream.addTrack()');
+  stream.addTrack(videoTrack);
+  assert_true(
+      pc.getSenders().find(s => { return s.track == videoTrack; }) != null,
+      'PC knows about the videoTrack after stream.addTrack()');
+}, 'Adding a track to an addStream()-stream adds it to the PC.');
+
+promise_test(async function() {
+  let pc = new RTCPeerConnection();
+  let stream = await navigator.mediaDevices.getUserMedia({audio:true,
+                                                          video:true});
+  let videoTrack = stream.getVideoTracks()[0];
+  pc.addStream(stream);
+  assert_true(
+      pc.getSenders().find(s => { return s.track == videoTrack; }) != null,
+      'PC knows about the track before stream.removeTrack()');
+  stream.removeTrack(videoTrack);
+  assert_true(
+      pc.getSenders().find(s => { return s.track == videoTrack; }) == null,
+      'PC does not know about the track after stream.removeTrack()');
+}, 'Removing a track from an addStream()-stream removes it from the PC.');
+
+promise_test(async function() {
+  let pc = new RTCPeerConnection();
+  let stream = await navigator.mediaDevices.getUserMedia({audio:true,
+                                                          video:true});
+  let videoTrack = stream.getVideoTracks()[0];
+  stream.removeTrack(videoTrack);
+
+  pc.addStream(stream);
+  pc.removeStream(stream);
+  assert_true(
+      pc.getSenders().find(s => { return s.track == videoTrack; }) == null,
+      'PC does not know about the videoTrack before stream.addTrack()');
+  stream.addTrack(videoTrack);
+  assert_true(
+      pc.getSenders().find(s => { return s.track == videoTrack; }) == null,
+      'PC does not know about the videoTrack after stream.addTrack()');
+}, 'The PC stops observing the stream after removeStream().');
+
+promise_test(async function() {
+  let pc = new RTCPeerConnection();
+  let stream = await navigator.mediaDevices.getUserMedia({audio:true});
+  pc.addStream(stream);
+  assert_array_equals(pc.getLocalStreams(), [ stream ]);
+  assert_equals(pc.getSenders().length, 1);
+  pc.removeStream(stream);
+  assert_array_equals(pc.getLocalStreams(), []);
+  assert_array_equals(pc.getSenders(), []);
+}, 'removeStream() after addStream() removes from local streams and senders.');
+
+promise_test(async function() {
+  let pc = new RTCPeerConnection();
+  let stream = await navigator.mediaDevices.getUserMedia({audio:true});
+  pc.addTrack(stream.getTracks()[0], stream);
+  assert_array_equals(pc.getLocalStreams(), [ stream ]);
+  assert_equals(pc.getSenders().length, 1);
+  pc.removeStream(stream);
+  assert_array_equals(pc.getLocalStreams(), []);
+  assert_array_equals(pc.getSenders(), []);
+}, 'removeStream() after addTrack() removes from local streams and senders.');
+
+promise_test(async function() {
+  let pc = new RTCPeerConnection();
+  let stream = await navigator.mediaDevices.getUserMedia({audio:true,
+                                                          video:true});
+  pc.addStream(stream);
+  assert_array_equals(pc.getLocalStreams(), [ stream ]);
+  let senders = pc.getSenders();
+  assert_equals(senders.length, 2);
+  pc.removeTrack(senders[0]);
+  assert_array_equals(pc.getLocalStreams(), [ stream ]);
+  assert_array_equals(pc.getSenders(), [ senders[1] ]);
+  pc.removeStream(stream);
+  assert_array_equals(pc.getLocalStreams(), []);
+  assert_array_equals(pc.getSenders(), []);
+}, 'removeStream() after removeTrack() removes remaining tracks.');
+
+promise_test(async function() {
+  let pc = new RTCPeerConnection();
+  let stream = await navigator.mediaDevices.getUserMedia({audio:true});
+  pc.addStream(stream);
+  assert_array_equals(pc.getLocalStreams(), [ stream ]);
+  assert_equals(pc.getSenders().length, 1);
+  pc.removeTrack(pc.getSenders()[0]);
+  assert_array_equals(pc.getLocalStreams(), []);
+  assert_array_equals(pc.getSenders(), []);
+}, 'removeTrack() after addStream() removes from local streams and senders.');
+
+promise_test(async function() {
+  let pc = new RTCPeerConnection();
+  let stream = await navigator.mediaDevices.getUserMedia({audio:true});
+  let sender = pc.addTrack(stream.getTracks()[0], stream);
+  assert_array_equals(pc.getLocalStreams(), [ stream ]);
+  assert_array_equals(pc.getSenders(), [ sender ]);
+  pc.removeTrack(sender);
+  assert_array_equals(pc.getLocalStreams(), []);
+  assert_array_equals(pc.getSenders(), []);
+}, 'removeTrack() after addTrack() removes from local streams and senders.');
+
+promise_test(async function() {
+  let pc = new RTCPeerConnection();
+  let stream = await navigator.mediaDevices.getUserMedia({audio:true});
+  pc.addStream(stream);
+  pc.createDTMFSender(stream.getTracks()[0]);
+}, 'createDTMFSender() with addStream()-track.');
+
+promise_test(async function() {
+  let pc = new RTCPeerConnection();
+  let stream = await navigator.mediaDevices.getUserMedia({audio:true});
+  let track = stream.getTracks()[0];
+  pc.addTrack(track);
+  pc.createDTMFSender(track);
+}, 'createDTMFSender() with addTrack()-track.');
+
+</script>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/designmode-no-caret-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/designmode-no-caret-expected.png
index 00c4753f..c85154dd 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/designmode-no-caret-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/designmode-no-caret-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/designmode-no-caret-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/designmode-no-caret-expected.txt
index 893d26d..04f2394 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/designmode-no-caret-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/designmode-no-caret-expected.txt
@@ -3,11 +3,13 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutNGBlockFlow (anonymous) at (0,0) size 784x60
-        LayoutText {#text} at (0,0) size 781x59
+      LayoutNGBlockFlow (anonymous) at (0,0) size 769x60
+        LayoutText {#text} at (0,0) size 759x59
           text run at (0,0) width 759: "This tests to see that a caret is placed inside an editable document that is entirely editable even when no caret is requested"
-          text run at (0,20) width 781: "programmatically. We do this as a convenience. Right now, we only do this convenience when a document's frame becomes"
-          text run at (0,40) width 377: "first responder or when a document's window becomes key."
+          text run at (0,20) width 117: "programmatically. "
+          text run at (116,20) width 187: "We do this as a convenience. "
+          text run at (302,20) width 420: "Right now, we only do this convenience when a document's frame"
+          text run at (0,40) width 436: "becomes first responder or when a document's window becomes key."
       LayoutBlockFlow {PRE} at (0,73) size 784x32
         LayoutText {#text} at (0,0) size 296x32
           text run at (0,0) width 296: "Test Failed - there should be a caret"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/mixed-editability-6-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/mixed-editability-6-expected.png
new file mode 100644
index 0000000..5323489
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/mixed-editability-6-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/mixed-editability-6-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/mixed-editability-6-expected.txt
new file mode 100644
index 0000000..3249e41
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/mixed-editability-6-expected.txt
@@ -0,0 +1,27 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x132
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x132
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x116
+      LayoutNGBlockFlow {P} at (0,0) size 784x40
+        LayoutText {#text} at (0,0) size 778x39
+          text run at (0,0) width 778: "This tests Select All when the caret is inside an editable region that is inside a non editable region. Whenever the selection is"
+          text run at (0,20) width 537: "in an editable region, Select All should select the contents of the highest editable root."
+      LayoutBlockFlow {DIV} at (0,56) size 784x60
+        LayoutBlockFlow {DIV} at (0,0) size 784x20
+          LayoutText {#text} at (0,0) size 27x19
+            text run at (0,0) width 27: "One"
+        LayoutBlockFlow {DIV} at (0,20) size 784x20
+          LayoutInline {SPAN} at (0,0) size 29x19
+            LayoutText {#text} at (0,0) size 29x19
+              text run at (0,0) width 29: "Two"
+          LayoutText {#text} at (28,0) size 5x19
+            text run at (28,0) width 5: " "
+          LayoutInline {SPAN} at (0,0) size 38x19
+            LayoutText {#text} at (32,0) size 38x19
+              text run at (32,0) width 38: "Three"
+        LayoutBlockFlow {DIV} at (0,40) size 784x20
+          LayoutText {#text} at (0,0) size 30x19
+            text run at (0,0) width 30: "Four"
+selection start: position 0 of child 0 {#text} of child 1 {DIV} of child 2 {DIV} of body
+selection end:   position 4 of child 0 {#text} of child 5 {DIV} of child 2 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/previous-line-position-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/previous-line-position-expected.png
new file mode 100644
index 0000000..57efcaf
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/previous-line-position-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/previous-line-position-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/previous-line-position-expected.txt
new file mode 100644
index 0000000..e838614
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/previous-line-position-expected.txt
@@ -0,0 +1,31 @@
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x154
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x154
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x138
+      LayoutNGBlockFlow {P} at (0,0) size 784x60
+        LayoutText {#text} at (0,0) size 241x19
+          text run at (0,0) width 241: "There was a workaround added to fix "
+        LayoutInline {A} at (0,0) size 149x19 [color=#0000EE]
+          LayoutText {#text} at (241,0) size 149x19
+            text run at (241,0) width 149: "rdar://problem/4033202"
+        LayoutText {#text} at (390,0) size 296x19
+          text run at (390,0) width 296: ". A bug to remove the workaround was filed as"
+        LayoutInline {A} at (0,0) size 149x19 [color=#0000EE]
+          LayoutText {#text} at (0,20) size 149x19
+            text run at (0,20) width 149: "rdar://problem/4040763"
+        LayoutText {#text} at (149,20) size 760x39
+          text run at (149,20) width 611: ". The underlying problem with VisiblePositions was fixed, and so I removed the workaround and"
+          text run at (0,40) width 136: "added this layout test."
+      LayoutBlockFlow {DIV} at (0,76) size 784x62 [border: (1px solid #0000FF)]
+        LayoutBlockFlow {P} at (1,1) size 782x20
+          LayoutText {#text} at (0,0) size 12x19
+            text run at (0,0) width 12: "hi"
+          LayoutInline {SPAN} at (0,0) size 0x19
+        LayoutNGBlockFlow (anonymous) at (1,21) size 767x40
+          LayoutBR {BR} at (0,0) size 0x19
+          LayoutText {#text} at (0,20) size 21x19
+            text run at (0,20) width 21: "test"
+caret: position 0 of child 2 {BR} of child 3 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/replaced/selection-rect-in-table-cell-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/replaced/selection-rect-in-table-cell-expected.png
index ddcb709..6faba5e 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/replaced/selection-rect-in-table-cell-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/replaced/selection-rect-in-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/replaced/selection-rect-transform-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/replaced/selection-rect-transform-expected.png
new file mode 100644
index 0000000..9c81b4f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/replaced/selection-rect-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/plugins/mouse-click-plugin-clears-selection-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/plugins/mouse-click-plugin-clears-selection-expected.png
new file mode 100644
index 0000000..a6afee3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/plugins/mouse-click-plugin-clears-selection-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/plugins/mouse-click-plugin-clears-selection-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/plugins/mouse-click-plugin-clears-selection-expected.txt
new file mode 100644
index 0000000..26c030f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/plugins/mouse-click-plugin-clears-selection-expected.txt
@@ -0,0 +1,22 @@
+CONSOLE MESSAGE: Blink Test Plugin: initializing
+CONSOLE MESSAGE: Blink Test Plugin: DidChangeFocus(true)
+CONSOLE MESSAGE: Blink Test Plugin: MouseDown at (52,52)
+CONSOLE MESSAGE: Blink Test Plugin: MouseUp at (52,52)
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x138
+  LayoutNGBlockFlow {HTML} at (0,0) size 800x138
+    LayoutNGBlockFlow {BODY} at (8,8) size 784x122
+      LayoutNGBlockFlow (anonymous) at (0,0) size 784x122
+        LayoutBR {BR} at (100,85) size 0x0
+        LayoutTextControl {INPUT} at (0,100) size 154x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
+        LayoutText {#text} at (0,0) size 0x0
+      LayoutNGBlockFlow {DIV} at (0,122) size 784x0
+layer at (8,8) size 100x100
+  LayoutEmbeddedObject {EMBED} at (0,0) size 100x100
+layer at (10,111) size 150x16
+  LayoutBlockFlow {DIV} at (2,3) size 150x16
+    LayoutText {#text} at (0,0) size 27x16
+      text run at (0,0) width 27: "hello"
+selection start: position 0 of child 0 {#text} of child 0 {DIV} of {#document-fragment} of child 4 {INPUT} of body
+selection end:   position 5 of child 0 {#text} of child 0 {DIV} of {#document-fragment} of child 4 {INPUT} of body
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-features=NetworkService/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-features=NetworkService/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt
new file mode 100644
index 0000000..1a74845
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-features=NetworkService/external/wpt/service-workers/service-worker/fetch-event.https-expected.txt
@@ -0,0 +1,24 @@
+This is a testharness.js-based test.
+PASS Service Worker headers in the request of a fetch event
+PASS Service Worker responds to fetch event with string
+PASS Service Worker responds to fetch event with blob body
+PASS Service Worker responds to fetch event with the referrer URL
+FAIL Service Worker responds to fetch event with an existing client id assert_unreached: unexpected rejection: assert_equals: Service Worker should respond to fetch with an existing client id expected "Client ID Found" but got "Client ID Not F" Reached unreachable code
+PASS Service Worker does not respond to fetch event
+PASS Service Worker responds to fetch event with null response body
+PASS Service Worker fetches other file in fetch event
+PASS Service Worker responds to fetch event with POST form
+PASS Service Worker falls back to network in fetch event with POST form
+PASS Multiple calls of respondWith must throw InvalidStateErrors
+PASS Service Worker event.respondWith must set the used flag
+PASS Service Worker should expose FetchEvent URL fragments.
+PASS Service Worker responds to fetch event with the correct cache types
+PASS Service Worker should intercept EventSource
+FAIL Service Worker responds to fetch event with the correct integrity_metadata assert_unreached: unexpected rejection: assert_equals: integrity expected "gs0nqru8KbsrIt5YToQqS9fYao4GQJXtcId610g7cCU=" but got "" Reached unreachable code
+PASS FetchEvent#body is a string
+PASS FetchEvent#body is a string and is passed to network fallback
+PASS FetchEvent#body is a blob
+PASS FetchEvent#body is a blob and is passed to network fallback
+PASS Service Worker responds to fetch event with the correct keepalive value
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/W3C-SVG-1.1/masking-mask-01-b-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/W3C-SVG-1.1/masking-mask-01-b-expected.png
deleted file mode 100644
index 39a0202..0000000
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/W3C-SVG-1.1/masking-mask-01-b-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/as-background-image/svg-as-background-6-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/as-background-image/svg-as-background-6-expected.png
new file mode 100644
index 0000000..858a2ff
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/as-background-image/svg-as-background-6-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/batik/masking/maskRegions-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/batik/masking/maskRegions-expected.png
new file mode 100644
index 0000000..d800430
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/batik/masking/maskRegions-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/custom/grayscale-gradient-mask-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/custom/grayscale-gradient-mask-expected.png
new file mode 100644
index 0000000..2486aa04
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/custom/grayscale-gradient-mask-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-dom-height-attr-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-dom-height-attr-expected.png
index c7f575b..0ed2eaa 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-dom-height-attr-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-dom-height-attr-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-dom-maskContentUnits-attr-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-dom-maskContentUnits-attr-expected.png
index c7f575b..0ed2eaa 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-dom-maskContentUnits-attr-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-dom-maskContentUnits-attr-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-dom-maskUnits-attr-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-dom-maskUnits-attr-expected.png
deleted file mode 100644
index 559d720..0000000
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-dom-maskUnits-attr-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-dom-width-attr-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-dom-width-attr-expected.png
index c7f575b..0ed2eaa 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-dom-width-attr-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-dom-width-attr-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-dom-x-attr-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-dom-x-attr-expected.png
index c7f575b..0ed2eaa 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-dom-x-attr-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-dom-x-attr-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-dom-y-attr-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-dom-y-attr-expected.png
index c7f575b..0ed2eaa 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-dom-y-attr-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-dom-y-attr-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-svgdom-height-prop-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-svgdom-height-prop-expected.png
index c7f575b..0ed2eaa 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-svgdom-height-prop-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-svgdom-height-prop-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-svgdom-maskContentUnits-prop-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-svgdom-maskContentUnits-prop-expected.png
index c7f575b..0ed2eaa 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-svgdom-maskContentUnits-prop-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-svgdom-maskContentUnits-prop-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-svgdom-maskUnits-prop-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-svgdom-maskUnits-prop-expected.png
deleted file mode 100644
index 559d720..0000000
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-svgdom-maskUnits-prop-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-svgdom-width-prop-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-svgdom-width-prop-expected.png
index c7f575b..0ed2eaa 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-svgdom-width-prop-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-svgdom-width-prop-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-svgdom-x-prop-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-svgdom-x-prop-expected.png
index c7f575b..0ed2eaa 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-svgdom-x-prop-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-svgdom-x-prop-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-svgdom-y-prop-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-svgdom-y-prop-expected.png
index c7f575b..0ed2eaa 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-svgdom-y-prop-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/dynamic-updates/SVGMaskElement-svgdom-y-prop-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/hixie/perf/007-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/hixie/perf/007-expected.png
index 15803c76..22e3621 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/hixie/perf/007-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/hixie/perf/007-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/transforms/text-with-mask-with-svg-transform-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/transforms/text-with-mask-with-svg-transform-expected.png
index 2e6f6d1..a3046b9 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/transforms/text-with-mask-with-svg-transform-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/transforms/text-with-mask-with-svg-transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/zoom/page/zoom-mask-with-percentages-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/zoom/page/zoom-mask-with-percentages-expected.png
new file mode 100644
index 0000000..b649e9fc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/svg/zoom/page/zoom-mask-with-percentages-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/tables/table-transform-absolute-position-child-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/tables/table-transform-absolute-position-child-expected.png
new file mode 100644
index 0000000..8c86b52
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/tables/table-transform-absolute-position-child-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png
deleted file mode 100644
index b6855bc..0000000
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/virtual/gpu-rasterization/images/color-profile-mask-image-svg-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/virtual/prefer_compositing_to_lcd_text/compositing/overflow/border-radius-composited-subframe-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/virtual/prefer_compositing_to_lcd_text/compositing/overflow/border-radius-composited-subframe-expected.png
new file mode 100644
index 0000000..deec6fa
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/virtual/prefer_compositing_to_lcd_text/compositing/overflow/border-radius-composited-subframe-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/virtual/prefer_compositing_to_lcd_text/compositing/overflow/border-radius-on-parent-composited-grandchild-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/virtual/prefer_compositing_to_lcd_text/compositing/overflow/border-radius-on-parent-composited-grandchild-expected.png
new file mode 100644
index 0000000..f380d7a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/virtual/prefer_compositing_to_lcd_text/compositing/overflow/border-radius-on-parent-composited-grandchild-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/virtual/prefer_compositing_to_lcd_text/compositing/overflow/mask-with-filter-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/virtual/prefer_compositing_to_lcd_text/compositing/overflow/mask-with-filter-expected.png
new file mode 100644
index 0000000..38d98ac
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/virtual/prefer_compositing_to_lcd_text/compositing/overflow/mask-with-filter-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/virtual/prefer_compositing_to_lcd_text/compositing/overflow/mask-with-small-content-rect-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/virtual/prefer_compositing_to_lcd_text/compositing/overflow/mask-with-small-content-rect-expected.png
new file mode 100644
index 0000000..28103ae5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/virtual/prefer_compositing_to_lcd_text/compositing/overflow/mask-with-small-content-rect-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/virtual/prefer_compositing_to_lcd_text/compositing/overflow/scaled-mask-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/virtual/prefer_compositing_to_lcd_text/compositing/overflow/scaled-mask-expected.png
new file mode 100644
index 0000000..d01051d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-slimming-paint-v175/virtual/prefer_compositing_to_lcd_text/compositing/overflow/scaled-mask-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object-expected.txt
index bb87c1d1..e111b47 100644
--- a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object-expected.txt
@@ -1,7 +1,6 @@
 Test that all ActiveDOMObjects with pending activities will get into one group in the heap snapshot. Bug 426809.
 Took heap snapshot
 Parsed snapshot
-SUCCESS: found (Pending activities group)
-SUCCESS: found Pending activities / 3 entries
-SUCCESS: found 2 MediaQueryLists in Pending activities / 3 entries
+SUCCESS: found Pending activities
+SUCCESS: found 2 MediaQueryLists in Pending activities
 
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object.js b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object.js
index 6018bb0..3d0bff0 100644
--- a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object.js
+++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-active-dom-object.js
@@ -32,7 +32,7 @@
   var snapshot = await helper.takeHeapSnapshot();
   var node;
   for (var it = snapshot._allNodes(); it.hasNext(); it.next()) {
-    if (it.node.name() === '(Pending activities group)') {
+    if (it.node.name() === 'Pending activities') {
       node = it.node;
       break;
     }
@@ -40,23 +40,9 @@
   if (node)
     testRunner.log('SUCCESS: found ' + node.name());
   else
-    return testRunner.fail(`cannot find '(Pending activities group)'`);
+    return testRunner.fail(`cannot find 'Pending activities'`);
 
-  var pendingActivitiesRE = /^Pending activities/;
-  var pendingActivitiesFound = false;
-  for (var iter = node.edges(); iter.hasNext(); iter.next()) {
-    var node = iter.edge.node();
-    if (pendingActivitiesRE.test(node.className())) {
-      if ('Pending activities / 3 entries' === node.name()) {
-        if (pendingActivitiesFound)
-          return testRunner.fail('second ' + node.name());
-        pendingActivitiesFound = true;
-        testRunner.log('SUCCESS: found ' + node.name());
-        checkPendingActivities(node);
-      } else {
-        return testRunner.fail(`unexpected 'Pending activities': ${node.name()}`);
-      }
-    }
-  }
+  checkPendingActivities(node);
+
   testRunner.completeTest();
 })
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree-expected.txt
deleted file mode 100644
index 8042a9f..0000000
--- a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-Test that all nodes from the detached DOM tree will get into one group in the heap snapshot. Bug 107819.
-Took heap snapshot
-Parsed snapshot
-SUCCESS: found (Detached DOM trees)
-SUCCESS: found Detached DOM tree / 3 entries
-SUCCESS: found 3 DIVs in Detached DOM tree / 3 entries
-
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree.js b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree.js
deleted file mode 100644
index 95f65af..0000000
--- a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-detached-dom-tree.js
+++ /dev/null
@@ -1,61 +0,0 @@
-(async function(testRunner) {
-  var {page, session, dp} = await testRunner.startBlank(
-      `Test that all nodes from the detached DOM tree will get into one group in the heap snapshot. Bug 107819.`);
-
-  await session.evaluate(`
-    if (window.gc)
-      window.gc();
-    window.retaining_wrapper = document.createElement('div');
-    var t = document.createElement('div');
-    retaining_wrapper.appendChild(t);
-    t.appendChild(document.createElement('div'));
-  `);
-
-  function checkDetachedDOMTreeNodes(treeNode) {
-    var divCount = 0;
-    for (var iter = treeNode.edges(); iter.hasNext(); iter.next()) {
-      var node = iter.edge.node();
-      if (node.name() === 'HTMLDivElement')
-        ++divCount;
-      else
-        return testRunner.fail('unexpected DOM wrapper: ' + node.name());
-    }
-    if (divCount === 3)
-      testRunner.log('SUCCESS: found ' + divCount + ' DIVs in ' + treeNode.name());
-    else
-      return testRunner.fail('unexpected DIV count: ' + divCount);
-  }
-
-  var Helper = await testRunner.loadScript('resources/heap-snapshot-common.js');
-  var helper = await Helper(testRunner, session);
-
-  var snapshot = await helper.takeHeapSnapshot();
-  var node;
-  for (var it = snapshot._allNodes(); it.hasNext(); it.next()) {
-    if (it.node.name() === '(Detached DOM trees)') {
-      node = it.node;
-      break;
-    }
-  }
-  if (node)
-    testRunner.log('SUCCESS: found ' + node.name());
-  else
-    return testRunner.fail('cannot find detached DOM trees root');
-
-  var detachedDOMTreeRE = /^Detached DOM tree/;
-  var detachedDomTreeFound = false;
-  for (var iter = node.edges(); iter.hasNext(); iter.next()) {
-    var node = iter.edge.node();
-    if (detachedDOMTreeRE.test(node.className())) {
-      if ('Detached DOM tree / 3 entries' === node.name()) {
-        if (detachedDomTreeFound)
-          return testRunner.fail('second ' + node.name());
-        detachedDomTreeFound = true;
-        testRunner.log('SUCCESS: found ' + node.name());
-        checkDetachedDOMTreeNodes(node);
-      } else
-        return testRunner.fail('unexpected detached DOM tree: ' + node.name());
-    }
-  }
-  testRunner.completeTest();
-})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-event-listener-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-event-listener-expected.txt
index 4608a90..a67ac3b 100644
--- a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-event-listener-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-event-listener-expected.txt
@@ -1,6 +1,6 @@
-Test that all nodes from the detached DOM tree will get into one group in the heap snapshot. Bug 107819.
+Test retaining path for an event listener.
 Took heap snapshot
 Parsed snapshot
 SUCCESS: found myEventListener
-SUCCESS: found link from HTMLBodyElement to myEventListener
+SUCCESS: retaining path = [EventListener, InternalNode, HTMLBodyElement, HTMLHtmlElement, HTMLDocument]
 
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-event-listener.js b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-event-listener.js
index 98429b0..68c6f12 100644
--- a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-event-listener.js
+++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-event-listener.js
@@ -1,6 +1,6 @@
 (async function(testRunner) {
   var {page, session, dp} = await testRunner.startBlank(
-      `Test that all nodes from the detached DOM tree will get into one group in the heap snapshot. Bug 107819.`);
+      `Test retaining path for an event listener.`);
 
   await session.evaluate(`
     function addEventListenerAndRunTest() {
@@ -26,24 +26,13 @@
   if (node)
     testRunner.log('SUCCESS: found ' + node.name());
   else
-    return testRunner.fail('cannot find detached DOM trees root');
+    return testRunner.fail('cannot find myEventListener node');
 
-  var nativeRetainers = 0;
-  for (var iter = node.retainers(); iter.hasNext(); iter.next()) {
-    var retainingEdge = iter.retainer;
-    if (retainingEdge.isInternal() && retainingEdge.name() === 'native') {
-      if (++nativeRetainers === 1) {
-        var retainerName = retainingEdge.node().name();
-        if (retainerName === 'HTMLBodyElement')
-          testRunner.log('SUCCESS: found link from HTMLBodyElement to ' + node.name());
-        else
-          return testRunner.fail('unexpected retainer of ' + node.name() + ': ' + retainerName);
-      } else
-        return testRunner.fail('too many retainers of ' + node.name());
-    } else if (!retainingEdge.isWeak())
-      return testRunner.fail('unexpected retaining edge of ' + node.name() + ' type: ' + retainingEdge.type() + ', name: ' + retainingEdge.name());
-  }
-  if (!nativeRetainers)
-    return testRunner.fail('cannot find HTMLBodyElement among retainers of ' + node.name());
+  var retainers = helper.firstRetainingPath(node).map(node => node.name());
+  // Limit to the retainers until the Window object to keep the test robust
+  // against root node name changes.
+  retainers = retainers.slice(0, retainers.indexOf('Window'));
+  var actual = retainers.join(', ');
+  testRunner.log(`SUCCESS: retaining path = [${actual}]`);
   testRunner.completeTest();
 })
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-iframe-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-iframe-expected.txt
new file mode 100644
index 0000000..b4662b7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-iframe-expected.txt
@@ -0,0 +1,6 @@
+Test retaining path that spans two DOM trees.
+Took heap snapshot
+Parsed snapshot
+SUCCESS: found Leak
+SUCCESS: retainingListener is in retaining path
+
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-iframe.js b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-iframe.js
new file mode 100644
index 0000000..4cab3e7c2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-iframe.js
@@ -0,0 +1,48 @@
+(async function(testRunner) {
+  var {page, session, dp} = await testRunner.startBlank(
+      `Test retaining path that spans two DOM trees.`);
+
+  await session.evaluate(`
+    function run() {
+      var frame = document.createElement('iframe');
+      frame.src = 'data:text/html,<script>class Leak{}; var x = new Leak();<'+
+                  '/script>';
+      document.body.appendChild(frame);
+      frame.addEventListener("load", function() {
+        var iframeWindow  = this.contentWindow;
+        function retainingListener() {
+          // This is leaking the iframe.
+          console.log(iframeWindow);
+        }
+        document.body.addEventListener('click', retainingListener, true);
+        document.body.removeChild(frame);
+      });
+    }
+    run();
+  `);
+  await dp.Page.onLoadEventFired(() => {});
+
+  var Helper = await testRunner.loadScript('resources/heap-snapshot-common.js');
+  var helper = await Helper(testRunner, session);
+
+  var snapshot = await helper.takeHeapSnapshot();
+  var node;
+  for (var it = snapshot._allNodes(); it.hasNext(); it.next()) {
+    if (it.node.className() === 'Leak') {
+      node = it.node;
+      break;
+    }
+  }
+  if (node)
+    testRunner.log('SUCCESS: found ' + node.name());
+  else
+    return testRunner.fail('cannot find leaking node');
+
+  var retainers = helper.firstRetainingPath(node).map(node => node.name());
+
+  if (retainers.indexOf('retainingListener') != -1)
+    testRunner.log('SUCCESS: retainingListener is in retaining path');
+  else
+    return testRunner.fail('cannot find retainingListener');
+  testRunner.completeTest();
+})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-multiple-retainers-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-multiple-retainers-expected.txt
new file mode 100644
index 0000000..1022d56
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-multiple-retainers-expected.txt
@@ -0,0 +1,9 @@
+Test multiple retaining path for an object.
+Took heap snapshot
+Parsed snapshot
+SUCCESS: found leaking
+SUCCESS: immediate retainer is EventListener.
+SUCCESS: found multiple retaining paths.
+SUCCESS: path1 = [HTMLBodyElement, HTMLHtmlElement, HTMLDocument]
+SUCCESS: path2 = [HTMLDivElement, HTMLBodyElement, HTMLHtmlElement, HTMLDocument]
+
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-multiple-retainers.js b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-multiple-retainers.js
new file mode 100644
index 0000000..04f648b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/heap-snapshot-with-multiple-retainers.js
@@ -0,0 +1,63 @@
+(async function(testRunner) {
+  var {page, session, dp} = await testRunner.startBlank(
+      `Test multiple retaining path for an object.`);
+
+  await session.evaluate(`
+    function run() {
+      function leaking() {
+        console.log('leaking');
+      }
+      var div = document.createElement('div');
+      document.body.appendChild(div);
+      div.addEventListener('click', leaking, true);
+      document.body.addEventListener('click', leaking, true);
+    }
+    run();
+  `);
+
+  var Helper = await testRunner.loadScript('resources/heap-snapshot-common.js');
+  var helper = await Helper(testRunner, session);
+
+  var snapshot = await helper.takeHeapSnapshot();
+  var node;
+  for (var it = snapshot._allNodes(); it.hasNext(); it.next()) {
+    if (it.node.type() === 'closure' && it.node.name() === 'leaking') {
+      node = it.node;
+      break;
+    }
+  }
+  if (node)
+    testRunner.log('SUCCESS: found ' + node.name());
+  else
+    return testRunner.fail('cannot find the leaking node');
+
+  var eventListener = helper.firstRetainingPath(node)[0];
+
+  if (eventListener.name() == 'EventListener') {
+    testRunner.log('SUCCESS: immediate retainer is EventListener.');
+  } else {
+    return testRunner.fail('cannot find the EventListener.');
+  }
+
+  var retainingPaths = [];
+  for (var iter = eventListener.retainers(); iter.hasNext(); iter.next()) {
+    var path = helper.firstRetainingPath(iter.retainer.node());
+    path = path.map(node => node.name());
+    // Limit the path until the Window object to keep the test robust
+    // against root node name changes.
+    path = path.slice(0, path.indexOf('Window'));
+    retainingPaths.push(path.join(', '));
+  }
+
+  if (retainingPaths.length >= 2) {
+    testRunner.log('SUCCESS: found multiple retaining paths.');
+  } else {
+    return testRunner.fail('cannot find multiple retaining paths.');
+  }
+
+  // Sort alphabetically to make the test robust.
+  retainingPaths.sort((a, b) => (a < b ? -1 : (a == b ? 0 : 1)));
+  testRunner.log(`SUCCESS: path1 = [${retainingPaths[0]}]`);
+  testRunner.log(`SUCCESS: path2 = [${retainingPaths[1]}]`);
+  testRunner.completeTest();
+})
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/resources/heap-snapshot-common.js b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/resources/heap-snapshot-common.js
index 5927bf1e..3118708e 100644
--- a/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/resources/heap-snapshot-common.js
+++ b/third_party/WebKit/LayoutTests/inspector-protocol/heap-profiler/resources/heap-snapshot-common.js
@@ -28,7 +28,22 @@
     return snapshot;
   }
 
+  function firstRetainingPath(node) {
+    for (var iter = node.retainers(); iter.hasNext(); iter.next()) {
+      var retainingEdge = iter.retainer;
+      var retainer = retainingEdge.node();
+      if (retainingEdge.isWeak() ||
+          retainer.distance() >= node.distance()) continue;
+      var path = firstRetainingPath(retainer);
+      path.unshift(retainer);
+      return path;
+    }
+    return [];
+  }
+
   return {
+    firstRetainingPath: firstRetainingPath,
+
     takeHeapSnapshot: function() {
       return takeHeapSnapshotInternal(() => session.protocol.HeapProfiler.takeHeapSnapshot());
     },
diff --git a/third_party/WebKit/LayoutTests/media/picture-in-picture/disable-picture-in-picture.html b/third_party/WebKit/LayoutTests/media/picture-in-picture/disable-picture-in-picture.html
new file mode 100644
index 0000000..5a44baad
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/media/picture-in-picture/disable-picture-in-picture.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<title>Test disable Picture-in-Picture</title>
+<script src='../../resources/testharness.js'></script>
+<script src='../../resources/testharnessreport.js'></script>
+<script src="../../resources/testdriver.js"></script>
+<script src="../../resources/testdriver-vendor.js"></script>
+<script src="resources/picture-in-picture-helpers.js"></script>
+<body></body>
+<script>
+test(t => {
+  const video = document.createElement('video');
+  assert_false(video.disablePictureInPicture); // default value
+
+  video.setAttribute('disablepictureinpicture', 'foo');
+  assert_true(video.disablePictureInPicture);
+
+  video.removeAttribute('disablepictureinpicture');
+  assert_false(video.disablePictureInPicture);
+
+  video.disablePictureInPicture = true;
+  assert_equals(video.getAttribute('disablepictureinpicture'), '');
+
+  video.disablePictureInPicture = false;
+  assert_equals(video.getAttribute('disablepictureinpicture'), null);
+}, 'Test disablePictureInPicture IDL attribute');
+
+promise_test(t => {
+  const video = document.createElement('video');
+  video.disablePictureInPicture = true;
+  return promise_rejects(t, 'InvalidStateError',
+      requestPictureInPictureWithTrustedClick(video));
+}, 'Request Picture-in-Picture rejects if disablePictureInPicture is true');
+
+promise_test(t => {
+  const video = document.createElement('video');
+  return requestPictureInPictureWithTrustedClick(video)
+  .then(() => {
+    video.disablePictureInPicture = true;
+    assert_equals(document.pictureInPictureElement, null);
+  });
+}, 'pictureInPictureElement is unset if disablePictureInPicture becomes true');
+
+promise_test(t => {
+  const video = document.createElement('video');
+  return requestPictureInPictureWithTrustedClick(video)
+  .then(() => {
+    video.disablePictureInPicture = false;
+    assert_equals(document.pictureInPictureElement, video);
+  });
+}, 'pictureInPictureElement is unchanged if disablePictureInPicture becomes false');
+
+promise_test(t => {
+  const video = document.createElement('video');
+  return requestPictureInPictureWithTrustedClick(video)
+  .then(() => {
+    document.createElement('video').disablePictureInPicture = true;
+    assert_equals(document.pictureInPictureElement, video);
+  });
+}, 'pictureInPictureElement is unchanged if disablePictureInPicture becomes ' +
+   'true for another video');
+</script>
diff --git a/third_party/WebKit/LayoutTests/media/picture-in-picture/exit-picture-in-picture.html b/third_party/WebKit/LayoutTests/media/picture-in-picture/exit-picture-in-picture.html
new file mode 100644
index 0000000..e19283d7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/media/picture-in-picture/exit-picture-in-picture.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<title>Test exit Picture-in-Picture</title>
+<script src='../../resources/testharness.js'></script>
+<script src='../../resources/testharnessreport.js'></script>
+<script src="../../resources/testdriver.js"></script>
+<script src="../../resources/testdriver-vendor.js"></script>
+<script src="resources/picture-in-picture-helpers.js"></script>
+<body></body>
+<script>
+promise_test(t => {
+  return requestPictureInPictureWithTrustedClick(document.createElement('video'))
+  .then(() => document.exitPictureInPicture());
+}, 'Exit Picture-in-Picture resolves when there is a Picture-in-Picture video');
+
+
+promise_test(t => {
+  return promise_rejects(t, 'InvalidStateError',
+      document.exitPictureInPicture());
+}, 'Exit Picture-in-Picture rejects when there is no Picture-in-Picture video');
+</script>
diff --git a/third_party/WebKit/LayoutTests/media/picture-in-picture/not-processing-user-gesture.html b/third_party/WebKit/LayoutTests/media/picture-in-picture/not-processing-user-gesture.html
index 0efac36..7b30831 100644
--- a/third_party/WebKit/LayoutTests/media/picture-in-picture/not-processing-user-gesture.html
+++ b/third_party/WebKit/LayoutTests/media/picture-in-picture/not-processing-user-gesture.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<title>Test request picture in picture requires a user gesture</title>
+<title>Test request Picture-in-Picture requires a user gesture</title>
 <script src='../../resources/testharness.js'></script>
 <script src='../../resources/testharnessreport.js'></script>
 <body></body>
diff --git a/third_party/WebKit/LayoutTests/media/picture-in-picture/picture-in-picture-element.html b/third_party/WebKit/LayoutTests/media/picture-in-picture/picture-in-picture-element.html
new file mode 100644
index 0000000..c4bc9a7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/media/picture-in-picture/picture-in-picture-element.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<title>Test Picture-in-Picture element</title>
+<script src='../../resources/testharness.js'></script>
+<script src='../../resources/testharnessreport.js'></script>
+<script src="../../resources/testdriver.js"></script>
+<script src="../../resources/testdriver-vendor.js"></script>
+<script src="resources/picture-in-picture-helpers.js"></script>
+<body></body>
+<script>
+promise_test(t => {
+  assert_equals(document.pictureInPictureElement, null);
+  const video = document.createElement('video');
+
+  return requestPictureInPictureWithTrustedClick(video)
+  .then(() => {
+    assert_equals(document.pictureInPictureElement, video);
+    return document.exitPictureInPicture();
+  })
+  .then(() => {
+    assert_equals(document.pictureInPictureElement, null);
+  })
+});
+</script>
diff --git a/third_party/WebKit/LayoutTests/media/picture-in-picture/request-picture-in-picture.html b/third_party/WebKit/LayoutTests/media/picture-in-picture/request-picture-in-picture.html
index 1c134be..0324d734 100644
--- a/third_party/WebKit/LayoutTests/media/picture-in-picture/request-picture-in-picture.html
+++ b/third_party/WebKit/LayoutTests/media/picture-in-picture/request-picture-in-picture.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<title>Test request picture in picture</title>
+<title>Test request Picture-in-Picture</title>
 <script src='../../resources/testharness.js'></script>
 <script src='../../resources/testharnessreport.js'></script>
 <script src="../../resources/testdriver.js"></script>
@@ -8,7 +8,6 @@
 <body></body>
 <script>
 promise_test(t => {
-  return promise_rejects(t, 'NotSupportedError',
-      requestPictureInPictureWithTrustedClick(document.createElement('video')));
+  return requestPictureInPictureWithTrustedClick(document.createElement('video'));
 });
 </script>
diff --git a/third_party/WebKit/LayoutTests/platform/linux/editing/inserting/4875189-2-expected.png b/third_party/WebKit/LayoutTests/platform/linux/editing/inserting/4875189-2-expected.png
deleted file mode 100644
index 9f1a661c..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/editing/inserting/4875189-2-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/editing/inserting/4875189-2-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/editing/inserting/4875189-2-expected.txt
deleted file mode 100644
index 42bd2d2..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/editing/inserting/4875189-2-expected.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {P} at (0,0) size 784x20
-        LayoutText {#text} at (0,0) size 784x19
-          text run at (0,0) width 441: "This tests for a bug when replacing the contents of a floating element. "
-          text run at (441,0) width 343: "Just its contents should be removed during the replace."
-      LayoutBlockFlow {DIV} at (0,36) size 784x20
-        LayoutText {#text} at (291,0) size 235x19
-          text run at (291,0) width 235: "This shouldn't be in the bordered div."
-        LayoutBlockFlow (floating) {DIV} at (0,0) size 291.97x22 [border: (1px solid #0000FF)]
-          LayoutText {#text} at (1,1) size 290x19
-            text run at (1,1) width 290: "This should be in a floating blue bordered div."
-caret: position 47 of child 0 {#text} of child 1 {DIV} of child 2 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/mac/editing/inserting/4875189-2-expected.png b/third_party/WebKit/LayoutTests/platform/mac/editing/inserting/4875189-2-expected.png
deleted file mode 100644
index 1f0abf15..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/editing/inserting/4875189-2-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/editing/inserting/4875189-2-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/editing/inserting/4875189-2-expected.txt
deleted file mode 100644
index 371c5cfe..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/editing/inserting/4875189-2-expected.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {P} at (0,0) size 784x36
-        LayoutText {#text} at (0,0) size 747x36
-          text run at (0,0) width 450: "This tests for a bug when replacing the contents of a floating element. "
-          text run at (449,0) width 298: "Just its contents should be removed during the"
-          text run at (0,18) width 51: "replace."
-      LayoutBlockFlow {DIV} at (0,52) size 784x18
-        LayoutText {#text} at (296,0) size 239x18
-          text run at (296,0) width 239: "This shouldn't be in the bordered div."
-        LayoutBlockFlow (floating) {DIV} at (0,0) size 296.47x20 [border: (1px solid #0000FF)]
-          LayoutText {#text} at (1,1) size 295x18
-            text run at (1,1) width 295: "This should be in a floating blue bordered div."
-caret: position 47 of child 0 {#text} of child 1 {DIV} of child 2 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/win/editing/inserting/4875189-2-expected.png b/third_party/WebKit/LayoutTests/platform/win/editing/inserting/4875189-2-expected.png
deleted file mode 100644
index 55e81b72..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/editing/inserting/4875189-2-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/editing/inserting/4875189-2-expected.txt b/third_party/WebKit/LayoutTests/platform/win/editing/inserting/4875189-2-expected.txt
deleted file mode 100644
index 0f49dda6..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/editing/inserting/4875189-2-expected.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-layer at (0,0) size 800x600
-  LayoutView at (0,0) size 800x600
-layer at (0,0) size 800x600
-  LayoutBlockFlow {HTML} at (0,0) size 800x600
-    LayoutBlockFlow {BODY} at (8,8) size 784x584
-      LayoutBlockFlow {P} at (0,0) size 784x20
-        LayoutText {#text} at (0,0) size 744x19
-          text run at (0,0) width 416: "This tests for a bug when replacing the contents of a floating element. "
-          text run at (416,0) width 328: "Just its contents should be removed during the replace."
-      LayoutBlockFlow {DIV} at (0,36) size 784x20
-        LayoutText {#text} at (274,0) size 223x19
-          text run at (274,0) width 223: "This shouldn't be in the bordered div."
-        LayoutBlockFlow (floating) {DIV} at (0,0) size 274.97x22 [border: (1px solid #0000FF)]
-          LayoutText {#text} at (1,1) size 273x19
-            text run at (1,1) width 273: "This should be in a floating blue bordered div."
-caret: position 47 of child 0 {#text} of child 1 {DIV} of child 2 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/absolute-sized-content-with-resources-expected.png b/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/absolute-sized-content-with-resources-expected.png
new file mode 100644
index 0000000..1c443440
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/absolute-sized-content-with-resources-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/absolute-sized-content-with-resources-expected.txt b/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/absolute-sized-content-with-resources-expected.txt
new file mode 100644
index 0000000..f986bd9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/absolute-sized-content-with-resources-expected.txt
@@ -0,0 +1,66 @@
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "backgroundColor": "#FFFFFF",
+      "paintInvalidations": [
+        {
+          "object": "LayoutBlockFlow div id='contentBox'",
+          "rect": [8, 52, 402, 402],
+          "reason": "geometry"
+        },
+        {
+          "object": "LayoutSVGRect rect",
+          "rect": [42, 119, 334, 268],
+          "reason": "paint property change"
+        },
+        {
+          "object": "LayoutSVGRect rect",
+          "rect": [42, 119, 334, 268],
+          "reason": "paint property change"
+        },
+        {
+          "object": "LayoutSVGRect rect",
+          "rect": [17, 219, 84, 68],
+          "reason": "paint property change"
+        },
+        {
+          "object": "LayoutSVGRect rect",
+          "rect": [17, 219, 84, 68],
+          "reason": "paint property change"
+        }
+      ]
+    }
+  ],
+  "objectPaintInvalidations": [
+    {
+      "object": "LayoutBlockFlow div id='contentBox'",
+      "reason": "geometry"
+    },
+    {
+      "object": "RootInlineBox",
+      "reason": "geometry"
+    },
+    {
+      "object": "LayoutSVGRoot svg",
+      "reason": "geometry"
+    },
+    {
+      "object": "LayoutSVGRect rect",
+      "reason": "SVG resource change"
+    }
+  ]
+}
+
diff --git a/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt
index ea774922..7133c5ff 100644
--- a/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/element-instance-property-listing-expected.txt
@@ -1071,6 +1071,7 @@
     property currentTime
     property defaultMuted
     property defaultPlaybackRate
+    property disablePictureInPicture
     property disableRemotePlayback
     property duration
     property ended
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
index 2575d850..884dddd 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -1576,6 +1576,7 @@
     getter onwebkitfullscreenerror
     getter onwheel
     getter origin
+    getter pictureInPictureElement
     getter pictureInPictureEnabled
     getter plugins
     getter pointerLockElement
@@ -3634,6 +3635,7 @@
     method constructor
 interface HTMLVideoElement : HTMLMediaElement
     attribute @@toStringTag
+    getter disablePictureInPicture
     getter height
     getter poster
     getter videoHeight
@@ -3650,6 +3652,7 @@
     method webkitEnterFullscreen
     method webkitExitFullScreen
     method webkitExitFullscreen
+    setter disablePictureInPicture
     setter height
     setter poster
     setter width
diff --git a/third_party/WebKit/Source/bindings/bindings.gni b/third_party/WebKit/Source/bindings/bindings.gni
index 2474de02..cf84666 100644
--- a/third_party/WebKit/Source/bindings/bindings.gni
+++ b/third_party/WebKit/Source/bindings/bindings.gni
@@ -112,6 +112,8 @@
                     "core/v8/V8CrossOriginSetterInfo.h",
                     "core/v8/V8DOMConfiguration.cpp",
                     "core/v8/V8DOMConfiguration.h",
+                    "core/v8/V8EmbedderGraphBuilder.cpp",
+                    "core/v8/V8EmbedderGraphBuilder.h",
                     "core/v8/V8ErrorHandler.cpp",
                     "core/v8/V8ErrorHandler.h",
                     "core/v8/V8EventListener.cpp",
diff --git a/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.cpp b/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.cpp
index 9369675..fd6df0bc 100644
--- a/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.cpp
@@ -147,6 +147,10 @@
     return v8::Local<v8::Promise>::Cast(value)->HasHandler();
   }
 
+  ExecutionContext* GetContext() {
+    return ExecutionContext::From(script_state_);
+  }
+
  private:
   Message(ScriptState* script_state,
           v8::Local<v8::Promise> promise,
@@ -216,10 +220,8 @@
     std::unique_ptr<Message>& message = reported_as_errors_.at(i);
     if (!message->IsCollected() && message->HasPromise(data.GetPromise())) {
       message->MakePromiseStrong();
-      Platform::Current()
-          ->CurrentThread()
-          ->Scheduler()
-          ->TimerTaskRunner()
+      message->GetContext()
+          ->GetTaskRunner(TaskType::kDOMManipulation)
           ->PostTask(FROM_HERE, WTF::Bind(&RejectedPromises::RevokeNow,
                                           scoped_refptr<RejectedPromises>(this),
                                           WTF::Passed(std::move(message))));
@@ -229,16 +231,11 @@
   }
 }
 
-std::unique_ptr<RejectedPromises::MessageQueue>
-RejectedPromises::CreateMessageQueue() {
-  return std::make_unique<MessageQueue>();
-}
-
 void RejectedPromises::Dispose() {
   if (queue_.IsEmpty())
     return;
 
-  std::unique_ptr<MessageQueue> queue = CreateMessageQueue();
+  std::unique_ptr<MessageQueue> queue = std::make_unique<MessageQueue>();
   queue->Swap(queue_);
   ProcessQueueNow(std::move(queue));
 }
@@ -247,15 +244,24 @@
   if (queue_.IsEmpty())
     return;
 
-  std::unique_ptr<MessageQueue> queue = CreateMessageQueue();
-  queue->Swap(queue_);
-  Platform::Current()
-      ->CurrentThread()
-      ->Scheduler()
-      ->TimerTaskRunner()
-      ->PostTask(FROM_HERE, WTF::Bind(&RejectedPromises::ProcessQueueNow,
-                                      scoped_refptr<RejectedPromises>(this),
-                                      WTF::Passed(std::move(queue))));
+  std::map<ExecutionContext*, std::unique_ptr<MessageQueue>> queues;
+  while (!queue_.IsEmpty()) {
+    std::unique_ptr<Message> message = queue_.TakeFirst();
+    ExecutionContext* context = message->GetContext();
+    if (queues.find(context) == queues.end()) {
+      queues.emplace(context, std::make_unique<MessageQueue>());
+    }
+    queues[context]->emplace_back(std::move(message));
+  }
+
+  for (auto& kv : queues) {
+    std::unique_ptr<MessageQueue> queue = std::make_unique<MessageQueue>();
+    queue->Swap(*kv.second);
+    kv.first->GetTaskRunner(blink::TaskType::kDOMManipulation)
+        ->PostTask(FROM_HERE, WTF::Bind(&RejectedPromises::ProcessQueueNow,
+                                        scoped_refptr<RejectedPromises>(this),
+                                        WTF::Passed(std::move(queue))));
+  }
 }
 
 void RejectedPromises::ProcessQueueNow(std::unique_ptr<MessageQueue> queue) {
diff --git a/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.h b/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.h
index 54c54fc..23a27df0 100644
--- a/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.h
+++ b/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.h
@@ -47,7 +47,6 @@
   RejectedPromises();
 
   using MessageQueue = Deque<std::unique_ptr<Message>>;
-  std::unique_ptr<MessageQueue> CreateMessageQueue();
 
   void ProcessQueueNow(std::unique_ptr<MessageQueue>);
   void RevokeNow(std::unique_ptr<Message>);
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8EmbedderGraphBuilder.cpp b/third_party/WebKit/Source/bindings/core/v8/V8EmbedderGraphBuilder.cpp
new file mode 100644
index 0000000..ecf0a5a
--- /dev/null
+++ b/third_party/WebKit/Source/bindings/core/v8/V8EmbedderGraphBuilder.cpp
@@ -0,0 +1,130 @@
+// 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 "bindings/core/v8/V8EmbedderGraphBuilder.h"
+
+#include "bindings/core/v8/ActiveScriptWrappable.h"
+#include "bindings/core/v8/V8Node.h"
+#include "platform/bindings/DOMWrapperMap.h"
+#include "platform/bindings/ScriptWrappable.h"
+#include "platform/bindings/ScriptWrappableVisitor.h"
+#include "platform/bindings/WrapperTypeInfo.h"
+
+namespace blink {
+
+V8EmbedderGraphBuilder::V8EmbedderGraphBuilder(v8::Isolate* isolate,
+                                               Graph* graph)
+    : isolate_(isolate), current_parent_(nullptr), graph_(graph) {}
+
+void V8EmbedderGraphBuilder::BuildEmbedderGraphCallback(
+    v8::Isolate* isolate,
+    v8::EmbedderGraph* graph) {
+  V8EmbedderGraphBuilder builder(isolate, graph);
+  builder.BuildEmbedderGraph();
+}
+
+void V8EmbedderGraphBuilder::BuildEmbedderGraph() {
+  isolate_->VisitHandlesWithClassIds(this);
+  VisitPendingActivities();
+  VisitTransitiveClosure();
+}
+
+void V8EmbedderGraphBuilder::VisitPersistentHandle(
+    v8::Persistent<v8::Value>* value,
+    uint16_t class_id) {
+  if (class_id != WrapperTypeInfo::kNodeClassId &&
+      class_id != WrapperTypeInfo::kObjectClassId)
+    return;
+  v8::Local<v8::Object> v8_value = v8::Local<v8::Object>::New(
+      isolate_, v8::Persistent<v8::Object>::Cast(*value));
+  ScriptWrappable* traceable = ToScriptWrappable(v8_value);
+  if (traceable) {
+    // Add v8_value => traceable edge.
+    Graph::Node* graph_node =
+        GraphNode(traceable, traceable->NameInHeapSnapshot());
+    graph_->AddEdge(GraphNode(v8_value), graph_node);
+    // Visit traceable members. This will also add traceable => v8_value edge.
+    ParentScope parent(this, graph_node);
+    traceable->TraceWrappers(this);
+  }
+}
+
+void V8EmbedderGraphBuilder::Visit(
+    const TraceWrapperV8Reference<v8::Value>& traced_wrapper) const {
+  const v8::PersistentBase<v8::Value>* value = &traced_wrapper.Get();
+  // Add an edge from the current parent to the V8 object.
+  v8::Local<v8::Value> v8_value = v8::Local<v8::Value>::New(isolate_, *value);
+  if (!v8_value.IsEmpty()) {
+    graph_->AddEdge(current_parent_, GraphNode(v8_value));
+  }
+}
+
+void V8EmbedderGraphBuilder::Visit(
+    const WrapperDescriptor& wrapper_descriptor) const {
+  // Add an edge from the current parent to this object.
+  // Also push the object to the worklist in order to process its members.
+  const void* traceable = wrapper_descriptor.traceable;
+  Graph::Node* graph_node =
+      GraphNode(traceable, wrapper_descriptor.name_callback(traceable));
+  graph_->AddEdge(current_parent_, graph_node);
+  if (!visited_.Contains(traceable)) {
+    visited_.insert(traceable);
+    worklist_.push_back(ToWorklistItem(graph_node, wrapper_descriptor));
+  }
+}
+
+void V8EmbedderGraphBuilder::Visit(DOMWrapperMap<ScriptWrappable>* wrapper_map,
+                                   const ScriptWrappable* key) const {
+  // Add an edge from the current parent to the V8 object.
+  v8::Local<v8::Value> v8_value =
+      wrapper_map->NewLocal(isolate_, const_cast<ScriptWrappable*>(key));
+  if (!v8_value.IsEmpty())
+    graph_->AddEdge(current_parent_, GraphNode(v8_value));
+}
+
+v8::EmbedderGraph::Node* V8EmbedderGraphBuilder::GraphNode(
+    const v8::Local<v8::Value>& value) const {
+  return graph_->V8Node(value);
+}
+
+v8::EmbedderGraph::Node* V8EmbedderGraphBuilder::GraphNode(
+    Traceable traceable,
+    const char* name) const {
+  auto iter = graph_node_.find(traceable);
+  if (iter != graph_node_.end())
+    return iter->value;
+  // Ownership of the new node is transferred to the graph_.
+  // graph_node_.at(tracable) is valid for all BuildEmbedderGraph execution.
+  auto node =
+      graph_->AddNode(std::unique_ptr<Graph::Node>(new EmbedderNode(name)));
+  graph_node_.insert(traceable, node);
+  return node;
+}
+
+void V8EmbedderGraphBuilder::VisitPendingActivities() {
+  // Ownership of the new node is transferred to the graph_.
+  Graph::Node* root = graph_->AddNode(
+      std::unique_ptr<Graph::Node>(new EmbedderRootNode("Pending activities")));
+  ParentScope parent(this, root);
+  ActiveScriptWrappableBase::TraceActiveScriptWrappables(isolate_, this);
+}
+
+V8EmbedderGraphBuilder::WorklistItem V8EmbedderGraphBuilder::ToWorklistItem(
+    Graph::Node* node,
+    const WrapperDescriptor& wrapper_descriptor) const {
+  return {node, wrapper_descriptor.traceable,
+          wrapper_descriptor.trace_wrappers_callback};
+}
+
+void V8EmbedderGraphBuilder::VisitTransitiveClosure() {
+  // Depth-first search.
+  while (!worklist_.empty()) {
+    auto item = worklist_.back();
+    worklist_.pop_back();
+    ParentScope parent(this, item.node);
+    item.trace_wrappers_callback(this, item.traceable);
+  }
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8EmbedderGraphBuilder.h b/third_party/WebKit/Source/bindings/core/v8/V8EmbedderGraphBuilder.h
new file mode 100644
index 0000000..9ab8f89
--- /dev/null
+++ b/third_party/WebKit/Source/bindings/core/v8/V8EmbedderGraphBuilder.h
@@ -0,0 +1,95 @@
+// 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 V8EmbedderGraphBuilder_h
+#define V8EmbedderGraphBuilder_h
+
+#include "platform/bindings/ScriptWrappableVisitor.h"
+#include "v8/include/v8-profiler.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+
+class V8EmbedderGraphBuilder : public ScriptWrappableVisitor,
+                               public v8::PersistentHandleVisitor {
+ public:
+  using Traceable = const void*;
+  using Graph = v8::EmbedderGraph;
+
+  V8EmbedderGraphBuilder(v8::Isolate*, Graph*);
+
+  static void BuildEmbedderGraphCallback(v8::Isolate*, v8::EmbedderGraph*);
+  void BuildEmbedderGraph();
+
+  // v8::PersistentHandleVisitor override.
+  void VisitPersistentHandle(v8::Persistent<v8::Value>*,
+                             uint16_t class_id) override;
+
+ protected:
+  // ScriptWrappableVisitor overrides.
+  void Visit(const TraceWrapperV8Reference<v8::Value>&) const final;
+  void Visit(const WrapperDescriptor&) const final;
+  void Visit(DOMWrapperMap<ScriptWrappable>*,
+             const ScriptWrappable*) const final;
+
+ private:
+  class EmbedderNode : public Graph::Node {
+   public:
+    explicit EmbedderNode(const char* name) : name_(name) {}
+
+    // Graph::Node overrides.
+    const char* Name() override { return name_; }
+    size_t SizeInBytes() override { return 0; }
+
+   private:
+    const char* name_;
+  };
+
+  class EmbedderRootNode : public EmbedderNode {
+   public:
+    explicit EmbedderRootNode(const char* name) : EmbedderNode(name) {}
+    // Graph::Node override.
+    bool IsRootNode() { return true; }
+  };
+
+  class ParentScope {
+    STACK_ALLOCATED();
+
+   public:
+    ParentScope(V8EmbedderGraphBuilder* visitor, Graph::Node* parent)
+        : visitor_(visitor) {
+      DCHECK_EQ(visitor->current_parent_, nullptr);
+      visitor->current_parent_ = parent;
+    }
+    ~ParentScope() { visitor_->current_parent_ = nullptr; }
+
+   private:
+    V8EmbedderGraphBuilder* visitor_;
+  };
+
+  struct WorklistItem {
+    Graph::Node* node;
+    Traceable traceable;
+    TraceWrappersCallback trace_wrappers_callback;
+  };
+
+  WorklistItem ToWorklistItem(Graph::Node*, const WrapperDescriptor&) const;
+
+  Graph::Node* GraphNode(const v8::Local<v8::Value>&) const;
+  Graph::Node* GraphNode(Traceable, const char* name) const;
+
+  void VisitPendingActivities();
+  void VisitTransitiveClosure();
+
+  v8::Isolate* isolate_;
+  Graph::Node* current_parent_;
+  mutable Graph* graph_;
+  mutable HashSet<Traceable> visited_;
+  mutable HashMap<Traceable, Graph::Node*> graph_node_;
+  mutable Deque<WorklistItem> worklist_;
+};
+
+}  // namespace blink
+
+#endif  // V8EmbedderGraphBuilder_h
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp b/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp
index aede214..aaadd3f3 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp
@@ -40,6 +40,7 @@
 #include "bindings/core/v8/V8BindingForCore.h"
 #include "bindings/core/v8/V8ContextSnapshot.h"
 #include "bindings/core/v8/V8DOMException.h"
+#include "bindings/core/v8/V8EmbedderGraphBuilder.h"
 #include "bindings/core/v8/V8ErrorEvent.h"
 #include "bindings/core/v8/V8ErrorHandler.h"
 #include "bindings/core/v8/V8GCController.h"
@@ -673,6 +674,8 @@
     profiler->SetWrapperClassInfoProvider(
         WrapperTypeInfo::kNodeClassId, &RetainedDOMInfo::CreateRetainedDOMInfo);
     profiler->SetGetRetainerInfosCallback(&V8GCController::GetRetainerInfos);
+    profiler->SetBuildEmbedderGraphCallback(
+        &V8EmbedderGraphBuilder::BuildEmbedderGraphCallback);
   }
 
   DCHECK(ThreadState::MainThreadState());
diff --git a/third_party/WebKit/Source/bindings/scripts/v8_dictionary.py b/third_party/WebKit/Source/bindings/scripts/v8_dictionary.py
index c3a7d36..4a51aaf 100644
--- a/third_party/WebKit/Source/bindings/scripts/v8_dictionary.py
+++ b/third_party/WebKit/Source/bindings/scripts/v8_dictionary.py
@@ -219,7 +219,9 @@
             return nullable_indicator_name
         if idl_type.is_union_type or idl_type.is_enum or idl_type.is_string_type:
             return '!%s_.IsNull()' % cpp_name
-        if idl_type.name in ['Any', 'Object']:
+        if idl_type.name == 'Any':
+            return '!({0}_.IsEmpty() || {0}_.IsUndefined())'.format(cpp_name)
+        if idl_type.name == 'Object':
             return '!({0}_.IsEmpty() || {0}_.IsNull() || {0}_.IsUndefined())'.format(cpp_name)
         if idl_type.name == 'Dictionary':
             return '!%s_.IsUndefinedOrNull()' % cpp_name
diff --git a/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.h b/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.h
index 4924330..cc912c1 100644
--- a/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.h
+++ b/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.h
@@ -53,7 +53,7 @@
   }
   void setAnyInRecordMember(const Vector<std::pair<String, ScriptValue>>&);
 
-  bool hasAnyMember() const { return !(any_member_.IsEmpty() || any_member_.IsNull() || any_member_.IsUndefined()); }
+  bool hasAnyMember() const { return !(any_member_.IsEmpty() || any_member_.IsUndefined()); }
   ScriptValue anyMember() const {
     return any_member_;
   }
diff --git a/third_party/WebKit/Source/build/scripts/templates/element_factory.cc.tmpl b/third_party/WebKit/Source/build/scripts/templates/element_factory.cc.tmpl
index c1e287de..bc12526 100644
--- a/third_party/WebKit/Source/build/scripts/templates/element_factory.cc.tmpl
+++ b/third_party/WebKit/Source/build/scripts/templates/element_factory.cc.tmpl
@@ -12,13 +12,6 @@
 {% if fallback_interface %}
 #include "core/{{namespace|lower}}/{{fallback_interface_header}}"
 {% endif %}
-{% if namespace == 'HTML' %}
-#include "core/html/custom/CustomElement.h"
-{% endif %}
-#include "core/html/custom/V0CustomElement.h"
-#include "core/html/custom/V0CustomElementRegistrationContext.h"
-#include "core/dom/Document.h"
-#include "core/frame/Settings.h"
 #include "platform/runtime_enabled_features.h"
 #include "platform/wtf/HashMap.h"
 
@@ -78,36 +71,4 @@
   return nullptr;
 }
 
-{{namespace}}Element* {{namespace}}ElementFactory::create{{namespace}}Element(
-    const AtomicString& localName,
-    Document& document,
-    CreateElementFlags flags) {
-  if (auto* element = {{namespace}}ElementFactory::CreateRaw{{namespace}}Element(localName, document, flags))
-    return element;
-
-  {% if namespace == 'HTML' %}
-  // createElement handles custom element creation itself in order to
-  // transmit exceptions.
-  // TODO(dominicc): When the HTML parser can pass an error
-  // reporting ExceptionState, and "v0" custom elements have been
-  // removed, consolidate custom element creation into one place.
-  if (flags != kCreatedByCreateElement && CustomElement::ShouldCreateCustomElement(localName)) {
-    QualifiedName tagName(g_null_atom, localName, HTMLNames::xhtmlNamespaceURI);
-    if (flags & kAsynchronousCustomElements)
-      return CustomElement::CreateCustomElementAsync(document, tagName, flags);
-    return CustomElement::CreateCustomElementSync(document, tagName);
-  }
-  {% endif %}
-
-  if (document.RegistrationContext() &&
-      V0CustomElement::IsValidName(localName)) {
-    Element* element = document.RegistrationContext()->CreateCustomTagElement(
-        document, QualifiedName(g_null_atom, localName, {{namespace}}Names::{{namespace_prefix}}NamespaceURI));
-    SECURITY_DCHECK(element->Is{{namespace}}Element());
-    return To{{namespace}}Element(element);
-  }
-
-  return {{fallback_interface}}::Create(QualifiedName(g_null_atom, localName, {{namespace}}Names::{{namespace_prefix}}NamespaceURI), document);
-}
-
 } // namespace blink
diff --git a/third_party/WebKit/Source/build/scripts/templates/element_factory.h.tmpl b/third_party/WebKit/Source/build/scripts/templates/element_factory.h.tmpl
index 2eeab7b..6a7345a 100644
--- a/third_party/WebKit/Source/build/scripts/templates/element_factory.h.tmpl
+++ b/third_party/WebKit/Source/build/scripts/templates/element_factory.h.tmpl
@@ -21,13 +21,6 @@
       const AtomicString& localName,
       Document&,
       CreateElementFlags flags);
-
-  // CreateRaw{{namespace}}Element() + custom element processing.
-  // If |localName| is unknown, a {{fallback_interface}} instance is returned.
-  static {{namespace}}Element* create{{namespace}}Element(
-      const AtomicString& localName,
-      Document&,
-      CreateElementFlags flags = kCreatedByParser);
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/css/CSSFontFeatureValue.cpp b/third_party/WebKit/Source/core/css/CSSFontFeatureValue.cpp
index 40a8743..61d2028a 100644
--- a/third_party/WebKit/Source/core/css/CSSFontFeatureValue.cpp
+++ b/third_party/WebKit/Source/core/css/CSSFontFeatureValue.cpp
@@ -37,8 +37,12 @@
   StringBuilder builder;
   builder.Append('"');
   builder.Append(tag_);
-  builder.Append("\" ");
-  builder.AppendNumber(value_);
+  builder.Append('"');
+  // Omit the value if it's 1 as 1 is implied by default.
+  if (value_ != 1) {
+    builder.Append(' ');
+    builder.AppendNumber(value_);
+  }
   return builder.ToString();
 }
 
diff --git a/third_party/WebKit/Source/core/css/SelectorChecker.cpp b/third_party/WebKit/Source/core/css/SelectorChecker.cpp
index 86682bcaf..d8ae925 100644
--- a/third_party/WebKit/Source/core/css/SelectorChecker.cpp
+++ b/third_party/WebKit/Source/core/css/SelectorChecker.cpp
@@ -504,10 +504,8 @@
     }
 
     case CSSSelector::kShadowSlot: {
-      if (IsHTMLSlotElement(context.element) &&
-          ToHTMLSlotElement(context.element)->SupportsAssignment()) {
+      if (ToHTMLSlotElementIfSupportsAssignmentOrNull(*context.element))
         return kSelectorFailsCompletely;
-      }
       const HTMLSlotElement* slot = FindSlotElementInScope(context);
       if (!slot)
         return kSelectorFailsCompletely;
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index c274aac..f0c9b1b4 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -906,8 +906,13 @@
           *this,
           QualifiedName(g_null_atom, local_name, HTMLNames::xhtmlNamespaceURI));
     }
-    return HTMLElementFactory::createHTMLElement(local_name, *this,
-                                                 kCreatedByCreateElement);
+    if (Element* element = HTMLElementFactory::CreateRawHTMLElement(
+            local_name, *this, kCreatedByCreateElement))
+      return element;
+    QualifiedName q_name(g_null_atom, local_name, HTMLNames::xhtmlNamespaceURI);
+    if (RegistrationContext() && V0CustomElement::IsValidName(local_name))
+      return RegistrationContext()->CreateCustomTagElement(*this, q_name);
+    return HTMLUnknownElement::Create(q_name, *this);
   }
   return Element::Create(QualifiedName(g_null_atom, name, g_null_atom), this);
 }
@@ -958,8 +963,6 @@
                            ? HTMLNames::xhtmlNamespaceURI
                            : g_null_atom);
 
-  // TODO(tkent): Share the code with createElementNS(namespace_uri,
-  // qualified_name, string_or_options, exception_state).
   bool is_v1 = string_or_options.IsDictionary() || !RegistrationContext();
   bool create_v1_builtin =
       string_or_options.IsDictionary() &&
@@ -970,41 +973,10 @@
   // 3.
   const AtomicString& is =
       AtomicString(GetTypeExtension(this, string_or_options, exception_state));
-  const AtomicString& name = should_create_builtin ? is : converted_local_name;
 
-  // 4. Let definition be result of lookup up custom element definition
-  CustomElementDefinition* definition = nullptr;
-  if (is_v1 && q_name.NamespaceURI() == HTMLNames::xhtmlNamespaceURI) {
-    // Is the runtime flag enabled for customized builtin elements?
-    const CustomElementDescriptor desc =
-        RuntimeEnabledFeatures::CustomElementsBuiltinEnabled()
-            ? CustomElementDescriptor(name, converted_local_name)
-            : CustomElementDescriptor(converted_local_name,
-                                      converted_local_name);
-    if (CustomElementRegistry* registry = CustomElement::Registry(*this))
-      definition = registry->DefinitionFor(desc);
-
-    // 5. If 'is' is non-null and definition is null, throw NotFoundError
-    // TODO(yurak): update when https://github.com/w3c/webcomponents/issues/608
-    //              is resolved
-    if (!definition && create_v1_builtin) {
-      exception_state.ThrowDOMException(kNotFoundError,
-                                        "Custom element definition not found.");
-      return nullptr;
-    }
-  }
-
-  // 7. Let element be the result of creating an element
-  Element* element;
-
-  if (definition) {
-    element = CustomElement::CreateCustomElementSync(*this, q_name, definition);
-  } else if (V0CustomElement::IsValidName(local_name) &&
-             RegistrationContext()) {
-    element = RegistrationContext()->CreateCustomTagElement(*this, q_name);
-  } else {
-    element = CreateRawElement(q_name, kCreatedByCreateElement);
-  }
+  // 5. Let element be the result of creating an element given ...
+  Element* element =
+      CreateElement(q_name, is_v1, should_create_builtin ? is : g_null_atom);
 
   // 8. If 'is' is non-null, set 'is' attribute
   if (!is.IsEmpty()) {
@@ -1078,7 +1050,6 @@
   // 2.
   const AtomicString& is =
       AtomicString(GetTypeExtension(this, string_or_options, exception_state));
-  const AtomicString& name = should_create_builtin ? is : q_name.LocalName();
 
   if (!IsValidElementName(this, qualified_name)) {
     exception_state.ThrowDOMException(
@@ -1087,20 +1058,38 @@
     return nullptr;
   }
 
-  // 3. Let definition be result of lookup up custom element definition
+  // 3. Let element be the result of creating an element
+  Element* element =
+      CreateElement(q_name, is_v1, should_create_builtin ? is : g_null_atom);
+
+  // 4. If 'is' is non-null, set 'is' attribute
+  if (!is.IsEmpty()) {
+    if (element->GetCustomElementState() != CustomElementState::kCustom) {
+      V0CustomElementRegistrationContext::SetIsAttributeAndTypeExtension(
+          element, is);
+    } else if (string_or_options.IsDictionary()) {
+      element->setAttribute(HTMLNames::isAttr, is);
+    }
+  }
+
+  return element;
+}
+
+// Entry point of "create an element".
+// https://dom.spec.whatwg.org/#concept-create-element
+// TODO(tkent): Add synchronous custom element flag.
+// TODO(tkent): Update or remove |is_v1| argument. At this moment, this
+// function is called only by createElement*() with string_or_options
+// argument. So we can determine v0 or v1 precisely.
+Element* Document::CreateElement(const QualifiedName& q_name,
+                                 bool is_v1,
+                                 const AtomicString& is) {
   CustomElementDefinition* definition = nullptr;
-  if (is_v1 && namespace_uri == HTMLNames::xhtmlNamespaceURI) {
-    const CustomElementDescriptor desc =
-        CustomElementDescriptor(name, q_name.LocalName());
+  if (is_v1 && q_name.NamespaceURI() == HTMLNames::xhtmlNamespaceURI) {
+    const CustomElementDescriptor desc(is.IsEmpty() ? q_name.LocalName() : is,
+                                       q_name.LocalName());
     if (CustomElementRegistry* registry = CustomElement::Registry(*this))
       definition = registry->DefinitionFor(desc);
-
-    // 4. If 'is' is non-null and definition is null, throw NotFoundError
-    if (!definition && create_v1_builtin) {
-      exception_state.ThrowDOMException(kNotFoundError,
-                                        "Custom element definition not found.");
-      return nullptr;
-    }
   }
 
   // 5. Let element be the result of creating an element
@@ -1113,18 +1102,13 @@
     element = RegistrationContext()->CreateCustomTagElement(*this, q_name);
   } else {
     element = CreateRawElement(q_name, kCreatedByCreateElement);
+    // 7.3. If namespace is the HTML namespace, and either localName is
+    // a valid custom element name or is is non-null, then set result’s
+    // custom element state to "undefined".
+    if (q_name.NamespaceURI() == HTMLNames::xhtmlNamespaceURI &&
+        (CustomElement::IsValidName(q_name.LocalName()) || !is.IsEmpty()))
+      element->SetCustomElementState(CustomElementState::kUndefined);
   }
-
-  // 6. If 'is' is non-null, set 'is' attribute
-  if (!is.IsEmpty()) {
-    if (element->GetCustomElementState() != CustomElementState::kCustom) {
-      V0CustomElementRegistrationContext::SetIsAttributeAndTypeExtension(
-          element, is);
-    } else if (string_or_options.IsDictionary()) {
-      element->setAttribute(HTMLNames::isAttr, is);
-    }
-  }
-
   return element;
 }
 
@@ -1455,10 +1439,36 @@
 
   // FIXME: Use registered namespaces and look up in a hash to find the right
   // factory.
-  if (q_name.NamespaceURI() == xhtmlNamespaceURI)
-    e = HTMLElementFactory::createHTMLElement(q_name.LocalName(), *this, flags);
-  else if (q_name.NamespaceURI() == SVGNames::svgNamespaceURI)
-    e = SVGElementFactory::createSVGElement(q_name.LocalName(), *this, flags);
+  const AtomicString& local_name = q_name.LocalName();
+  if (q_name.NamespaceURI() == xhtmlNamespaceURI) {
+    e = HTMLElementFactory::CreateRawHTMLElement(local_name, *this, flags);
+    if (!e) {
+      // TODO(dominicc): When the HTML parser can pass an error
+      // reporting ExceptionState, and "v0" custom elements have been
+      // removed, consolidate custom element creation into one place.
+      if (flags != kCreatedByCreateElement &&
+          CustomElement::ShouldCreateCustomElement(local_name)) {
+        if (flags & kAsynchronousCustomElements)
+          e = CustomElement::CreateCustomElementAsync(*this, q_name, flags);
+        else
+          e = CustomElement::CreateCustomElementSync(*this, q_name);
+      } else if (RegistrationContext() &&
+                 V0CustomElement::IsValidName(local_name)) {
+        e = RegistrationContext()->CreateCustomTagElement(*this, q_name);
+      } else {
+        e = HTMLUnknownElement::Create(q_name, *this);
+      }
+    }
+  } else if (q_name.NamespaceURI() == SVGNames::svgNamespaceURI) {
+    e = SVGElementFactory::CreateRawSVGElement(local_name, *this, flags);
+    if (!e) {
+      if (RegistrationContext() && V0CustomElement::IsValidName(local_name)) {
+        e = RegistrationContext()->CreateCustomTagElement(*this, q_name);
+      } else {
+        e = SVGUnknownElement::Create(q_name, *this);
+      }
+    }
+  }
 
   if (e)
     saw_elements_in_known_namespaces_ = true;
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h
index 2c878c7..f11650c 100644
--- a/third_party/WebKit/Source/core/dom/Document.h
+++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -67,6 +67,7 @@
 #include "core/page/PageVisibilityState.h"
 #include "platform/Length.h"
 #include "platform/Timer.h"
+#include "platform/WebTaskRunner.h"
 #include "platform/bindings/TraceWrapperMember.h"
 #include "platform/loader/fetch/ClientHintsPreferences.h"
 #include "platform/scroll/ScrollTypes.h"
@@ -349,6 +350,10 @@
   Element* createElement(const QualifiedName&, CreateElementFlags);
   // Creates an element without custom element processing.
   Element* CreateRawElement(const QualifiedName&, CreateElementFlags);
+  // "create an element" defined in DOM standard.
+  Element* CreateElement(const QualifiedName&,
+                         bool is_v1,
+                         const AtomicString& is);
 
   Element* ElementFromPoint(double x, double y) const;
   HeapVector<Member<Element>> ElementsFromPoint(double x, double y) const;
diff --git a/third_party/WebKit/Source/core/dom/FlatTreeTraversal.cpp b/third_party/WebKit/Source/core/dom/FlatTreeTraversal.cpp
index b7fb944..8c58b16 100644
--- a/third_party/WebKit/Source/core/dom/FlatTreeTraversal.cpp
+++ b/third_party/WebKit/Source/core/dom/FlatTreeTraversal.cpp
@@ -59,14 +59,13 @@
        sibling = (direction == kTraversalDirectionForward
                       ? sibling->nextSibling()
                       : sibling->previousSibling())) {
-    if (auto* slot = ToHTMLSlotElementOrNull(*sibling)) {
-      if (slot->SupportsAssignment()) {
-        if (Node* found = (direction == kTraversalDirectionForward
-                               ? slot->FirstDistributedNode()
-                               : slot->LastDistributedNode()))
-          return found;
-        continue;
-      }
+    if (const HTMLSlotElement* slot =
+            ToHTMLSlotElementIfSupportsAssignmentOrNull(*sibling)) {
+      if (Node* found = (direction == kTraversalDirectionForward
+                             ? slot->FirstDistributedNode()
+                             : slot->LastDistributedNode()))
+        return found;
+      continue;
     }
     if (node->IsInV0ShadowTree())
       return V0ResolveDistributionStartingAt(*sibling, direction);
@@ -78,8 +77,7 @@
 Node* FlatTreeTraversal::V0ResolveDistributionStartingAt(
     const Node& node,
     TraversalDirection direction) {
-  DCHECK(!IsHTMLSlotElement(node) ||
-         !ToHTMLSlotElement(node).SupportsAssignment());
+  DCHECK(!ToHTMLSlotElementIfSupportsAssignmentOrNull(node));
   for (const Node* sibling = &node; sibling;
        sibling = (direction == kTraversalDirectionForward
                       ? sibling->nextSibling()
@@ -117,8 +115,9 @@
 
   // Slotted nodes are already handled in traverseSiblingsForV1HostChild()
   // above, here is for fallback contents.
-  if (auto* slot = ToHTMLSlotElementOrNull(node.parentElement())) {
-    if (slot->SupportsAssignment() && slot->AssignedNodes().IsEmpty())
+  if (auto* slot =
+          ToHTMLSlotElementIfSupportsAssignmentOrNull(node.parentElement())) {
+    if (slot->AssignedNodes().IsEmpty())
       return TraverseSiblings(*slot, direction);
   }
 
@@ -167,12 +166,11 @@
     return TraverseParent(*slot);
   }
 
-  if (auto* slot = ToHTMLSlotElementOrNull(node.parentElement())) {
-    if (slot->SupportsAssignment()) {
-      if (!slot->AssignedNodes().IsEmpty())
-        return nullptr;
-      return TraverseParent(*slot, details);
-    }
+  if (auto* slot =
+          ToHTMLSlotElementIfSupportsAssignmentOrNull(node.parentElement())) {
+    if (!slot->AssignedNodes().IsEmpty())
+      return nullptr;
+    return TraverseParent(*slot, details);
   }
 
   if (CanBeDistributedToV0InsertionPoint(node))
diff --git a/third_party/WebKit/Source/core/dom/Node.cpp b/third_party/WebKit/Source/core/dom/Node.cpp
index 4e3429c..f9f218f 100644
--- a/third_party/WebKit/Source/core/dom/Node.cpp
+++ b/third_party/WebKit/Source/core/dom/Node.cpp
@@ -1169,8 +1169,7 @@
 }
 
 bool Node::IsActiveSlotOrActiveV0InsertionPoint() const {
-  return (IsHTMLSlotElement(*this) &&
-          ToHTMLSlotElement(*this).SupportsAssignment()) ||
+  return ToHTMLSlotElementIfSupportsAssignmentOrNull(*this) ||
          IsActiveV0InsertionPoint(*this);
 }
 
@@ -2686,15 +2685,13 @@
       slot->DidSlotChange(slot_change_type);
   } else if (IsInV1ShadowTree()) {
     // Checking for fallback content if the node is in a v1 shadow tree.
-    Element* parent = parentElement();
-    if (parent && IsHTMLSlotElement(parent)) {
-      HTMLSlotElement& parent_slot = ToHTMLSlotElement(*parent);
-      DCHECK(parent_slot.SupportsAssignment());
+    if (auto* parent_slot = ToHTMLSlotElementOrNull(parentElement())) {
+      DCHECK(parent_slot->SupportsAssignment());
       // The parent_slot's assigned nodes might not be calculated because they
       // are lazy evaluated later at UpdateDistribution() so we have to check it
       // here.
-      if (!parent_slot.HasAssignedNodesSlow())
-        parent_slot.DidSlotChange(slot_change_type);
+      if (!parent_slot->HasAssignedNodesSlow())
+        parent_slot->DidSlotChange(slot_change_type);
     }
   }
 }
diff --git a/third_party/WebKit/Source/core/dom/ng/flat_tree_traversal_ng.cc b/third_party/WebKit/Source/core/dom/ng/flat_tree_traversal_ng.cc
index f4a94fb..f1430bf 100644
--- a/third_party/WebKit/Source/core/dom/ng/flat_tree_traversal_ng.cc
+++ b/third_party/WebKit/Source/core/dom/ng/flat_tree_traversal_ng.cc
@@ -43,15 +43,13 @@
 
 Node* FlatTreeTraversalNg::TraverseChild(const Node& node,
                                          TraversalDirection direction) {
-  if (auto* slot = ToHTMLSlotElementOrNull(node)) {
-    if (slot->SupportsAssignment()) {
-      if (slot->AssignedNodes().IsEmpty()) {
-        return direction == kTraversalDirectionForward ? slot->firstChild()
-                                                       : slot->lastChild();
-      }
-      return direction == kTraversalDirectionForward ? slot->FirstAssignedNode()
-                                                     : slot->LastAssignedNode();
+  if (auto* slot = ToHTMLSlotElementIfSupportsAssignmentOrNull(node)) {
+    if (slot->AssignedNodes().IsEmpty()) {
+      return direction == kTraversalDirectionForward ? slot->firstChild()
+                                                     : slot->lastChild();
     }
+    return direction == kTraversalDirectionForward ? slot->FirstAssignedNode()
+                                                   : slot->LastAssignedNode();
   }
 
   Node* child;
@@ -94,8 +92,7 @@
 Node* FlatTreeTraversalNg::V0ResolveDistributionStartingAt(
     const Node& node,
     TraversalDirection direction) {
-  DCHECK(!IsHTMLSlotElement(node) ||
-         !ToHTMLSlotElement(node).SupportsAssignment());
+  DCHECK(!ToHTMLSlotElementIfSupportsAssignmentOrNull(node));
   for (const Node* sibling = &node; sibling;
        sibling = (direction == kTraversalDirectionForward
                       ? sibling->nextSibling()
@@ -181,10 +178,11 @@
   if (node.IsChildOfV1ShadowHost())
     return node.AssignedSlot();
 
-  if (auto* slot = ToHTMLSlotElementOrNull(node.parentElement())) {
-    if (slot->SupportsAssignment() && !slot->AssignedNodes().IsEmpty())
+  if (auto* parent_slot =
+          ToHTMLSlotElementIfSupportsAssignmentOrNull(node.parentElement())) {
+    if (!parent_slot->AssignedNodes().IsEmpty())
       return nullptr;
-    return slot;
+    return parent_slot;
   }
 
   if (CanBeDistributedToV0InsertionPoint(node))
diff --git a/third_party/WebKit/Source/core/editing/DOMSelection.cpp b/third_party/WebKit/Source/core/editing/DOMSelection.cpp
index e5378d1..a4483ef 100644
--- a/third_party/WebKit/Source/core/editing/DOMSelection.cpp
+++ b/third_party/WebKit/Source/core/editing/DOMSelection.cpp
@@ -288,7 +288,6 @@
   UpdateFrameSelection(
       SelectionInDOMTree::Builder()
           .Collapse(Position(node, offset))
-          .SetIsDirectional(GetFrame()->Selection().IsDirectional())
           .Build(),
       new_range,
       SetSelectionOptions::Builder()
@@ -418,7 +417,6 @@
   UpdateFrameSelection(
       SelectionInDOMTree::Builder()
           .SetBaseAndExtentDeprecated(base_position, extent_position)
-          .SetIsDirectional(true)
           .Build(),
       new_range, SetSelectionOptions::Builder().SetIsDirectional(true).Build());
 }
@@ -548,7 +546,7 @@
   else
     builder.Collapse(old_anchor).Extend(new_focus);
   UpdateFrameSelection(
-      builder.SetIsDirectional(true).Build(), new_range,
+      builder.Build(), new_range,
       SetSelectionOptions::Builder().SetIsDirectional(true).Build());
 }
 
diff --git a/third_party/WebKit/Source/core/editing/FrameSelection.cpp b/third_party/WebKit/Source/core/editing/FrameSelection.cpp
index 0cdbe90..6946bc5 100644
--- a/third_party/WebKit/Source/core/editing/FrameSelection.cpp
+++ b/third_party/WebKit/Source/core/editing/FrameSelection.cpp
@@ -170,7 +170,6 @@
   const VisiblePosition position =
       VisiblePositionForContentsPoint(point, GetFrame());
   SelectionInDOMTree::Builder builder;
-  builder.SetIsDirectional(GetSelectionInDOMTree().IsDirectional());
   if (position.IsNotNull())
     builder.Collapse(position.ToPositionWithAffinity());
   SetSelection(builder.Build(), SetSelectionOptions::Builder()
@@ -197,19 +196,14 @@
 }
 
 bool FrameSelection::SetSelectionDeprecated(
-    const SelectionInDOMTree& passed_selection,
+    const SelectionInDOMTree& new_selection,
     const SetSelectionOptions& passed_options) {
-  DCHECK(IsAvailable());
-  passed_selection.AssertValidFor(GetDocument());
-
   SetSelectionOptions::Builder options_builder(passed_options);
-  SelectionInDOMTree::Builder builder(passed_selection);
   if (ShouldAlwaysUseDirectionalSelection(frame_)) {
-    builder.SetIsDirectional(true);
     options_builder.SetIsDirectional(true);
   }
-  SelectionInDOMTree new_selection = builder.Build();
   SetSelectionOptions options = options_builder.Build();
+
   if (granularity_strategy_ && !options.DoNotClearStrategy())
     granularity_strategy_->Clear();
   granularity_ = options.Granularity();
diff --git a/third_party/WebKit/Source/core/editing/GranularityStrategyTest.cpp b/third_party/WebKit/Source/core/editing/GranularityStrategyTest.cpp
index 709da400..79f7d4b 100644
--- a/third_party/WebKit/Source/core/editing/GranularityStrategyTest.cpp
+++ b/third_party/WebKit/Source/core/editing/GranularityStrategyTest.cpp
@@ -708,7 +708,6 @@
   const SelectionInDOMTree& selection_in_dom_tree =
       SelectionInDOMTree::Builder()
           .Collapse(Position(sample->firstChild(), 2))
-          .SetIsDirectional(true)
           .Build();
   Selection().SetSelection(selection_in_dom_tree,
                            SetSelectionOptions::Builder()
@@ -745,7 +744,6 @@
   const SelectionInDOMTree& selection_in_dom_tree =
       SelectionInDOMTree::Builder()
           .Collapse(Position(sample->firstChild(), 2))
-          .SetIsDirectional(true)
           .Build();
   Selection().SetSelection(selection_in_dom_tree,
                            SetSelectionOptions::Builder()
diff --git a/third_party/WebKit/Source/core/editing/SelectionController.cpp b/third_party/WebKit/Source/core/editing/SelectionController.cpp
index a2faa67..146b9f6 100644
--- a/third_party/WebKit/Source/core/editing/SelectionController.cpp
+++ b/third_party/WebKit/Source/core/editing/SelectionController.cpp
@@ -892,7 +892,6 @@
   const bool selection_is_directional =
       frame_->GetEditor().Behavior().ShouldConsiderSelectionAsDirectional() ||
       set_selection_options.IsDirectional();
-  builder.SetIsDirectional(selection_is_directional);
   const SelectionInFlatTree& selection_in_flat_tree = builder.Build();
 
   const bool selection_remains_the_same =
diff --git a/third_party/WebKit/Source/core/editing/SelectionEditor.cpp b/third_party/WebKit/Source/core/editing/SelectionEditor.cpp
index 83f1c13..208b86d3 100644
--- a/third_party/WebKit/Source/core/editing/SelectionEditor.cpp
+++ b/third_party/WebKit/Source/core/editing/SelectionEditor.cpp
@@ -56,9 +56,6 @@
   cached_visible_selection_in_flat_tree_ = VisibleSelectionInFlatTree();
   cached_visible_selection_in_dom_tree_is_dirty_ = false;
   cached_visible_selection_in_flat_tree_is_dirty_ = false;
-  if (!ShouldAlwaysUseDirectionalSelection())
-    return;
-  selection_.is_directional_ = true;
 }
 
 void SelectionEditor::Dispose() {
@@ -401,8 +398,7 @@
     builder.Collapse(base);
   else if (extent.IsNotNull())
     builder.Collapse(extent);
-  builder.SetAffinity(selection_.Affinity())
-      .SetIsDirectional(selection_.IsDirectional());
+  builder.SetAffinity(selection_.Affinity());
   cached_visible_selection_in_flat_tree_ =
       CreateVisibleSelection(builder.Build());
   if (!cached_visible_selection_in_flat_tree_.IsNone())
diff --git a/third_party/WebKit/Source/core/editing/SelectionModifier.cpp b/third_party/WebKit/Source/core/editing/SelectionModifier.cpp
index ab72bfea..b44acf4 100644
--- a/third_party/WebKit/Source/core/editing/SelectionModifier.cpp
+++ b/third_party/WebKit/Source/core/editing/SelectionModifier.cpp
@@ -666,7 +666,6 @@
       current_selection_ =
           SelectionInDOMTree::Builder()
               .Collapse(position.ToPositionWithAffinity())
-              .SetIsDirectional(ShouldAlwaysUseDirectionalSelection(GetFrame()))
               .Build();
       break;
     case SelectionModifyAlteration::kExtend:
@@ -703,7 +702,6 @@
         current_selection_ = SelectionInDOMTree::Builder()
                                  .Collapse(selection_.Base())
                                  .Extend(position.DeepEquivalent())
-                                 .SetIsDirectional(true)
                                  .Build();
       } else {
         TextDirection text_direction = DirectionOfEnclosingBlock();
@@ -719,7 +717,6 @@
                                 : position.DeepEquivalent())
                   .Extend(selection_.IsBaseFirst() ? position.DeepEquivalent()
                                                    : selection_.Extent())
-                  .SetIsDirectional(true)
                   .Build();
         } else {
           current_selection_ =
@@ -728,7 +725,6 @@
                                                      : selection_.Base())
                   .Extend(selection_.IsBaseFirst() ? selection_.Extent()
                                                    : position.DeepEquivalent())
-                  .SetIsDirectional(true)
                   .Build();
         }
       }
@@ -826,7 +822,6 @@
       current_selection_ =
           SelectionInDOMTree::Builder()
               .Collapse(result.ToPositionWithAffinity())
-              .SetIsDirectional(ShouldAlwaysUseDirectionalSelection(GetFrame()))
               .SetAffinity(direction == SelectionModifyVerticalDirection::kUp
                                ? TextAffinity::kUpstream
                                : TextAffinity::kDownstream)
@@ -836,7 +831,6 @@
       current_selection_ = SelectionInDOMTree::Builder()
                                .Collapse(selection_.Base())
                                .Extend(result.DeepEquivalent())
-                               .SetIsDirectional(true)
                                .Build();
       break;
     }
diff --git a/third_party/WebKit/Source/core/editing/SelectionTemplate.cpp b/third_party/WebKit/Source/core/editing/SelectionTemplate.cpp
index 6e039d1..5b076ad 100644
--- a/third_party/WebKit/Source/core/editing/SelectionTemplate.cpp
+++ b/third_party/WebKit/Source/core/editing/SelectionTemplate.cpp
@@ -16,8 +16,7 @@
     : base_(other.base_),
       extent_(other.extent_),
       affinity_(other.affinity_),
-      direction_(other.direction_),
-      is_directional_(other.is_directional_)
+      direction_(other.direction_)
 #if DCHECK_IS_ON()
       ,
       dom_tree_version_(other.dom_tree_version_)
@@ -40,8 +39,7 @@
     return false;
   DCHECK_EQ(base_.GetDocument(), other.GetDocument()) << *this << ' ' << other;
   return base_ == other.base_ && extent_ == other.extent_ &&
-         affinity_ == other.affinity_ &&
-         is_directional_ == other.is_directional_;
+         affinity_ == other.affinity_;
 }
 
 template <typename Strategy>
@@ -383,13 +381,6 @@
   return SetBaseAndExtent(EphemeralRangeTemplate<Strategy>());
 }
 
-template <typename Strategy>
-typename SelectionTemplate<Strategy>::Builder&
-SelectionTemplate<Strategy>::Builder::SetIsDirectional(bool is_directional) {
-  selection_.is_directional_ = is_directional;
-  return *this;
-}
-
 // ---
 
 template <typename Strategy>
@@ -422,7 +413,6 @@
       .SetAffinity(selection_in_flat_tree.Affinity())
       .SetBaseAndExtent(ToPositionInDOMTree(selection_in_flat_tree.Base()),
                         ToPositionInDOMTree(selection_in_flat_tree.Extent()))
-      .SetIsDirectional(selection_in_flat_tree.IsDirectional())
       .Build();
 }
 
@@ -432,7 +422,6 @@
       .SetAffinity(selection.Affinity())
       .SetBaseAndExtent(ToPositionInFlatTree(selection.Base()),
                         ToPositionInFlatTree(selection.Extent()))
-      .SetIsDirectional(selection.IsDirectional())
       .Build();
 }
 
diff --git a/third_party/WebKit/Source/core/editing/SelectionTemplate.h b/third_party/WebKit/Source/core/editing/SelectionTemplate.h
index b9431852..5571541 100644
--- a/third_party/WebKit/Source/core/editing/SelectionTemplate.h
+++ b/third_party/WebKit/Source/core/editing/SelectionTemplate.h
@@ -68,7 +68,6 @@
         const PositionTemplate<Strategy>& extent);
 
     Builder& SetAffinity(TextAffinity);
-    Builder& SetIsDirectional(bool);
 
    private:
     SelectionTemplate selection_;
@@ -107,7 +106,6 @@
   TextAffinity Affinity() const { return affinity_; }
   bool IsBaseFirst() const;
   bool IsCaret() const;
-  bool IsDirectional() const { return is_directional_; }
   bool IsNone() const { return base_.IsNull(); }
   bool IsRange() const;
 
@@ -147,7 +145,6 @@
   PositionTemplate<Strategy> extent_;
   TextAffinity affinity_ = TextAffinity::kDownstream;
   mutable Direction direction_ = Direction::kForward;
-  bool is_directional_ = false;
 #if DCHECK_IS_ON()
   uint64_t dom_tree_version_;
 #endif
diff --git a/third_party/WebKit/Source/core/editing/SelectionTemplateTest.cpp b/third_party/WebKit/Source/core/editing/SelectionTemplateTest.cpp
index e4886920..829b7e2 100644
--- a/third_party/WebKit/Source/core/editing/SelectionTemplateTest.cpp
+++ b/third_party/WebKit/Source/core/editing/SelectionTemplateTest.cpp
@@ -17,7 +17,6 @@
 
   EXPECT_EQ(TextAffinity::kDownstream, selection.Affinity());
   EXPECT_TRUE(selection.IsBaseFirst());
-  EXPECT_FALSE(selection.IsDirectional());
   EXPECT_TRUE(selection.IsNone());
   EXPECT_EQ(Position(), selection.Base());
   EXPECT_EQ(Position(), selection.Extent());
@@ -37,7 +36,6 @@
 
   EXPECT_EQ(TextAffinity::kDownstream, selection.Affinity());
   EXPECT_FALSE(selection.IsBaseFirst());
-  EXPECT_FALSE(selection.IsDirectional());
   EXPECT_FALSE(selection.IsNone());
   EXPECT_EQ(base, selection.Base());
   EXPECT_EQ(extent, selection.Extent());
@@ -54,7 +52,6 @@
 
   EXPECT_EQ(TextAffinity::kDownstream, selection.Affinity());
   EXPECT_TRUE(selection.IsBaseFirst());
-  EXPECT_FALSE(selection.IsDirectional());
   EXPECT_FALSE(selection.IsNone());
   EXPECT_EQ(position, selection.Base());
   EXPECT_EQ(position, selection.Extent());
@@ -73,7 +70,6 @@
 
   EXPECT_EQ(TextAffinity::kDownstream, selection.Affinity());
   EXPECT_TRUE(selection.IsBaseFirst());
-  EXPECT_FALSE(selection.IsDirectional());
   EXPECT_FALSE(selection.IsNone());
   EXPECT_EQ(base, selection.Base());
   EXPECT_EQ(extent, selection.Extent());
@@ -97,7 +93,6 @@
 
   EXPECT_EQ(TextAffinity::kDownstream, backward_selection.Affinity());
   EXPECT_FALSE(backward_selection.IsBaseFirst());
-  EXPECT_FALSE(backward_selection.IsDirectional());
   EXPECT_FALSE(backward_selection.IsNone());
   EXPECT_EQ(end, backward_selection.Base());
   EXPECT_EQ(start, backward_selection.Extent());
@@ -107,7 +102,6 @@
 
   EXPECT_EQ(TextAffinity::kDownstream, forward_selection.Affinity());
   EXPECT_TRUE(forward_selection.IsBaseFirst());
-  EXPECT_FALSE(forward_selection.IsDirectional());
   EXPECT_FALSE(forward_selection.IsNone());
   EXPECT_EQ(start, forward_selection.Base());
   EXPECT_EQ(end, forward_selection.Extent());
@@ -117,7 +111,6 @@
 
   EXPECT_EQ(TextAffinity::kDownstream, collapsed_selection.Affinity());
   EXPECT_TRUE(collapsed_selection.IsBaseFirst());
-  EXPECT_FALSE(collapsed_selection.IsDirectional());
   EXPECT_FALSE(collapsed_selection.IsNone());
   EXPECT_EQ(start, collapsed_selection.Base());
   EXPECT_EQ(start, collapsed_selection.Extent());
diff --git a/third_party/WebKit/Source/core/editing/VisibleSelection.cpp b/third_party/WebKit/Source/core/editing/VisibleSelection.cpp
index 4aae1a40..50eacbaa 100644
--- a/third_party/WebKit/Source/core/editing/VisibleSelection.cpp
+++ b/third_party/WebKit/Source/core/editing/VisibleSelection.cpp
@@ -45,9 +45,7 @@
 
 template <typename Strategy>
 VisibleSelectionTemplate<Strategy>::VisibleSelectionTemplate()
-    : affinity_(TextAffinity::kDownstream),
-      base_is_first_(true),
-      is_directional_(false) {}
+    : affinity_(TextAffinity::kDownstream), base_is_first_(true) {}
 
 template <typename Strategy>
 VisibleSelectionTemplate<Strategy>::VisibleSelectionTemplate(
@@ -55,8 +53,7 @@
     : base_(selection.Base()),
       extent_(selection.Extent()),
       affinity_(selection.Affinity()),
-      base_is_first_(selection.IsBaseFirst()),
-      is_directional_(selection.IsDirectional()) {}
+      base_is_first_(selection.IsBaseFirst()) {}
 
 template <typename Strategy>
 VisibleSelectionTemplate<Strategy> VisibleSelectionTemplate<Strategy>::Create(
@@ -124,8 +121,7 @@
     : base_(other.base_),
       extent_(other.extent_),
       affinity_(other.affinity_),
-      base_is_first_(other.base_is_first_),
-      is_directional_(other.is_directional_) {}
+      base_is_first_(other.base_is_first_) {}
 
 template <typename Strategy>
 VisibleSelectionTemplate<Strategy>& VisibleSelectionTemplate<Strategy>::
@@ -134,7 +130,6 @@
   extent_ = other.extent_;
   affinity_ = other.affinity_;
   base_is_first_ = other.base_is_first_;
-  is_directional_ = other.is_directional_;
   return *this;
 }
 
@@ -143,13 +138,11 @@
     const {
   if (base_.IsNull()) {
     return typename SelectionTemplate<Strategy>::Builder()
-        .SetIsDirectional(is_directional_)
         .Build();
   }
   return typename SelectionTemplate<Strategy>::Builder()
       .SetBaseAndExtent(base_, extent_)
       .SetAffinity(affinity_)
-      .SetIsDirectional(is_directional_)
       .Build();
 }
 
@@ -291,7 +284,6 @@
         .Collapse(PositionWithAffinityTemplate<Strategy>(
             editing_adjusted_range.StartPosition(),
             passed_selection.Affinity()))
-        .SetIsDirectional(passed_selection.IsDirectional())
         .Build();
   }
 
@@ -310,12 +302,10 @@
       MostBackwardCaretPosition(editing_adjusted_range.EndPosition()));
   if (canonicalized_selection.IsBaseFirst()) {
     return typename SelectionTemplate<Strategy>::Builder()
-        .SetIsDirectional(passed_selection.IsDirectional())
         .SetAsForwardSelection(range)
         .Build();
   }
   return typename SelectionTemplate<Strategy>::Builder()
-      .SetIsDirectional(passed_selection.IsDirectional())
       .SetAsBackwardSelection(range)
       .Build();
 }
@@ -373,8 +363,7 @@
 static bool EqualSelectionsAlgorithm(
     const VisibleSelectionTemplate<Strategy>& selection1,
     const VisibleSelectionTemplate<Strategy>& selection2) {
-  if (selection1.Affinity() != selection2.Affinity() ||
-      selection1.IsDirectional() != selection2.IsDirectional())
+  if (selection1.Affinity() != selection2.Affinity())
     return false;
 
   if (selection1.IsNone())
@@ -463,7 +452,6 @@
            << " extent:" << selection.Extent()
            << " start: " << selection.Start() << " end: " << selection.End()
            << ' ' << selection.Affinity() << ' '
-           << (selection.IsDirectional() ? "Directional" : "NonDirectional")
            << ')';
 }
 
diff --git a/third_party/WebKit/Source/core/editing/VisibleSelection.h b/third_party/WebKit/Source/core/editing/VisibleSelection.h
index 853cdd5e..75bef21e 100644
--- a/third_party/WebKit/Source/core/editing/VisibleSelection.h
+++ b/third_party/WebKit/Source/core/editing/VisibleSelection.h
@@ -84,7 +84,6 @@
 
   // True if base() <= extent().
   bool IsBaseFirst() const { return base_is_first_; }
-  bool IsDirectional() const { return is_directional_; }
 
   // TODO(yosin) Most callers probably don't want these functions, but
   // are using them for historical reasons. |toNormalizedEphemeralRange()|
@@ -131,9 +130,6 @@
 
   // these are cached, can be recalculated by validate()
   bool base_is_first_ : 1;        // True if base is before the extent
-  // Non-directional ignores m_baseIsFirst and selection always extends on shift
-  // + arrow key.
-  bool is_directional_ : 1;
 };
 
 extern template class CORE_EXTERN_TEMPLATE_EXPORT
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnits.h b/third_party/WebKit/Source/core/editing/VisibleUnits.h
index c1eb1c6..a011caa 100644
--- a/third_party/WebKit/Source/core/editing/VisibleUnits.h
+++ b/third_party/WebKit/Source/core/editing/VisibleUnits.h
@@ -149,7 +149,7 @@
 CORE_EXPORT VisiblePositionInFlatTree
 EndOfWord(const VisiblePositionInFlatTree&, EWordSide = kNextWordIfOnBoundary);
 VisiblePosition PreviousWordPosition(const VisiblePosition&);
-VisiblePosition NextWordPosition(const VisiblePosition&);
+CORE_EXPORT VisiblePosition NextWordPosition(const VisiblePosition&);
 
 // sentences
 CORE_EXPORT VisiblePosition StartOfSentence(const VisiblePosition&);
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnitsWordTest.cpp b/third_party/WebKit/Source/core/editing/VisibleUnitsWordTest.cpp
index 750924a..ad5f6e7b 100644
--- a/third_party/WebKit/Source/core/editing/VisibleUnitsWordTest.cpp
+++ b/third_party/WebKit/Source/core/editing/VisibleUnitsWordTest.cpp
@@ -33,6 +33,15 @@
                           .DeepEquivalent())
             .Build());
   }
+
+  std::string DoNextWord(const std::string& selection_text) {
+    const Position position = SetSelectionTextToBody(selection_text).Base();
+    return GetSelectionTextFromBody(
+        SelectionInDOMTree::Builder()
+            .Collapse(NextWordPosition(CreateVisiblePosition(position))
+                          .DeepEquivalent())
+            .Build());
+  }
 };
 
 TEST_F(VisibleUnitsWordTest, StartOfWordBasic) {
@@ -211,4 +220,54 @@
   EXPECT_EQ("abc<s>foo bar</s>baz|", DoEndOfWord("abc<s>foo bar</s>b|az"));
 }
 
+TEST_F(VisibleUnitsWordTest, NextWordBasic) {
+  EXPECT_EQ("<p> (1|) abc def</p>", DoNextWord("<p>| (1) abc def</p>"));
+  EXPECT_EQ("<p> (1|) abc def</p>", DoNextWord("<p> |(1) abc def</p>"));
+  EXPECT_EQ("<p> (1|) abc def</p>", DoNextWord("<p> (|1) abc def</p>"));
+  EXPECT_EQ("<p> (1) abc| def</p>", DoNextWord("<p> (1|) abc def</p>"));
+  EXPECT_EQ("<p> (1) abc| def</p>", DoNextWord("<p> (1)| abc def</p>"));
+  EXPECT_EQ("<p> (1) abc| def</p>", DoNextWord("<p> (1) |abc def</p>"));
+  EXPECT_EQ("<p> (1) abc| def</p>", DoNextWord("<p> (1) a|bc def</p>"));
+  EXPECT_EQ("<p> (1) abc| def</p>", DoNextWord("<p> (1) ab|c def</p>"));
+  EXPECT_EQ("<p> (1) abc def|</p>", DoNextWord("<p> (1) abc| def</p>"));
+  EXPECT_EQ("<p> (1) abc def|</p>", DoNextWord("<p> (1) abc |def</p>"));
+  EXPECT_EQ("<p> (1) abc def|</p>", DoNextWord("<p> (1) abc d|ef</p>"));
+  EXPECT_EQ("<p> (1) abc def|</p>", DoNextWord("<p> (1) abc de|f</p>"));
+  EXPECT_EQ("<p> (1) abc def|</p>", DoNextWord("<p> (1) abc def|</p>"));
+  EXPECT_EQ("<p> (1) abc def|</p>", DoNextWord("<p> (1) abc def</p>|"));
+}
+
+TEST_F(VisibleUnitsWordTest, NextWordCrossingBlock) {
+  EXPECT_EQ("<p>abc|</p><p>def</p>", DoNextWord("<p>|abc</p><p>def</p>"));
+  EXPECT_EQ("<p>abc</p><p>def|</p>", DoNextWord("<p>abc|</p><p>def</p>"));
+}
+
+TEST_F(VisibleUnitsWordTest, NextWordMixedEditability) {
+  EXPECT_EQ(
+      "<p contenteditable>"
+      "abc<b contenteditable=\"false\">def ghi</b>|jkl mno</p>",
+      DoNextWord("<p contenteditable>"
+                 "|abc<b contenteditable=false>def ghi</b>jkl mno</p>"));
+  EXPECT_EQ(
+      "<p contenteditable>"
+      "abc<b contenteditable=\"false\">def| ghi</b>jkl mno</p>",
+      DoNextWord("<p contenteditable>"
+                 "abc<b contenteditable=false>|def ghi</b>jkl mno</p>"));
+  EXPECT_EQ(
+      "<p contenteditable>"
+      "abc<b contenteditable=\"false\">def ghi|</b>jkl mno</p>",
+      DoNextWord("<p contenteditable>"
+                 "abc<b contenteditable=false>def |ghi</b>jkl mno</p>"));
+  EXPECT_EQ(
+      "<p contenteditable>"
+      "abc<b contenteditable=\"false\">def ghi|</b>jkl mno</p>",
+      DoNextWord("<p contenteditable>"
+                 "abc<b contenteditable=false>def ghi|</b>jkl mno</p>"));
+}
+
+TEST_F(VisibleUnitsWordTest, NextWordSkipTab) {
+  InsertStyleElement("s { white-space: pre }");
+  EXPECT_EQ("<p><s>\t</s>foo|</p>", DoNextWord("<p><s>\t|</s>foo</p>"));
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/editing/commands/ApplyBlockElementCommand.cpp b/third_party/WebKit/Source/core/editing/commands/ApplyBlockElementCommand.cpp
index 6ffd41f..5b83038 100644
--- a/third_party/WebKit/Source/core/editing/commands/ApplyBlockElementCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/ApplyBlockElementCommand.cpp
@@ -88,7 +88,6 @@
     builder.Collapse(visible_start.ToPositionWithAffinity());
     if (new_end.IsNotNull())
       builder.Extend(new_end);
-    builder.SetIsDirectional(EndingSelection().IsDirectional());
     const SelectionInDOMTree& new_selection = builder.Build();
     if (new_selection.IsNone())
       return;
@@ -124,7 +123,6 @@
           SelectionInDOMTree::Builder()
               .Collapse(start.ToPositionWithAffinity())
               .Extend(end.DeepEquivalent())
-              .SetIsDirectional(EndingSelection().IsDirectional())
               .Build()));
     }
   }
@@ -156,7 +154,6 @@
     SetEndingSelection(SelectionForUndoStep::From(
         SelectionInDOMTree::Builder()
             .Collapse(Position::BeforeNode(*placeholder))
-            .SetIsDirectional(EndingSelection().IsDirectional())
             .Build()));
     return;
   }
diff --git a/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp b/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp
index 0e61c580..fcf774c 100644
--- a/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp
@@ -186,7 +186,6 @@
       StartingSelection().IsBaseFirst() || !SelectionIsDirectional();
   const EphemeralRange range(new_start, new_end);
   SelectionInDOMTree::Builder builder;
-  builder.SetIsDirectional(EndingSelection().IsDirectional());
   if (was_base_first)
     builder.SetAsForwardSelection(range);
   else
diff --git a/third_party/WebKit/Source/core/editing/commands/BreakBlockquoteCommand.cpp b/third_party/WebKit/Source/core/editing/commands/BreakBlockquoteCommand.cpp
index ebd43dd..9f3d3e1 100644
--- a/third_party/WebKit/Source/core/editing/commands/BreakBlockquoteCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/BreakBlockquoteCommand.cpp
@@ -138,7 +138,6 @@
     SetEndingSelection(SelectionForUndoStep::From(
         SelectionInDOMTree::Builder()
             .Collapse(Position::BeforeNode(*break_element))
-            .SetIsDirectional(EndingSelection().IsDirectional())
             .Build()));
     RebalanceWhitespace();
     return;
@@ -157,7 +156,6 @@
     SetEndingSelection(SelectionForUndoStep::From(
         SelectionInDOMTree::Builder()
             .Collapse(Position::BeforeNode(*break_element))
-            .SetIsDirectional(EndingSelection().IsDirectional())
             .Build()));
     RebalanceWhitespace();
     return;
@@ -203,7 +201,6 @@
     SetEndingSelection(SelectionForUndoStep::From(
         SelectionInDOMTree::Builder()
             .Collapse(FirstPositionInOrBeforeNode(*start_node))
-            .SetIsDirectional(EndingSelection().IsDirectional())
             .Build()));
     return;
   }
@@ -289,7 +286,6 @@
   SetEndingSelection(SelectionForUndoStep::From(
       SelectionInDOMTree::Builder()
           .Collapse(Position::BeforeNode(*break_element))
-          .SetIsDirectional(EndingSelection().IsDirectional())
           .Build()));
   RebalanceWhitespace();
 }
diff --git a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp
index b1cd2d4..636e030f 100644
--- a/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/CompositeEditCommand.cpp
@@ -1416,7 +1416,6 @@
   int start_index = -1;
   int end_index = -1;
   int destination_index = -1;
-  bool original_is_directional = EndingSelection().IsDirectional();
   if (should_preserve_selection == kPreserveSelection &&
       !EndingSelection().IsNone()) {
     VisiblePosition visible_start = EndingVisibleSelection().VisibleStart();
@@ -1555,7 +1554,6 @@
   const VisibleSelection& destination_selection =
       CreateVisibleSelection(SelectionInDOMTree::Builder()
                                  .Collapse(destination.ToPositionWithAffinity())
-                                 .SetIsDirectional(original_is_directional)
                                  .Build());
   if (EndingSelection().IsNone()) {
     // We abort executing command since |destination| becomes invisible.
@@ -1616,7 +1614,6 @@
       CreateVisibleSelection(SelectionInDOMTree::Builder()
                                  .Collapse(start_range.StartPosition())
                                  .Extend(end_range.StartPosition())
-                                 .SetIsDirectional(original_is_directional)
                                  .Build());
   SetEndingSelection(
       SelectionForUndoStep::From(visible_selection.AsSelection()));
@@ -1724,7 +1721,6 @@
   SetEndingSelection(SelectionForUndoStep::From(
       SelectionInDOMTree::Builder()
           .Collapse(Position::FirstPositionInNode(*new_block))
-          .SetIsDirectional(EndingSelection().IsDirectional())
           .Build()));
 
   style->PrepareToApplyAt(EndingSelection().Start());
@@ -1787,7 +1783,6 @@
   SetEndingSelection(SelectionForUndoStep::From(
       SelectionInDOMTree::Builder()
           .Collapse(at_br.ToPositionWithAffinity())
-          .SetIsDirectional(EndingSelection().IsDirectional())
           .Build()));
 
   // If this is an empty paragraph there must be a line break here.
diff --git a/third_party/WebKit/Source/core/editing/commands/CreateLinkCommand.cpp b/third_party/WebKit/Source/core/editing/commands/CreateLinkCommand.cpp
index 769374e..5ed5215 100644
--- a/third_party/WebKit/Source/core/editing/commands/CreateLinkCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/CreateLinkCommand.cpp
@@ -61,7 +61,6 @@
         SelectionInDOMTree::Builder()
             .Collapse(Position::InParentBeforeNode(*anchor_element))
             .Extend(Position::InParentAfterNode(*anchor_element))
-            .SetIsDirectional(EndingSelection().IsDirectional())
             .Build()));
   }
 }
diff --git a/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp b/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp
index 856629c..c4fb1a5 100644
--- a/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/DeleteSelectionCommand.cpp
@@ -218,8 +218,7 @@
   SelectionInDOMTree::Builder builder;
   builder.SetAffinity(new_base.Affinity())
       .SetBaseAndExtentDeprecated(new_base.DeepEquivalent(),
-                                  new_extent.DeepEquivalent())
-      .SetIsDirectional(StartingSelection().IsDirectional());
+                                  new_extent.DeepEquivalent());
   const VisibleSelection& visible_selection =
       CreateVisibleSelection(builder.Build());
   SetStartingSelection(
@@ -1163,7 +1162,6 @@
     GetDocument().UpdateStyleAndLayoutIgnorePendingStylesheets();
     SelectionInDOMTree::Builder builder;
     builder.SetAffinity(affinity);
-    builder.SetIsDirectional(EndingSelection().IsDirectional());
     if (ending_position_.IsNotNull())
       builder.Collapse(ending_position_);
     const VisibleSelection& visible_selection =
@@ -1227,7 +1225,6 @@
 
   SelectionInDOMTree::Builder builder;
   builder.SetAffinity(affinity);
-  builder.SetIsDirectional(EndingSelection().IsDirectional());
   if (ending_position_.IsNotNull())
     builder.Collapse(ending_position_);
   const VisibleSelection& visible_selection =
diff --git a/third_party/WebKit/Source/core/editing/commands/InsertLineBreakCommand.cpp b/third_party/WebKit/Source/core/editing/commands/InsertLineBreakCommand.cpp
index 97bf354..17ec4c8 100644
--- a/third_party/WebKit/Source/core/editing/commands/InsertLineBreakCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/InsertLineBreakCommand.cpp
@@ -132,7 +132,6 @@
     SetEndingSelection(SelectionForUndoStep::From(
         SelectionInDOMTree::Builder()
             .Collapse(Position::BeforeNode(*node_to_insert))
-            .SetIsDirectional(EndingSelection().IsDirectional())
             .Build()));
   } else if (pos.ComputeEditingOffset() <= CaretMinOffset(pos.AnchorNode())) {
     InsertNodeAt(node_to_insert, pos, editing_state);
@@ -151,7 +150,6 @@
     SetEndingSelection(SelectionForUndoStep::From(
         SelectionInDOMTree::Builder()
             .Collapse(Position::InParentAfterNode(*node_to_insert))
-            .SetIsDirectional(EndingSelection().IsDirectional())
             .Build()));
     // If we're inserting after all of the rendered text in a text node, or into
     // a non-text node, a simple insertion is sufficient.
@@ -164,7 +162,6 @@
     SetEndingSelection(SelectionForUndoStep::From(
         SelectionInDOMTree::Builder()
             .Collapse(Position::InParentAfterNode(*node_to_insert))
-            .SetIsDirectional(EndingSelection().IsDirectional())
             .Build()));
   } else if (pos.AnchorNode()->IsTextNode()) {
     // Split a text node
@@ -199,7 +196,6 @@
     SetEndingSelection(SelectionForUndoStep::From(
         SelectionInDOMTree::Builder()
             .Collapse(ending_position)
-            .SetIsDirectional(EndingSelection().IsDirectional())
             .Build()));
   }
 
diff --git a/third_party/WebKit/Source/core/editing/commands/InsertListCommand.cpp b/third_party/WebKit/Source/core/editing/commands/InsertListCommand.cpp
index 2592a93..2f4bbdf 100644
--- a/third_party/WebKit/Source/core/editing/commands/InsertListCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/InsertListCommand.cpp
@@ -169,7 +169,6 @@
     const VisiblePosition& new_end =
         PreviousPositionOf(visible_end, kCannotCrossEditingBoundary);
     SelectionInDOMTree::Builder builder;
-    builder.SetIsDirectional(EndingSelection().IsDirectional());
     builder.Collapse(visible_start.ToPositionWithAffinity());
     if (new_end.IsNotNull())
       builder.Extend(new_end.DeepEquivalent());
@@ -308,7 +307,6 @@
             .SetBaseAndExtentDeprecated(
                 visible_start_of_selection.DeepEquivalent(),
                 visible_end_of_selection.DeepEquivalent())
-            .SetIsDirectional(EndingSelection().IsDirectional())
             .Build()));
     return;
   }
diff --git a/third_party/WebKit/Source/core/editing/commands/InsertParagraphSeparatorCommand.cpp b/third_party/WebKit/Source/core/editing/commands/InsertParagraphSeparatorCommand.cpp
index e2c14650..41d7e46 100644
--- a/third_party/WebKit/Source/core/editing/commands/InsertParagraphSeparatorCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/InsertParagraphSeparatorCommand.cpp
@@ -350,7 +350,6 @@
     SetEndingSelection(SelectionForUndoStep::From(
         SelectionInDOMTree::Builder()
             .Collapse(Position::FirstPositionInNode(*parent))
-            .SetIsDirectional(EndingSelection().IsDirectional())
             .Build()));
     return;
   }
@@ -424,7 +423,6 @@
     SetEndingSelection(SelectionForUndoStep::From(
         SelectionInDOMTree::Builder()
             .Collapse(insertion_position)
-            .SetIsDirectional(EndingSelection().IsDirectional())
             .Build()));
     return;
   }
@@ -452,7 +450,6 @@
       SetEndingSelection(SelectionForUndoStep::From(
           SelectionInDOMTree::Builder()
               .Collapse(insertion_position)
-              .SetIsDirectional(EndingSelection().IsDirectional())
               .Build()));
       return;
     }
@@ -607,7 +604,6 @@
   SetEndingSelection(SelectionForUndoStep::From(
       SelectionInDOMTree::Builder()
           .Collapse(Position::FirstPositionInNode(*block_to_insert))
-          .SetIsDirectional(EndingSelection().IsDirectional())
           .Build()));
   ApplyStyleAfterInsertion(start_block, editing_state);
 }
diff --git a/third_party/WebKit/Source/core/editing/commands/InsertTextCommand.cpp b/third_party/WebKit/Source/core/editing/commands/InsertTextCommand.cpp
index 3128b45..a9e27d3 100644
--- a/third_party/WebKit/Source/core/editing/commands/InsertTextCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/InsertTextCommand.cpp
@@ -85,7 +85,6 @@
       SelectionInDOMTree::Builder()
           .Collapse(start_position)
           .Extend(end_position)
-          .SetIsDirectional(EndingSelection().IsDirectional())
           .Build()));
 }
 
@@ -113,7 +112,6 @@
   SetEndingSelection(SelectionForUndoStep::From(
       SelectionInDOMTree::Builder()
           .Collapse(EndingVisibleSelection().End())
-          .SetIsDirectional(EndingSelection().IsDirectional())
           .Build()));
   return true;
 }
@@ -142,7 +140,6 @@
   SetEndingSelection(SelectionForUndoStep::From(
       SelectionInDOMTree::Builder()
           .Collapse(EndingVisibleSelection().End())
-          .SetIsDirectional(EndingSelection().IsDirectional())
           .Build()));
   return true;
 }
@@ -298,7 +295,6 @@
   SelectionInDOMTree::Builder builder;
   const VisibleSelection& selection = EndingVisibleSelection();
   builder.SetAffinity(selection.Affinity());
-  builder.SetIsDirectional(EndingSelection().IsDirectional());
   if (selection.End().IsNotNull())
     builder.Collapse(selection.End());
   SetEndingSelection(SelectionForUndoStep::From(builder.Build()));
diff --git a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp
index e7965865..65cc191 100644
--- a/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/ReplaceSelectionCommand.cpp
@@ -1808,7 +1808,6 @@
     SetEndingSelection(SelectionForUndoStep::From(
         SelectionInDOMTree::Builder()
             .SetBaseAndExtentDeprecated(start, end)
-            .SetIsDirectional(EndingSelection().IsDirectional())
             .Build()));
     return;
   }
@@ -1817,7 +1816,6 @@
     SetEndingSelection(SelectionForUndoStep::From(
         SelectionInDOMTree::Builder()
             .Collapse(end)
-            .SetIsDirectional(EndingSelection().IsDirectional())
             .Build()));
     return;
   }
diff --git a/third_party/WebKit/Source/core/editing/commands/SelectionForUndoStep.cpp b/third_party/WebKit/Source/core/editing/commands/SelectionForUndoStep.cpp
index eb251f8..e598465 100644
--- a/third_party/WebKit/Source/core/editing/commands/SelectionForUndoStep.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/SelectionForUndoStep.cpp
@@ -17,7 +17,6 @@
   result.base_ = selection.Base();
   result.extent_ = selection.Extent();
   result.affinity_ = selection.Affinity();
-  result.is_directional_ = selection.IsDirectional();
   result.is_base_first_ = selection.IsBaseFirst();
   return result;
 }
@@ -36,9 +35,7 @@
   if (other.IsNone())
     return false;
   return base_ == other.base_ && extent_ == other.extent_ &&
-         affinity_ == other.affinity_ &&
-         is_base_first_ == other.is_base_first_ &&
-         is_directional_ == other.is_directional_;
+         affinity_ == other.affinity_ && is_base_first_ == other.is_base_first_;
 }
 
 bool SelectionForUndoStep::operator!=(const SelectionForUndoStep& other) const {
@@ -47,14 +44,11 @@
 
 SelectionInDOMTree SelectionForUndoStep::AsSelection() const {
   if (IsNone()) {
-    return SelectionInDOMTree::Builder()
-        .SetIsDirectional(is_directional_)
-        .Build();
+    return SelectionInDOMTree();
   }
   return SelectionInDOMTree::Builder()
       .SetBaseAndExtent(base_, extent_)
       .SetAffinity(affinity_)
-      .SetIsDirectional(is_directional_)
       .Build();
 }
 
diff --git a/third_party/WebKit/Source/core/editing/commands/SelectionForUndoStep.h b/third_party/WebKit/Source/core/editing/commands/SelectionForUndoStep.h
index 263bd741..ef0ec80 100644
--- a/third_party/WebKit/Source/core/editing/commands/SelectionForUndoStep.h
+++ b/third_party/WebKit/Source/core/editing/commands/SelectionForUndoStep.h
@@ -37,7 +37,6 @@
   Position Base() const { return base_; }
   Position Extent() const { return extent_; }
   bool IsBaseFirst() const { return is_base_first_; }
-  bool IsDirectional() const { return is_directional_; }
 
   SelectionInDOMTree AsSelection() const;
 
@@ -65,7 +64,6 @@
   // Note: We should compute |is_base_first_| as construction otherwise we
   // fail "backward and forward delete" case in "undo-delete-boundary.html".
   bool is_base_first_ = true;
-  bool is_directional_ = false;
 };
 
 // Builds |SelectionForUndoStep| object with disconnected position. You should
diff --git a/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp b/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp
index eee3e2c..9f90da1 100644
--- a/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp
+++ b/third_party/WebKit/Source/core/editing/commands/TypingCommand.cpp
@@ -118,7 +118,6 @@
 
 SelectionInDOMTree CreateSelection(const size_t start,
                                    const size_t end,
-                                   const bool is_directional,
                                    Element* element) {
   const EphemeralRange& start_range =
       PlainTextRange(0, static_cast<int>(start)).CreateRange(*element);
@@ -133,7 +132,6 @@
   const SelectionInDOMTree& selection =
       SelectionInDOMTree::Builder()
           .SetBaseAndExtent(start_position, end_position)
-          .SetIsDirectional(is_directional)
           .Build();
   return selection;
 }
@@ -326,8 +324,8 @@
   }
 
   const size_t new_end = selection_start + text_length;
-  const SelectionInDOMTree& selection = CreateSelection(
-      new_end, new_end, EndingSelection().IsDirectional(), element);
+  const SelectionInDOMTree& selection =
+      CreateSelection(new_end, new_end, element);
   SetEndingSelection(SelectionForUndoStep::From(selection));
 }
 
@@ -744,7 +742,6 @@
   const SelectionInDOMTree& selection =
       SelectionInDOMTree::Builder()
           .Collapse(Position::FirstPositionInNode(*root))
-          .SetIsDirectional(EndingSelection().IsDirectional())
           .Build();
   SetEndingSelection(SelectionForUndoStep::From(selection));
 
@@ -870,7 +867,6 @@
         SelectionInDOMTree::Builder()
             .Collapse(Position::BeforeNode(*table))
             .Extend(EndingSelection().Start())
-            .SetIsDirectional(EndingSelection().IsDirectional())
             .Build();
     SetEndingSelection(SelectionForUndoStep::From(selection));
     TypingAddedToOpenCommand(kDeleteKey);
@@ -1010,7 +1006,6 @@
             .SetBaseAndExtentDeprecated(
                 EndingSelection().End(),
                 Position::AfterNode(*downstream_end.ComputeContainerNode()))
-            .SetIsDirectional(EndingSelection().IsDirectional())
             .Build();
     SetEndingSelection(SelectionForUndoStep::From(selection));
     TypingAddedToOpenCommand(kForwardDeleteKey);
diff --git a/third_party/WebKit/Source/core/html/HTMLAttributeNames.json5 b/third_party/WebKit/Source/core/html/HTMLAttributeNames.json5
index fe5742e..1955e2bf 100644
--- a/third_party/WebKit/Source/core/html/HTMLAttributeNames.json5
+++ b/third_party/WebKit/Source/core/html/HTMLAttributeNames.json5
@@ -119,6 +119,7 @@
     "direction",
     "dirname",
     "disabled",
+    "disablepictureinpicture",
     "disableremoteplayback",
     "download",
     "draggable",
diff --git a/third_party/WebKit/Source/core/html/HTMLSlotElement.cpp b/third_party/WebKit/Source/core/html/HTMLSlotElement.cpp
index e4da5cb..614a172 100644
--- a/third_party/WebKit/Source/core/html/HTMLSlotElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLSlotElement.cpp
@@ -112,15 +112,6 @@
 
 namespace {
 
-const HTMLSlotElement* ToHTMLSlotElementIfSupportsAssignmentOrNull(
-    const Node& node) {
-  if (auto* slot = ToHTMLSlotElementOrNull(node)) {
-    if (slot->SupportsAssignment())
-      return slot;
-  }
-  return nullptr;
-}
-
 HeapVector<Member<Node>> CollectFlattenedAssignedNodes(
     const HTMLSlotElement& slot) {
   DCHECK(RuntimeEnabledFeatures::IncrementalShadowDOMEnabled());
@@ -211,11 +202,12 @@
 void HTMLSlotElement::ResolveDistributedNodes() {
   for (auto& node : assigned_nodes_) {
     DCHECK(node->IsSlotable());
-    if (IsHTMLSlotElement(*node) &&
-        ToHTMLSlotElement(*node).SupportsAssignment())
-      AppendDistributedNodesFrom(ToHTMLSlotElement(*node));
-    else
+    if (HTMLSlotElement* slot =
+            ToHTMLSlotElementIfSupportsAssignmentOrNull(*node)) {
+      AppendDistributedNodesFrom(*slot);
+    } else {
       AppendDistributedNode(*node);
+    }
 
     if (IsChildOfV1ShadowHost())
       ParentElementShadow()->SetNeedsDistributionRecalc();
diff --git a/third_party/WebKit/Source/core/html/HTMLSlotElement.h b/third_party/WebKit/Source/core/html/HTMLSlotElement.h
index 2368fb9..42d66957e 100644
--- a/third_party/WebKit/Source/core/html/HTMLSlotElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLSlotElement.h
@@ -201,6 +201,36 @@
   friend class HTMLSlotElementTest;
 };
 
+inline const HTMLSlotElement* ToHTMLSlotElementIfSupportsAssignmentOrNull(
+    const Node& node) {
+  if (auto* slot = ToHTMLSlotElementOrNull(node)) {
+    if (slot->SupportsAssignment())
+      return slot;
+  }
+  return nullptr;
+}
+
+inline HTMLSlotElement* ToHTMLSlotElementIfSupportsAssignmentOrNull(
+    Node& node) {
+  return const_cast<HTMLSlotElement*>(
+      ToHTMLSlotElementIfSupportsAssignmentOrNull(
+          static_cast<const Node&>(node)));
+}
+
+inline const HTMLSlotElement* ToHTMLSlotElementIfSupportsAssignmentOrNull(
+    const Node* node) {
+  if (!node)
+    return nullptr;
+  return ToHTMLSlotElementIfSupportsAssignmentOrNull(*node);
+}
+
+inline HTMLSlotElement* ToHTMLSlotElementIfSupportsAssignmentOrNull(
+    Node* node) {
+  return const_cast<HTMLSlotElement*>(
+      ToHTMLSlotElementIfSupportsAssignmentOrNull(
+          static_cast<const Node*>(node)));
+}
+
 }  // namespace blink
 
 #endif  // HTMLSlotElement_h
diff --git a/third_party/WebKit/Source/core/html/HTMLSourceElement.h b/third_party/WebKit/Source/core/html/HTMLSourceElement.h
index 4cff705..0f46881 100644
--- a/third_party/WebKit/Source/core/html/HTMLSourceElement.h
+++ b/third_party/WebKit/Source/core/html/HTMLSourceElement.h
@@ -29,6 +29,7 @@
 #include "core/css/MediaQueryListListener.h"
 #include "core/html/HTMLElement.h"
 #include "platform/Timer.h"
+#include "platform/WebTaskRunner.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/html/forms/ImageInputType.cpp b/third_party/WebKit/Source/core/html/forms/ImageInputType.cpp
index 4df0a95..fddbd7ff 100644
--- a/third_party/WebKit/Source/core/html/forms/ImageInputType.cpp
+++ b/third_party/WebKit/Source/core/html/forms/ImageInputType.cpp
@@ -73,12 +73,6 @@
   DEFINE_STATIC_LOCAL(String, dot_y_string, (".y"));
   form_data.append(name + dot_x_string, click_location_.X());
   form_data.append(name + dot_y_string, click_location_.Y());
-
-  if (!GetElement().value().IsEmpty()) {
-    UseCounter::Count(GetElement().GetDocument(),
-                      WebFeature::kImageInputTypeFormDataWithNonEmptyValue);
-    form_data.append(name, GetElement().value());
-  }
 }
 
 String ImageInputType::ResultForDialogSubmit() const {
diff --git a/third_party/WebKit/Source/core/html/forms/TextControlElement.cpp b/third_party/WebKit/Source/core/html/forms/TextControlElement.cpp
index 3423539..5eccc3d4 100644
--- a/third_party/WebKit/Source/core/html/forms/TextControlElement.cpp
+++ b/third_party/WebKit/Source/core/html/forms/TextControlElement.cpp
@@ -453,7 +453,6 @@
                         : start_position)
           .Extend(direction == kSelectionHasBackwardDirection ? start_position
                                                               : end_position)
-          .SetIsDirectional(direction != kSelectionHasNoDirection)
           .Build(),
       SetSelectionOptions::Builder()
           .SetShouldCloseTyping(true)
@@ -627,7 +626,6 @@
   if (!inner_text->HasChildren()) {
     return SelectionInDOMTree::Builder()
         .Collapse(Position(inner_text, 0))
-        .SetIsDirectional(selectionDirection() != "none")
         .Build();
   }
 
@@ -655,7 +653,6 @@
 
   return SelectionInDOMTree::Builder()
       .SetBaseAndExtent(Position(start_node, start), Position(end_node, end))
-      .SetIsDirectional(selectionDirection() != "none")
       .Build();
 }
 
diff --git a/third_party/WebKit/Source/core/html/track/vtt/VTTParser.cpp b/third_party/WebKit/Source/core/html/track/vtt/VTTParser.cpp
index 9a2cea3..7a32ed24 100644
--- a/third_party/WebKit/Source/core/html/track/vtt/VTTParser.cpp
+++ b/third_party/WebKit/Source/core/html/track/vtt/VTTParser.cpp
@@ -450,7 +450,7 @@
 
   // Steps 5 - 7 - Collect a sequence of characters that are 0-9.
   // If not 2 characters or value is greater than 59, interpret as hours.
-  int value1;
+  unsigned value1;
   unsigned value1_digits = input.ScanDigits(value1);
   if (!value1_digits)
     return false;
@@ -459,12 +459,12 @@
 
   // Steps 8 - 11 - Collect the next sequence of 0-9 after ':' (must be 2
   // chars).
-  int value2;
+  unsigned value2;
   if (!input.Scan(':') || input.ScanDigits(value2) != 2)
     return false;
 
   // Step 12 - Detect whether this timestamp includes hours.
-  int value3;
+  unsigned value3;
   if (mode == kHours || input.Match(':')) {
     if (!input.Scan(':') || input.ScanDigits(value3) != 2)
       return false;
@@ -475,7 +475,7 @@
   }
 
   // Steps 13 - 17 - Collect next sequence of 0-9 after '.' (must be 3 chars).
-  int value4;
+  unsigned value4;
   if (!input.Scan('.') || input.ScanDigits(value4) != 3)
     return false;
   if (value2 > 59 || value3 > 59)
diff --git a/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.cpp b/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.cpp
index 5c6063f..b23b16e 100644
--- a/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.cpp
+++ b/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.cpp
@@ -111,13 +111,7 @@
   width_ = value;
 }
 
-void VTTRegion::setLines(int value, ExceptionState& exception_state) {
-  if (value < 0) {
-    exception_state.ThrowDOMException(
-        kIndexSizeError,
-        "The height provided (" + String::Number(value) + ") is negative.");
-    return;
-  }
+void VTTRegion::setLines(unsigned value) {
   lines_ = value;
 }
 
@@ -230,11 +224,11 @@
       break;
     }
     case kLines: {
-      int number;
+      unsigned number;
       if (input.ScanDigits(number) && ParsedEntireRun(input, value_run))
         lines_ = number;
       else
-        DVLOG(VTT_LOG_LEVEL) << "parseSettingValue, invalid Height";
+        DVLOG(VTT_LOG_LEVEL) << "parseSettingValue, invalid Lines";
       break;
     }
     case kRegionAnchor: {
diff --git a/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.h b/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.h
index 064a162..6a9c8a9 100644
--- a/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.h
+++ b/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.h
@@ -59,8 +59,8 @@
   double width() const { return width_; }
   void setWidth(double, ExceptionState&);
 
-  int lines() const { return lines_; }
-  void setLines(int, ExceptionState&);
+  unsigned lines() const { return lines_; }
+  void setLines(unsigned);
 
   double regionAnchorX() const { return region_anchor_.X(); }
   void setRegionAnchorX(double, ExceptionState&);
diff --git a/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.idl b/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.idl
index e57a8ef..e764131 100644
--- a/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.idl
+++ b/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.idl
@@ -33,7 +33,7 @@
 ] interface VTTRegion {
     attribute DOMString id;
     [RaisesException=Setter] attribute double width;
-    [RaisesException=Setter] attribute long lines;
+    attribute unsigned long lines;
     [RaisesException=Setter] attribute double regionAnchorX;
     [RaisesException=Setter] attribute double regionAnchorY;
     [RaisesException=Setter] attribute double viewportAnchorX;
diff --git a/third_party/WebKit/Source/core/html/track/vtt/VTTScanner.cpp b/third_party/WebKit/Source/core/html/track/vtt/VTTScanner.cpp
index b50fa04..1e746c2 100644
--- a/third_party/WebKit/Source/core/html/track/vtt/VTTScanner.cpp
+++ b/third_party/WebKit/Source/core/html/track/vtt/VTTScanner.cpp
@@ -109,7 +109,7 @@
   return ExtractString(rest);
 }
 
-unsigned VTTScanner::ScanDigits(int& number) {
+unsigned VTTScanner::ScanDigits(unsigned& number) {
   Run run_of_digits = CollectWhile<IsASCIIDigit>();
   if (run_of_digits.IsEmpty()) {
     number = 0;
@@ -118,19 +118,19 @@
   bool valid_number;
   size_t num_digits = run_of_digits.length();
   if (is8_bit_) {
-    number = CharactersToInt(data_.characters8, num_digits,
-                             WTF::NumberParsingOptions::kNone, &valid_number);
+    number = CharactersToUInt(data_.characters8, num_digits,
+                              WTF::NumberParsingOptions::kNone, &valid_number);
   } else {
-    number = CharactersToInt(data_.characters16, num_digits,
-                             WTF::NumberParsingOptions::kNone, &valid_number);
+    number = CharactersToUInt(data_.characters16, num_digits,
+                              WTF::NumberParsingOptions::kNone, &valid_number);
   }
 
   // Since we know that scanDigits only scanned valid (ASCII) digits (and
-  // hence that's what got passed to charactersToInt()), the remaining
-  // failure mode for charactersToInt() is overflow, so if |validNumber| is
-  // not true, then set |number| to the maximum int value.
+  // hence that's what got passed to charactersToUInt()), the remaining
+  // failure mode for charactersToUInt() is overflow, so if |validNumber| is
+  // not true, then set |number| to the maximum unsigned value.
   if (!valid_number)
-    number = std::numeric_limits<int>::max();
+    number = std::numeric_limits<unsigned>::max();
   // Consume the digits.
   SeekTo(run_of_digits.end());
   return num_digits;
diff --git a/third_party/WebKit/Source/core/html/track/vtt/VTTScanner.h b/third_party/WebKit/Source/core/html/track/vtt/VTTScanner.h
index 44f3401..a8a61e5 100644
--- a/third_party/WebKit/Source/core/html/track/vtt/VTTScanner.h
+++ b/third_party/WebKit/Source/core/html/track/vtt/VTTScanner.h
@@ -131,9 +131,9 @@
 
   // Scan a set of ASCII digits from the input. Return the number of digits
   // scanned, and set |number| to the computed value. If the digits make up a
-  // number that does not fit the 'int' type, |number| is set to INT_MAX.
+  // number that does not fit the 'unsigned' type, |number| is set to UINT_MAX.
   // Note: Does not handle sign.
-  unsigned ScanDigits(int& number);
+  unsigned ScanDigits(unsigned& number);
 
   // Scan a floating point value on one of the forms: \d+\.? \d+\.\d+ \.\d+
   bool ScanDouble(double& number);
diff --git a/third_party/WebKit/Source/core/html/track/vtt/VTTScannerTest.cpp b/third_party/WebKit/Source/core/html/track/vtt/VTTScannerTest.cpp
index 34c5775..d48c3ee 100644
--- a/third_party/WebKit/Source/core/html/track/vtt/VTTScannerTest.cpp
+++ b/third_party/WebKit/Source/core/html/track/vtt/VTTScannerTest.cpp
@@ -240,37 +240,39 @@
 void ScanDigits1(const String& input) {
   VTTScanner scanner(input);
   EXPECT_TRUE(scanner.Scan("foo"));
-  int number;
+  unsigned number;
+
   EXPECT_EQ(scanner.ScanDigits(number), 0u);
-  EXPECT_EQ(number, 0);
+  EXPECT_EQ(number, 0u);
+
   EXPECT_TRUE(scanner.Scan(' '));
   EXPECT_EQ(scanner.ScanDigits(number), 3u);
   EXPECT_TRUE(scanner.Match(' '));
-  EXPECT_EQ(number, 123);
+  EXPECT_EQ(number, 123u);
 
   EXPECT_TRUE(scanner.Scan(' '));
   EXPECT_TRUE(scanner.Scan("bar"));
   EXPECT_TRUE(scanner.Scan(' '));
 
   EXPECT_EQ(scanner.ScanDigits(number), 5u);
-  EXPECT_EQ(number, 45678);
+  EXPECT_EQ(number, 45678u);
 
   EXPECT_TRUE(scanner.IsAtEnd());
 }
 
 void ScanDigits2(const String& input) {
   VTTScanner scanner(input);
-  int number;
+  unsigned number;
   EXPECT_EQ(scanner.ScanDigits(number), 0u);
-  EXPECT_EQ(number, 0);
+  EXPECT_EQ(number, 0u);
   EXPECT_TRUE(scanner.Scan('-'));
   EXPECT_EQ(scanner.ScanDigits(number), 3u);
-  EXPECT_EQ(number, 654);
+  EXPECT_EQ(number, 654u);
 
   EXPECT_TRUE(scanner.Scan(' '));
 
   EXPECT_EQ(scanner.ScanDigits(number), 19u);
-  EXPECT_EQ(number, std::numeric_limits<int>::max());
+  EXPECT_EQ(number, std::numeric_limits<unsigned>::max());
 
   EXPECT_TRUE(scanner.IsAtEnd());
 }
diff --git a/third_party/WebKit/Source/core/layout/ng/layout_ng_mixin.cc b/third_party/WebKit/Source/core/layout/ng/layout_ng_mixin.cc
index 1147e58..884a8f2 100644
--- a/third_party/WebKit/Source/core/layout/ng/layout_ng_mixin.cc
+++ b/third_party/WebKit/Source/core/layout/ng/layout_ng_mixin.cc
@@ -143,7 +143,7 @@
 template <typename Base>
 void LayoutNGMixin<Base>::SetPaintFragment(
     scoped_refptr<const NGPhysicalFragment> fragment) {
-  paint_fragment_ = std::make_unique<NGPaintFragment>(std::move(fragment));
+  paint_fragment_ = NGPaintFragment::Create(std::move(fragment));
 }
 
 static Vector<NGPaintFragment*> GetNGPaintFragmentsInternal(
diff --git a/third_party/WebKit/Source/core/paint/CSSMaskPainter.cpp b/third_party/WebKit/Source/core/paint/CSSMaskPainter.cpp
index 07baa00..db9f185b 100644
--- a/third_party/WebKit/Source/core/paint/CSSMaskPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/CSSMaskPainter.cpp
@@ -24,7 +24,7 @@
     LayoutSVGResourceMasker* masker = resources ? resources->Masker() : nullptr;
     if (!masker)
       return WTF::nullopt;
-    return EnclosingIntRect(object.ObjectBoundingBox());
+    return EnclosingIntRect(masker->ResourceBoundingBox(&object));
   }
 
   const ComputedStyle& style = object.StyleRef();
diff --git a/third_party/WebKit/Source/core/paint/CSSMaskPainterTest.cpp b/third_party/WebKit/Source/core/paint/CSSMaskPainterTest.cpp
index 4fc5177..8c85461 100644
--- a/third_party/WebKit/Source/core/paint/CSSMaskPainterTest.cpp
+++ b/third_party/WebKit/Source/core/paint/CSSMaskPainterTest.cpp
@@ -28,7 +28,7 @@
   Optional<IntRect> mask_bounding_box =
       CSSMaskPainter::MaskBoundingBox(masked, LayoutPoint());
   ASSERT_TRUE(mask_bounding_box.has_value());
-  EXPECT_EQ(IntRect(50, 50, 150, 150), *mask_bounding_box);
+  EXPECT_EQ(IntRect(75, 75, 100, 100), *mask_bounding_box);
 }
 
 TEST_F(CSSMaskPainterTest, MaskBoundingBoxCSSBlock) {
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
index 25719d0..ed1149e 100644
--- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
@@ -308,6 +308,7 @@
   ALWAYS_INLINE void UpdatePaintOffset();
   ALWAYS_INLINE void UpdateForPaintOffsetTranslation(Optional<IntPoint>&);
   ALWAYS_INLINE void UpdatePaintOffsetTranslation(const Optional<IntPoint>&);
+  ALWAYS_INLINE void SetNeedsPaintPropertyUpdateIfNeeded();
   ALWAYS_INLINE void UpdateForObjectLocationAndSize(
       Optional<IntPoint>& paint_offset_translation);
   ALWAYS_INLINE void UpdateTransform();
@@ -943,11 +944,6 @@
   return false;
 }
 
-static bool NeedsControlClipFragmentationAdjustment(const LayoutBox& box) {
-  return box.HasControlClip() && !box.Layer() &&
-         box.PaintingLayer()->EnclosingPaginationLayer();
-}
-
 static LayoutPoint VisualOffsetFromPaintOffsetRoot(
     const PaintPropertyTreeBuilderFragmentContext& context,
     const PaintLayer* child) {
@@ -1522,29 +1518,30 @@
   }
 }
 
-static void SetNeedsPaintPropertyUpdateIfNeeded(const LayoutObject& object) {
-  if (!object.IsBoxModelObject())
+void FragmentPaintPropertyTreeBuilder::SetNeedsPaintPropertyUpdateIfNeeded() {
+  if (!object_.IsBoxModelObject())
     return;
 
-  const LayoutBoxModelObject& box_model_object = ToLayoutBoxModelObject(object);
+  const auto& box_model_object = ToLayoutBoxModelObject(object_);
   if (box_model_object.Layer() &&
       box_model_object.Layer()->ShouldFragmentCompositedBounds()) {
     // Always force-update properties for fragmented content.
     // TODO(chrishtr): find ways to optimize this in the future.
     // It may suffice to compare previous and current visual overflow,
     // but we do not currenly cache that on the LayoutObject or PaintLayer.
-    object.GetMutableForPainting().SetNeedsPaintPropertyUpdate();
+    object_.GetMutableForPainting().SetNeedsPaintPropertyUpdate();
     return;
   }
 
-  if (!object.IsBox())
+  if (!object_.IsBox())
     return;
 
-  const LayoutBox& box = ToLayoutBox(object);
+  const LayoutBox& box = ToLayoutBox(object_);
 
   // Always force-update properties for fragmented content. Boxes with
   // control clip have a fragment-aware offset.
-  if (NeedsControlClipFragmentationAdjustment(box)) {
+  if (box.HasControlClip() && !box.Layer() &&
+      full_context_.painting_layer->EnclosingPaginationLayer()) {
     box.GetMutableForPainting().SetNeedsPaintPropertyUpdate();
     return;
   }
@@ -1605,7 +1602,7 @@
   if (paint_offset_translation)
     context_.current.paint_offset_root = &ToLayoutBoxModelObject(object_);
 
-  SetNeedsPaintPropertyUpdateIfNeeded(object_);
+  SetNeedsPaintPropertyUpdateIfNeeded();
 }
 
 void FragmentPaintPropertyTreeBuilder::UpdateForSelf() {
@@ -2010,10 +2007,9 @@
   UpdateRepeatingPaintOffsetAdjustment();
 }
 
-static inline bool ObjectTypeMightNeedPaintProperties(
-    const LayoutObject& object) {
-  return object.IsBoxModelObject() || object.IsSVG() ||
-         object.PaintingLayer()->EnclosingPaginationLayer();
+bool ObjectPaintPropertyTreeBuilder::ObjectTypeMightNeedPaintProperties() {
+  return object_.IsBoxModelObject() || object_.IsSVG() ||
+         context_.painting_layer->EnclosingPaginationLayer();
 }
 
 void ObjectPaintPropertyTreeBuilder::UpdatePaintingLayer() {
@@ -2035,7 +2031,7 @@
 void ObjectPaintPropertyTreeBuilder::UpdateForSelf() {
   UpdatePaintingLayer();
 
-  if (ObjectTypeMightNeedPaintProperties(object_))
+  if (ObjectTypeMightNeedPaintProperties())
     UpdateFragments();
   else
     object_.GetMutableForPainting().FirstFragment().ClearNextFragment();
@@ -2057,7 +2053,7 @@
 }
 
 void ObjectPaintPropertyTreeBuilder::UpdateForChildren() {
-  if (!ObjectTypeMightNeedPaintProperties(object_))
+  if (!ObjectTypeMightNeedPaintProperties())
     return;
 
   bool property_added_or_removed = false;
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.h b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.h
index 419e8f2..f258f2b 100644
--- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.h
+++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.h
@@ -182,6 +182,7 @@
   ALWAYS_INLINE void InitFragmentPaintProperties(FragmentData&,
                                                  bool needs_paint_properties);
   ALWAYS_INLINE void InitSingleFragmentFromParent(bool needs_paint_properties);
+  ALWAYS_INLINE bool ObjectTypeMightNeedPaintProperties();
   ALWAYS_INLINE void UpdateCompositedLayerPaginationOffset();
   ALWAYS_INLINE void UpdateFragments();
   ALWAYS_INLINE void UpdatePaintingLayer();
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp
index 61599709..eda8f25 100644
--- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeUpdateTests.cpp
@@ -985,13 +985,13 @@
   EXPECT_NE(nullptr, properties->Mask());
   const auto* mask_clip = properties->MaskClip();
   ASSERT_NE(nullptr, mask_clip);
-  EXPECT_EQ(FloatRoundedRect(0, 50, 50, 100), mask_clip->ClipRect());
+  EXPECT_EQ(FloatRoundedRect(0, 50, 100, 150), mask_clip->ClipRect());
 
   GetDocument().getElementById("rect")->setAttribute("width", "200");
   GetDocument().View()->UpdateAllLifecyclePhases();
   EXPECT_NE(nullptr, properties->Effect());
   EXPECT_NE(nullptr, properties->Mask());
-  EXPECT_EQ(FloatRoundedRect(0, 50, 200, 100), mask_clip->ClipRect());
+  EXPECT_EQ(FloatRoundedRect(0, 50, 100, 150), mask_clip->ClipRect());
 }
 
 TEST_P(PaintPropertyTreeUpdateTest, WillTransformChangeAboveFixed) {
diff --git a/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.cpp
index 75eb742c..7b4af48 100644
--- a/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.cpp
+++ b/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.cpp
@@ -1651,13 +1651,8 @@
   bool overflow_clip_rect_offset_changed =
       old_scrolling_layer_offset != scrolling_layer_->OffsetFromLayoutObject();
 
-  IntSize scroll_size =
-      PixelSnappedIntRect(
-          LayoutRect(
-              LayoutPoint(owning_layer_.SubpixelAccumulation()),
-              LayoutSize(layout_box.ScrollWidth(), layout_box.ScrollHeight())))
-          .Size();
-
+  IntSize scroll_size(layout_box.PixelSnappedScrollWidth(),
+                      layout_box.PixelSnappedScrollHeight());
   if (overflow_clip_rect_offset_changed)
     scrolling_contents_layer_->SetNeedsDisplay();
 
diff --git a/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMappingTest.cpp b/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMappingTest.cpp
index 3ff16d6..3f9fa34 100644
--- a/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMappingTest.cpp
+++ b/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMappingTest.cpp
@@ -2475,47 +2475,4 @@
   EXPECT_EQ(FloatSize(100, 100), mapping->ForegroundLayer()->Size());
 }
 
-TEST_P(CompositedLayerMappingTest, ScrollLayerSizingSubpixelAccumulation) {
-  // This test verifies that when subpixel accumulation causes snapping it
-  // applies to both the scrolling and scrolling contents layers. Verify that
-  // the mapping doesn't have any vertical scrolling introduced as a result of
-  // the snapping behavior. https://crbug.com/801381.
-  GetDocument().GetFrame()->GetSettings()->SetPreferCompositingToLCDTextEnabled(
-      true);
-
-  // The values below are chosen so that the subpixel accumulation causes the
-  // pixel snapped height to be increased relative to snapping without it.
-  SetBodyInnerHTML(R"HTML(
-    <!DOCTYPE html>
-    <style>
-      body {
-        margin: 0;
-      }
-      #scroller {
-        position: relative;
-        top: 0.5625px;
-        width: 200px;
-        height: 200.8125px;
-        overflow: auto;
-      }
-      #space {
-        width: 1000px;
-        height: 200.8125px;
-      }
-    </style>
-    <div id="scroller">
-      <div id="space"></div>
-    </div>
-  )HTML");
-  GetDocument().View()->UpdateAllLifecyclePhases();
-  auto* mapping = ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller"))
-                      ->Layer()
-                      ->GetCompositedLayerMapping();
-  ASSERT_TRUE(mapping);
-  ASSERT_TRUE(mapping->ScrollingLayer());
-  ASSERT_TRUE(mapping->ScrollingContentsLayer());
-  EXPECT_EQ(mapping->ScrollingLayer()->Size().Height(),
-            mapping->ScrollingContentsLayer()->Size().Height());
-}
-
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/ng/ng_paint_fragment.cc b/third_party/WebKit/Source/core/paint/ng/ng_paint_fragment.cc
index 42700ec..09e8e28 100644
--- a/third_party/WebKit/Source/core/paint/ng/ng_paint_fragment.cc
+++ b/third_party/WebKit/Source/core/paint/ng/ng_paint_fragment.cc
@@ -4,6 +4,7 @@
 
 #include "core/paint/ng/ng_paint_fragment.h"
 
+#include "core/layout/LayoutBlockFlow.h"
 #include "core/layout/LayoutInline.h"
 #include "core/layout/ng/geometry/ng_physical_offset_rect.h"
 #include "core/layout/ng/inline/ng_physical_text_fragment.h"
@@ -17,10 +18,22 @@
 
 NGPaintFragment::NGPaintFragment(
     scoped_refptr<const NGPhysicalFragment> fragment,
-    bool stop_at_block_layout_root)
-    : physical_fragment_(std::move(fragment)) {
+    NGPaintFragment* parent)
+    : physical_fragment_(std::move(fragment)), parent_(parent) {
   DCHECK(physical_fragment_);
-  PopulateDescendants(stop_at_block_layout_root);
+}
+
+std::unique_ptr<NGPaintFragment> NGPaintFragment::Create(
+    scoped_refptr<const NGPhysicalFragment> fragment) {
+  std::unique_ptr<NGPaintFragment> paint_fragment =
+      std::make_unique<NGPaintFragment>(std::move(fragment), nullptr);
+
+  HashMap<const LayoutObject*, NGPaintFragment*> last_fragment_map;
+  paint_fragment->PopulateDescendants(NGPhysicalOffset(),
+                                      &paint_fragment->first_fragment_map_,
+                                      &last_fragment_map);
+
+  return paint_fragment;
 }
 
 bool NGPaintFragment::HasSelfPaintingLayer() const {
@@ -43,24 +56,76 @@
 }
 
 // Populate descendants from NGPhysicalFragment tree.
-//
-// |stop_at_block_layout_root| is set to |false| on the root fragment because
-// most root fragments are block layout root but their children are needed.
-// For children, it is set to |true| to stop at the block layout root.
-void NGPaintFragment::PopulateDescendants(bool stop_at_block_layout_root) {
+void NGPaintFragment::PopulateDescendants(
+    const NGPhysicalOffset inline_offset_to_container_box,
+    HashMap<const LayoutObject*, NGPaintFragment*>* first_fragment_map,
+    HashMap<const LayoutObject*, NGPaintFragment*>* last_fragment_map) {
   DCHECK(children_.IsEmpty());
   const NGPhysicalFragment& fragment = PhysicalFragment();
-  // Recurse chlidren, except when this is a block layout root.
-  if (fragment.IsContainer() &&
-      !(fragment.IsBlockLayoutRoot() && stop_at_block_layout_root)) {
-    const NGPhysicalContainerFragment& container =
-        ToNGPhysicalContainerFragment(fragment);
-    children_.ReserveCapacity(container.Children().size());
-    for (const auto& child_fragment : container.Children()) {
-      children_.push_back(
-          std::make_unique<NGPaintFragment>(child_fragment, true));
+  if (!fragment.IsContainer())
+    return;
+  const NGPhysicalContainerFragment& container =
+      ToNGPhysicalContainerFragment(fragment);
+  children_.ReserveCapacity(container.Children().size());
+
+  for (const auto& child_fragment : container.Children()) {
+    std::unique_ptr<NGPaintFragment> child =
+        std::make_unique<NGPaintFragment>(child_fragment, this);
+
+    // Create a linked list for each LayoutObject.
+    //
+    // |first_fragment_map| and |last_fragment_map| each keeps the first and the
+    // last of the list of fragments for a LayoutObject. We use two maps because
+    // |last_fragment_map| is needed only while creating lists, while
+    // |first_fragment_map| is kept for later queries. This may change when we
+    // use fields in LayoutObject to keep the first fragments.
+    if (LayoutObject* layout_object = child_fragment->GetLayoutObject()) {
+      auto add_result = last_fragment_map->insert(layout_object, child.get());
+      if (add_result.is_new_entry) {
+        DCHECK(first_fragment_map->find(layout_object) ==
+               first_fragment_map->end());
+        first_fragment_map->insert(layout_object, child.get());
+      } else {
+        DCHECK(first_fragment_map->find(layout_object) !=
+               first_fragment_map->end());
+        DCHECK(add_result.stored_value->value);
+        add_result.stored_value->value->next_fragment_ = child.get();
+        add_result.stored_value->value = child.get();
+      }
+    }
+
+    child->inline_offset_to_container_box_ =
+        inline_offset_to_container_box + child_fragment->Offset();
+
+    // Recurse chlidren, except when this is a block layout root.
+    // TODO(kojii): At the block layout root, chlidren maybe for NGPaint,
+    // LayoutNG but not for NGPaint, or legacy. In order to get the maximum
+    // test coverage, split the NGPaintFragment tree at all possible engine
+    // boundaries.
+    if (!child_fragment->IsBlockLayoutRoot()) {
+      child->PopulateDescendants(child->inline_offset_to_container_box_,
+                                 first_fragment_map, last_fragment_map);
+    }
+
+    children_.push_back(std::move(child));
+  }
+}
+
+NGPaintFragment::FragmentRange NGPaintFragment::InlineFragmentsFor(
+    const LayoutObject* layout_object) {
+  DCHECK(layout_object && layout_object->IsInline());
+  if (LayoutBlockFlow* block_flow = layout_object->EnclosingNGBlockFlow()) {
+    if (const NGPaintFragment* root = block_flow->PaintFragment()) {
+      auto it = root->first_fragment_map_.find(layout_object);
+      if (it != root->first_fragment_map_.end())
+        return FragmentRange(it->value);
+
+      // TODO(kojii): This is a culled inline box. Should we handle the case
+      // here, or by the caller, or even stop the culled inline boxes?
+      DCHECK(layout_object->IsLayoutInline());
     }
   }
+  return FragmentRange(nullptr);
 }
 
 // TODO(kojii): This code copies VisualRects from the LayoutObject tree. We
diff --git a/third_party/WebKit/Source/core/paint/ng/ng_paint_fragment.h b/third_party/WebKit/Source/core/paint/ng/ng_paint_fragment.h
index 81b5501..b0c8f964 100644
--- a/third_party/WebKit/Source/core/paint/ng/ng_paint_fragment.h
+++ b/third_party/WebKit/Source/core/paint/ng/ng_paint_fragment.h
@@ -5,6 +5,7 @@
 #ifndef ng_paint_fragment_h
 #define ng_paint_fragment_h
 
+#include "core/CoreExport.h"
 #include "core/layout/ng/ng_physical_fragment.h"
 #include "core/loader/resource/ImageResourceObserver.h"
 #include "platform/graphics/paint/DisplayItemClient.h"
@@ -30,19 +31,31 @@
 //   (See https://drafts.csswg.org/css-backgrounds-3/#the-background-image)
 // - image (<img>, svg <image>) or video (<video>) elements that are
 //   placeholders for displaying them.
-class NGPaintFragment : public DisplayItemClient, public ImageResourceObserver {
+class CORE_EXPORT NGPaintFragment : public DisplayItemClient,
+                                    public ImageResourceObserver {
  public:
-  explicit NGPaintFragment(scoped_refptr<const NGPhysicalFragment>,
-                           bool stop_at_block_layout_root = false);
+  NGPaintFragment(scoped_refptr<const NGPhysicalFragment>, NGPaintFragment*);
+  static std::unique_ptr<NGPaintFragment> Create(
+      scoped_refptr<const NGPhysicalFragment>);
 
   const NGPhysicalFragment& PhysicalFragment() const {
     return *physical_fragment_;
   }
 
+  // The parent NGPaintFragment. This is nullptr for a root; i.e., when parent
+  // is not for NGPaint. In the first phase, this means that this is a root of
+  // an inline formatting context.
+  NGPaintFragment* Parent() const { return parent_; }
   const Vector<std::unique_ptr<NGPaintFragment>>& Children() const {
     return children_;
   }
 
+  // Returns offset to its container box for inline fragments.
+  const NGPhysicalOffset& InlineOffsetToContainerBox() const {
+    DCHECK(PhysicalFragment().IsInline());
+    return inline_offset_to_container_box_;
+  }
+
   // Update VisualRect() for this object and all its descendants from
   // LayoutObject. Corresponding LayoutObject::VisualRect() must be computed and
   // set beforehand.
@@ -81,17 +94,84 @@
   NGPhysicalOffset Offset() const { return PhysicalFragment().Offset(); }
   NGPhysicalSize Size() const { return PhysicalFragment().Size(); }
 
+  // A range of fragments for |FragmentsFor()|.
+  class FragmentRange {
+   public:
+    explicit FragmentRange(NGPaintFragment* first) : first_(first) {}
+
+    bool IsEmpty() const { return !first_; }
+
+    class iterator {
+     public:
+      explicit iterator(NGPaintFragment* first) : current_(first) {}
+
+      NGPaintFragment* operator*() const { return current_; }
+      NGPaintFragment* operator->() const { return current_; }
+      void operator++() {
+        CHECK(current_);
+        current_ = current_->next_fragment_;
+      }
+      bool operator==(const iterator& other) const {
+        return current_ == other.current_;
+      }
+      bool operator!=(const iterator& other) const {
+        return current_ != other.current_;
+      }
+
+     private:
+      NGPaintFragment* current_;
+    };
+
+    iterator begin() const { return iterator(first_); }
+    iterator end() const { return iterator(nullptr); }
+
+   private:
+    NGPaintFragment* first_;
+  };
+
+  // Returns a range of NGPaintFragment in an inline formatting context that are
+  // for a LayoutObject.
+  static FragmentRange InlineFragmentsFor(const LayoutObject*);
+
  private:
   void SetVisualRect(const LayoutRect& rect) { visual_rect_ = rect; }
 
-  void PopulateDescendants(bool stop_at_block_layout_root);
+  void PopulateDescendants(
+      const NGPhysicalOffset inline_offset_to_container_box,
+      HashMap<const LayoutObject*, NGPaintFragment*>* first_fragment_map,
+      HashMap<const LayoutObject*, NGPaintFragment*>* last_fragment_map);
 
   void UpdateVisualRectFromLayoutObject(const NGPhysicalOffset&);
 
-  scoped_refptr<const NGPhysicalFragment> physical_fragment_;
-  LayoutRect visual_rect_;
+  //
+  // Following fields are computed in the layout phase.
+  //
 
+  scoped_refptr<const NGPhysicalFragment> physical_fragment_;
+
+  NGPaintFragment* parent_;
   Vector<std::unique_ptr<NGPaintFragment>> children_;
+
+  NGPaintFragment* next_fragment_ = nullptr;
+  NGPhysicalOffset inline_offset_to_container_box_;
+
+  // Maps LayoutObject to NGPaintFragment for the root of an inline formatting
+  // context.
+  // TODO(kojii): This is to be stored in fields of LayoutObject where they are
+  // no longer used in NGPaint, specifically:
+  //   LayoutText::first_text_box_
+  //   LayoutInline::line_boxes_
+  //   LayotuBox::inline_box_wrapper_
+  // but doing so is likely to have some impacts on the performance.
+  // Alternatively we can keep in the root NGPaintFragment. Having this in all
+  // NGPaintFragment is tentative.
+  HashMap<const LayoutObject*, NGPaintFragment*> first_fragment_map_;
+
+  //
+  // Following fields are computed in the pre-paint phase.
+  //
+
+  LayoutRect visual_rect_;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/ng/ng_paint_fragment_test.cc b/third_party/WebKit/Source/core/paint/ng/ng_paint_fragment_test.cc
index 8ecbf6e..776e4f7 100644
--- a/third_party/WebKit/Source/core/paint/ng/ng_paint_fragment_test.cc
+++ b/third_party/WebKit/Source/core/paint/ng/ng_paint_fragment_test.cc
@@ -22,18 +22,76 @@
         ScopedLayoutNGPaintFragmentsForTest(true) {}
 
  protected:
-  const NGPaintFragment& FirstLineBoxByElementId(const char* id) {
+  const NGPaintFragment& RootPaintFragmentByElementId(const char* id) {
     const LayoutNGBlockFlow& block_flow =
         ToLayoutNGBlockFlow(*GetLayoutObjectByElementId(id));
-    const NGPaintFragment& root_fragment = *block_flow.PaintFragment();
-    EXPECT_GE(1u, root_fragment.Children().size());
-    const NGPaintFragment& line_box = *root_fragment.Children()[0];
+    const NGPaintFragment& root = *block_flow.PaintFragment();
+    return root;
+  }
+
+  const NGPaintFragment& FirstLineBoxByElementId(const char* id) {
+    const NGPaintFragment& root = RootPaintFragmentByElementId(id);
+    EXPECT_GE(1u, root.Children().size());
+    const NGPaintFragment& line_box = *root.Children()[0];
     EXPECT_EQ(NGPhysicalFragment::kFragmentLineBox,
               line_box.PhysicalFragment().Type());
     return line_box;
   }
 };
 
+TEST_F(NGPaintFragmentTest, InlineFragmentsFor) {
+  LoadAhem();
+  SetBodyInnerHTML(R"HTML(
+    <!DOCTYPE html>
+    <style>
+    html, body { margin: 0; }
+    div { font: 10px/1 Ahem; width: 10ch; }
+    span { background: yellow; }
+    </style>
+    <body>
+      <div id="container">12345 <span id="box">789 123456789 123<span> 567</div>
+    </body>
+  )HTML");
+  LayoutBlockFlow* container =
+      ToLayoutBlockFlow(GetLayoutObjectByElementId("container"));
+  ASSERT_TRUE(container);
+  LayoutObject* text1 = container->FirstChild();
+  ASSERT_TRUE(text1 && text1->IsText());
+  LayoutObject* box = text1->NextSibling();
+  ASSERT_TRUE(box && box->IsLayoutInline());
+
+  Vector<NGPaintFragment*> results;
+  auto it = NGPaintFragment::InlineFragmentsFor(text1);
+  results.AppendRange(it.begin(), it.end());
+  EXPECT_EQ(1u, results.size());
+  EXPECT_EQ(text1, results[0]->GetLayoutObject());
+  EXPECT_EQ(NGPhysicalOffset(), results[0]->InlineOffsetToContainerBox());
+
+  results.clear();
+  it = NGPaintFragment::InlineFragmentsFor(box);
+  results.AppendRange(it.begin(), it.end());
+  EXPECT_EQ(3u, results.size());
+  EXPECT_EQ(box, results[0]->GetLayoutObject());
+  EXPECT_EQ(box, results[1]->GetLayoutObject());
+  EXPECT_EQ(box, results[2]->GetLayoutObject());
+
+  EXPECT_EQ(NGPhysicalOffset(LayoutUnit(60), LayoutUnit()),
+            results[0]->InlineOffsetToContainerBox());
+  EXPECT_EQ("789", ToNGPhysicalTextFragment(
+                       results[0]->Children()[0]->PhysicalFragment())
+                       .Text());
+  EXPECT_EQ(NGPhysicalOffset(LayoutUnit(), LayoutUnit(10)),
+            results[1]->InlineOffsetToContainerBox());
+  EXPECT_EQ("123456789", ToNGPhysicalTextFragment(
+                             results[1]->Children()[0]->PhysicalFragment())
+                             .Text());
+  EXPECT_EQ(NGPhysicalOffset(LayoutUnit(), LayoutUnit(20)),
+            results[2]->InlineOffsetToContainerBox());
+  EXPECT_EQ("123", ToNGPhysicalTextFragment(
+                       results[2]->Children()[0]->PhysicalFragment())
+                       .Text());
+}
+
 TEST_F(NGPaintFragmentTest, InlineBox) {
   LoadAhem();
   SetBodyInnerHTML(R"HTML(
diff --git a/third_party/WebKit/Source/core/scheduler/VirtualTimeTest.cpp b/third_party/WebKit/Source/core/scheduler/VirtualTimeTest.cpp
index ce3a79cd..9427803 100644
--- a/third_party/WebKit/Source/core/scheduler/VirtualTimeTest.cpp
+++ b/third_party/WebKit/Source/core/scheduler/VirtualTimeTest.cpp
@@ -225,7 +225,7 @@
       "setTimeout(() => { run_order.push(1); }, 1000);"
       "setTimeout(() => { run_order.push(2); }, 1001);");
 
-  scoped_refptr<WebTaskRunner> runner =
+  scoped_refptr<base::SingleThreadTaskRunner> runner =
       Window().GetExecutionContext()->GetTaskRunner(TaskType::kJavascriptTimer);
 
   // Schedule a task to suspend virtual time at the same point in time.
diff --git a/third_party/WebKit/Source/core/testing/DictionaryTest.cpp b/third_party/WebKit/Source/core/testing/DictionaryTest.cpp
index d02ef86..3d59348 100644
--- a/third_party/WebKit/Source/core/testing/DictionaryTest.cpp
+++ b/third_party/WebKit/Source/core/testing/DictionaryTest.cpp
@@ -77,6 +77,7 @@
     internal_enum_or_internal_enum_sequence_ =
         testing_dictionary.internalEnumOrInternalEnumSequenceMember();
   }
+  any_member_ = testing_dictionary.anyMember();
 }
 
 void DictionaryTest::get(InternalDictionary& result) {
@@ -131,6 +132,7 @@
   result.setEventTargetOrNullMember(event_target_or_null_member_);
   result.setInternalEnumOrInternalEnumSequenceMember(
       internal_enum_or_internal_enum_sequence_);
+  result.setAnyMember(any_member_);
 }
 
 ScriptValue DictionaryTest::getDictionaryMemberProperties(
@@ -233,6 +235,7 @@
   dictionary_member_properties_ = WTF::nullopt;
   internal_enum_or_internal_enum_sequence_ =
       InternalEnumOrInternalEnumSequence();
+  any_member_ = ScriptValue();
 }
 
 void DictionaryTest::Trace(blink::Visitor* visitor) {
diff --git a/third_party/WebKit/Source/core/testing/DictionaryTest.h b/third_party/WebKit/Source/core/testing/DictionaryTest.h
index e7a1445..31c77ed 100644
--- a/third_party/WebKit/Source/core/testing/DictionaryTest.h
+++ b/third_party/WebKit/Source/core/testing/DictionaryTest.h
@@ -91,6 +91,7 @@
   bool required_boolean_member_;
   Optional<HashMap<String, String>> dictionary_member_properties_;
   InternalEnumOrInternalEnumSequence internal_enum_or_internal_enum_sequence_;
+  ScriptValue any_member_;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/testing/InternalDictionary.idl b/third_party/WebKit/Source/core/testing/InternalDictionary.idl
index 0ea3728..ef18a2c 100644
--- a/third_party/WebKit/Source/core/testing/InternalDictionary.idl
+++ b/third_party/WebKit/Source/core/testing/InternalDictionary.idl
@@ -35,4 +35,5 @@
     EventTarget? eventTargetOrNullMember = null;
     Dictionary dictionaryMember;
     (InternalEnum or sequence<InternalEnum>) internalEnumOrInternalEnumSequenceMember;
+    any anyMember;
 };
diff --git a/third_party/WebKit/Source/modules/filesystem/DOMFileSystemBase.cpp b/third_party/WebKit/Source/modules/filesystem/DOMFileSystemBase.cpp
index fed4f1a..e9842fb0 100644
--- a/third_party/WebKit/Source/modules/filesystem/DOMFileSystemBase.cpp
+++ b/third_party/WebKit/Source/modules/filesystem/DOMFileSystemBase.cpp
@@ -451,7 +451,7 @@
 int DOMFileSystemBase::ReadDirectory(
     DirectoryReaderBase* reader,
     const String& path,
-    DirectoryReaderOnDidReadCallback* success_callback,
+    EntriesCallbacks::OnDidGetEntriesCallback* success_callback,
     ErrorCallbackBase* error_callback,
     SynchronousType synchronous_type) {
   if (!FileSystem()) {
diff --git a/third_party/WebKit/Source/modules/filesystem/DOMFileSystemBase.h b/third_party/WebKit/Source/modules/filesystem/DOMFileSystemBase.h
index f18b702..fc329743 100644
--- a/third_party/WebKit/Source/modules/filesystem/DOMFileSystemBase.h
+++ b/third_party/WebKit/Source/modules/filesystem/DOMFileSystemBase.h
@@ -48,7 +48,6 @@
 namespace blink {
 
 class DirectoryReaderBase;
-class DirectoryReaderOnDidReadCallback;
 class EntryBase;
 class ExecutionContext;
 class File;
@@ -152,7 +151,7 @@
                     SynchronousType = kAsynchronous);
   int ReadDirectory(DirectoryReaderBase*,
                     const String& path,
-                    DirectoryReaderOnDidReadCallback*,
+                    EntriesCallbacks::OnDidGetEntriesCallback*,
                     ErrorCallbackBase*,
                     SynchronousType = kAsynchronous);
   bool WaitForAdditionalResult(int callbacks_id);
diff --git a/third_party/WebKit/Source/modules/filesystem/DirectoryReader.cpp b/third_party/WebKit/Source/modules/filesystem/DirectoryReader.cpp
index ecc403b..7232fbd 100644
--- a/third_party/WebKit/Source/modules/filesystem/DirectoryReader.cpp
+++ b/third_party/WebKit/Source/modules/filesystem/DirectoryReader.cpp
@@ -40,28 +40,31 @@
 
 namespace {
 
-void RunEntriesCallback(V8EntriesCallback* callback,
-                        HeapVector<Member<Entry>>* entries) {
+void RunEntriesCallback(V8EntriesCallback* callback, EntryHeapVector* entries) {
   callback->handleEvent(*entries);
 }
 
 }  // namespace
 
 class DirectoryReader::EntriesCallbackHelper final
-    : public DirectoryReaderOnDidReadCallback {
+    : public EntriesCallbacks::OnDidGetEntriesCallback {
  public:
-  explicit EntriesCallbackHelper(DirectoryReader* reader) : reader_(reader) {}
-
-  void OnDidReadDirectoryEntries(const EntryHeapVector& entries) override {
-    reader_->AddEntries(entries);
+  static EntriesCallbackHelper* Create(DirectoryReader* reader) {
+    return new EntriesCallbackHelper(reader);
   }
 
   void Trace(blink::Visitor* visitor) override {
     visitor->Trace(reader_);
-    DirectoryReaderOnDidReadCallback::Trace(visitor);
+    EntriesCallbacks::OnDidGetEntriesCallback::Trace(visitor);
+  }
+
+  void OnSuccess(EntryHeapVector* entries) override {
+    reader_->AddEntries(*entries);
   }
 
  private:
+  explicit EntriesCallbackHelper(DirectoryReader* reader) : reader_(reader) {}
+
   // FIXME: This Member keeps the reader alive until all of the readDirectory
   // results are received. crbug.com/350285
   Member<DirectoryReader> reader_;
@@ -69,7 +72,9 @@
 
 class DirectoryReader::ErrorCallbackHelper final : public ErrorCallbackBase {
  public:
-  explicit ErrorCallbackHelper(DirectoryReader* reader) : reader_(reader) {}
+  static ErrorCallbackHelper* Create(DirectoryReader* reader) {
+    return new ErrorCallbackHelper(reader);
+  }
 
   void Invoke(FileError::ErrorCode error) override { reader_->OnError(error); }
 
@@ -79,6 +84,8 @@
   }
 
  private:
+  explicit ErrorCallbackHelper(DirectoryReader* reader) : reader_(reader) {}
+
   Member<DirectoryReader> reader_;
 };
 
@@ -86,15 +93,13 @@
                                  const String& full_path)
     : DirectoryReaderBase(file_system, full_path), is_reading_(false) {}
 
-DirectoryReader::~DirectoryReader() = default;
-
 void DirectoryReader::readEntries(V8EntriesCallback* entries_callback,
                                   V8ErrorCallback* error_callback) {
   if (!is_reading_) {
     is_reading_ = true;
     Filesystem()->ReadDirectory(this, full_path_,
-                                new EntriesCallbackHelper(this),
-                                new ErrorCallbackHelper(this));
+                                EntriesCallbackHelper::Create(this),
+                                ErrorCallbackHelper::Create(this));
   }
 
   if (error_) {
@@ -104,7 +109,7 @@
   }
 
   if (entries_callback_) {
-    // Non-null m_entriesCallback means multiple readEntries() calls are made
+    // Non-null entries_callback_ means multiple readEntries() calls are made
     // concurrently. We don't allow doing it.
     Filesystem()->ReportError(ScriptErrorCallback::Wrap(error_callback),
                               FileError::kInvalidStateErr);
@@ -112,14 +117,11 @@
   }
 
   if (!has_more_entries_ || !entries_.IsEmpty()) {
-    if (entries_callback) {
-      auto* entries = new HeapVector<Member<Entry>>(std::move(entries_));
-      DOMFileSystem::ScheduleCallback(
-          Filesystem()->GetExecutionContext(),
-          WTF::Bind(&RunEntriesCallback, WrapPersistent(entries_callback),
-                    WrapPersistent(entries)));
-    }
-    entries_.clear();
+    EntryHeapVector* entries = new EntryHeapVector(std::move(entries_));
+    DOMFileSystem::ScheduleCallback(
+        Filesystem()->GetExecutionContext(),
+        WTF::Bind(&RunEntriesCallback, WrapPersistent(entries_callback),
+                  WrapPersistent(entries)));
     return;
   }
 
@@ -130,8 +132,7 @@
 void DirectoryReader::AddEntries(const EntryHeapVector& entries) {
   entries_.AppendVector(entries);
   error_callback_ = nullptr;
-  if (entries_callback_) {
-    V8EntriesCallback* entries_callback = entries_callback_.Release();
+  if (V8EntriesCallback* entries_callback = entries_callback_.Release()) {
     EntryHeapVector entries;
     entries.swap(entries_);
     entries_callback->handleEvent(entries);
@@ -141,8 +142,9 @@
 void DirectoryReader::OnError(FileError::ErrorCode error) {
   error_ = error;
   entries_callback_ = nullptr;
-  if (error_callback_)
-    error_callback_->handleEvent(FileError::CreateDOMException(error));
+  if (V8ErrorCallback* error_callback = error_callback_.Release()) {
+    error_callback->handleEvent(FileError::CreateDOMException(error_));
+  }
 }
 
 void DirectoryReader::Trace(blink::Visitor* visitor) {
diff --git a/third_party/WebKit/Source/modules/filesystem/DirectoryReader.h b/third_party/WebKit/Source/modules/filesystem/DirectoryReader.h
index 8c51467..2479644b 100644
--- a/third_party/WebKit/Source/modules/filesystem/DirectoryReader.h
+++ b/third_party/WebKit/Source/modules/filesystem/DirectoryReader.h
@@ -50,7 +50,7 @@
     return new DirectoryReader(file_system, full_path);
   }
 
-  ~DirectoryReader() override;
+  ~DirectoryReader() override = default;
 
   void readEntries(V8EntriesCallback*, V8ErrorCallback* = nullptr);
 
diff --git a/third_party/WebKit/Source/modules/filesystem/DirectoryReaderBase.h b/third_party/WebKit/Source/modules/filesystem/DirectoryReaderBase.h
index 13d540ee..d96de333 100644
--- a/third_party/WebKit/Source/modules/filesystem/DirectoryReaderBase.h
+++ b/third_party/WebKit/Source/modules/filesystem/DirectoryReaderBase.h
@@ -68,17 +68,6 @@
   bool has_more_entries_;
 };
 
-class DirectoryReaderOnDidReadCallback
-    : public GarbageCollectedFinalized<DirectoryReaderOnDidReadCallback> {
- public:
-  virtual ~DirectoryReaderOnDidReadCallback() = default;
-  virtual void Trace(blink::Visitor* visitor) {}
-  virtual void OnDidReadDirectoryEntries(const EntryHeapVector&) = 0;
-
- protected:
-  DirectoryReaderOnDidReadCallback() = default;
-};
-
 }  // namespace blink
 
 #endif  // DirectoryReaderBase_h
diff --git a/third_party/WebKit/Source/modules/filesystem/DirectoryReaderSync.cpp b/third_party/WebKit/Source/modules/filesystem/DirectoryReaderSync.cpp
index 7305bc26..34c3ba0 100644
--- a/third_party/WebKit/Source/modules/filesystem/DirectoryReaderSync.cpp
+++ b/third_party/WebKit/Source/modules/filesystem/DirectoryReaderSync.cpp
@@ -40,62 +40,70 @@
 namespace blink {
 
 class DirectoryReaderSync::EntriesCallbackHelper final
-    : public DirectoryReaderOnDidReadCallback {
+    : public EntriesCallbacks::OnDidGetEntriesCallback {
  public:
-  explicit EntriesCallbackHelper(DirectoryReaderSync* reader)
-      : reader_(reader) {}
-
-  void OnDidReadDirectoryEntries(const EntryHeapVector& entries) override {
-    EntrySyncHeapVector sync_entries;
-    sync_entries.ReserveInitialCapacity(entries.size());
-    for (size_t i = 0; i < entries.size(); ++i)
-      sync_entries.UncheckedAppend(EntrySync::Create(entries[i].Get()));
-    reader_->AddEntries(sync_entries);
+  static EntriesCallbackHelper* Create(DirectoryReaderSync* reader) {
+    return new EntriesCallbackHelper(reader);
   }
 
   void Trace(blink::Visitor* visitor) override {
     visitor->Trace(reader_);
-    DirectoryReaderOnDidReadCallback::Trace(visitor);
+    EntriesCallbacks::OnDidGetEntriesCallback::Trace(visitor);
+  }
+
+  void OnSuccess(EntryHeapVector* entries) override {
+    reader_->entries_.ReserveCapacity(reader_->entries_.size() +
+                                      entries->size());
+    for (const auto& entry : *entries) {
+      reader_->entries_.UncheckedAppend(EntrySync::Create(entry.Get()));
+    }
   }
 
  private:
+  explicit EntriesCallbackHelper(DirectoryReaderSync* reader)
+      : reader_(reader) {}
+
   Member<DirectoryReaderSync> reader_;
 };
 
 class DirectoryReaderSync::ErrorCallbackHelper final
     : public ErrorCallbackBase {
  public:
-  explicit ErrorCallbackHelper(DirectoryReaderSync* reader) : reader_(reader) {}
-
-  void Invoke(FileError::ErrorCode error) override { reader_->SetError(error); }
+  static ErrorCallbackHelper* Create(DirectoryReaderSync* reader) {
+    return new ErrorCallbackHelper(reader);
+  }
 
   void Trace(blink::Visitor* visitor) override {
     visitor->Trace(reader_);
     ErrorCallbackBase::Trace(visitor);
   }
 
+  void Invoke(FileError::ErrorCode error) override {
+    reader_->error_code_ = error;
+  }
+
  private:
+  explicit ErrorCallbackHelper(DirectoryReaderSync* reader) : reader_(reader) {}
+
   Member<DirectoryReaderSync> reader_;
 };
 
 DirectoryReaderSync::DirectoryReaderSync(DOMFileSystemBase* file_system,
                                          const String& full_path)
-    : DirectoryReaderBase(file_system, full_path),
-      callbacks_id_(0),
-      error_code_(FileError::kOK) {}
-
-DirectoryReaderSync::~DirectoryReaderSync() = default;
+    : DirectoryReaderBase(file_system, full_path) {}
 
 EntrySyncHeapVector DirectoryReaderSync::readEntries(
     ExceptionState& exception_state) {
   if (!callbacks_id_) {
     callbacks_id_ = Filesystem()->ReadDirectory(
-        this, full_path_, new EntriesCallbackHelper(this),
-        new ErrorCallbackHelper(this), DOMFileSystemBase::kSynchronous);
+        this, full_path_, EntriesCallbackHelper::Create(this),
+        ErrorCallbackHelper::Create(this), DOMFileSystemBase::kSynchronous);
   }
 
-  if (error_code_ == FileError::kOK && has_more_entries_ && entries_.IsEmpty())
-    file_system_->WaitForAdditionalResult(callbacks_id_);
+  if (error_code_ == FileError::kOK && has_more_entries_ &&
+      entries_.IsEmpty()) {
+    CHECK(Filesystem()->WaitForAdditionalResult(callbacks_id_));
+  }
 
   if (error_code_ != FileError::kOK) {
     FileError::ThrowDOMException(exception_state, error_code_);
diff --git a/third_party/WebKit/Source/modules/filesystem/DirectoryReaderSync.h b/third_party/WebKit/Source/modules/filesystem/DirectoryReaderSync.h
index e3c6290..2ab3106 100644
--- a/third_party/WebKit/Source/modules/filesystem/DirectoryReaderSync.h
+++ b/third_party/WebKit/Source/modules/filesystem/DirectoryReaderSync.h
@@ -52,16 +52,10 @@
     return new DirectoryReaderSync(file_system, full_path);
   }
 
-  ~DirectoryReaderSync() override;
+  ~DirectoryReaderSync() override = default;
 
   EntrySyncHeapVector readEntries(ExceptionState&);
 
-  void AddEntries(const EntrySyncHeapVector& entries) {
-    entries_.AppendVector(entries);
-  }
-
-  void SetError(FileError::ErrorCode code) { error_code_ = code; }
-
   void Trace(blink::Visitor*) override;
 
  private:
@@ -70,9 +64,9 @@
 
   DirectoryReaderSync(DOMFileSystemBase*, const String& full_path);
 
-  int callbacks_id_;
+  int callbacks_id_ = 0;
   EntrySyncHeapVector entries_;
-  FileError::ErrorCode error_code_;
+  FileError::ErrorCode error_code_ = FileError::kOK;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/filesystem/FileSystemCallbacks.cpp b/third_party/WebKit/Source/modules/filesystem/FileSystemCallbacks.cpp
index 334232d..80f3b6a 100644
--- a/third_party/WebKit/Source/modules/filesystem/FileSystemCallbacks.cpp
+++ b/third_party/WebKit/Source/modules/filesystem/FileSystemCallbacks.cpp
@@ -88,38 +88,6 @@
          execution_context_->IsContextPaused();
 }
 
-template <typename CB, typename CBArg>
-void FileSystemCallbacksBase::HandleEventOrScheduleCallback(CB* callback,
-                                                            CBArg* arg) {
-  DCHECK(callback);
-  if (callback) {
-    if (ShouldScheduleCallback()) {
-      DOMFileSystem::ScheduleCallback(
-          execution_context_.Get(),
-          WTF::Bind(&CB::handleEvent, WrapPersistent(callback),
-                    WrapPersistent(arg)));
-    } else {
-      callback->handleEvent(arg);
-    }
-  }
-  execution_context_.Clear();
-}
-
-template <typename CB>
-void FileSystemCallbacksBase::HandleEventOrScheduleCallback(CB* callback) {
-  DCHECK(callback);
-  if (callback) {
-    if (ShouldScheduleCallback()) {
-      DOMFileSystem::ScheduleCallback(
-          execution_context_.Get(),
-          WTF::Bind(&CB::handleEvent, WrapPersistent(callback)));
-    } else {
-      callback->handleEvent();
-    }
-  }
-  execution_context_.Clear();
-}
-
 template <typename CallbackMemberFunction,
           typename CallbackClass,
           typename... Args>
@@ -213,7 +181,7 @@
 // EntriesCallbacks -----------------------------------------------------------
 
 std::unique_ptr<AsyncFileSystemCallbacks> EntriesCallbacks::Create(
-    DirectoryReaderOnDidReadCallback* success_callback,
+    OnDidGetEntriesCallback* success_callback,
     ErrorCallbackBase* error_callback,
     ExecutionContext* context,
     DirectoryReaderBase* directory_reader,
@@ -222,12 +190,11 @@
       success_callback, error_callback, context, directory_reader, base_path));
 }
 
-EntriesCallbacks::EntriesCallbacks(
-    DirectoryReaderOnDidReadCallback* success_callback,
-    ErrorCallbackBase* error_callback,
-    ExecutionContext* context,
-    DirectoryReaderBase* directory_reader,
-    const String& base_path)
+EntriesCallbacks::EntriesCallbacks(OnDidGetEntriesCallback* success_callback,
+                                   ErrorCallbackBase* error_callback,
+                                   ExecutionContext* context,
+                                   DirectoryReaderBase* directory_reader,
+                                   const String& base_path)
     : FileSystemCallbacksBase(error_callback,
                               directory_reader->Filesystem(),
                               context),
@@ -239,23 +206,24 @@
 
 void EntriesCallbacks::DidReadDirectoryEntry(const String& name,
                                              bool is_directory) {
-  if (is_directory)
-    entries_.push_back(
-        DirectoryEntry::Create(directory_reader_->Filesystem(),
-                               DOMFilePath::Append(base_path_, name)));
-  else
-    entries_.push_back(
-        FileEntry::Create(directory_reader_->Filesystem(),
-                          DOMFilePath::Append(base_path_, name)));
+  DOMFileSystemBase* filesystem = directory_reader_->Filesystem();
+  const String& path = DOMFilePath::Append(base_path_, name);
+  Entry* entry =
+      is_directory
+          ? static_cast<Entry*>(DirectoryEntry::Create(filesystem, path))
+          : static_cast<Entry*>(FileEntry::Create(filesystem, path));
+  entries_.push_back(entry);
 }
 
 void EntriesCallbacks::DidReadDirectoryEntries(bool has_more) {
   directory_reader_->SetHasMoreEntries(has_more);
-  EntryHeapVector entries;
-  entries.swap(entries_);
-  // FIXME: delay the callback iff shouldScheduleCallback() is true.
-  if (success_callback_)
-    success_callback_->OnDidReadDirectoryEntries(entries);
+  EntryHeapVector* entries = new EntryHeapVector(std::move(entries_));
+
+  if (!success_callback_)
+    return;
+
+  InvokeOrScheduleCallback(&OnDidGetEntriesCallback::OnSuccess,
+                           success_callback_.Get(), entries);
 }
 
 // FileSystemCallbacks --------------------------------------------------------
diff --git a/third_party/WebKit/Source/modules/filesystem/FileSystemCallbacks.h b/third_party/WebKit/Source/modules/filesystem/FileSystemCallbacks.h
index e047b6e..4dec622 100644
--- a/third_party/WebKit/Source/modules/filesystem/FileSystemCallbacks.h
+++ b/third_party/WebKit/Source/modules/filesystem/FileSystemCallbacks.h
@@ -34,6 +34,7 @@
 #include <memory>
 
 #include "core/fileapi/FileError.h"
+#include "modules/filesystem/EntryHeapVector.h"
 #include "platform/AsyncFileSystemCallbacks.h"
 #include "platform/FileSystemType.h"
 #include "platform/heap/Handle.h"
@@ -45,7 +46,6 @@
 class DOMFileSystem;
 class DOMFileSystemBase;
 class DirectoryReaderBase;
-class DirectoryReaderOnDidReadCallback;
 class Entry;
 class ExecutionContext;
 class File;
@@ -86,12 +86,6 @@
 
   bool ShouldScheduleCallback() const;
 
-  template <typename CB, typename CBArg>
-  void HandleEventOrScheduleCallback(CB*, CBArg*);
-
-  template <typename CB>
-  void HandleEventOrScheduleCallback(CB*);
-
   // Invokes the given callback synchronously or asynchronously depending on
   // the result of |ShouldScheduleCallback|.
   template <typename CallbackMemberFunction,
@@ -173,8 +167,19 @@
 
 class EntriesCallbacks final : public FileSystemCallbacksBase {
  public:
+  class OnDidGetEntriesCallback
+      : public GarbageCollectedFinalized<OnDidGetEntriesCallback> {
+   public:
+    virtual ~OnDidGetEntriesCallback() = default;
+    virtual void Trace(blink::Visitor*) {}
+    virtual void OnSuccess(EntryHeapVector*) = 0;
+
+   protected:
+    OnDidGetEntriesCallback() = default;
+  };
+
   static std::unique_ptr<AsyncFileSystemCallbacks> Create(
-      DirectoryReaderOnDidReadCallback*,
+      OnDidGetEntriesCallback*,
       ErrorCallbackBase*,
       ExecutionContext*,
       DirectoryReaderBase*,
@@ -183,12 +188,12 @@
   void DidReadDirectoryEntries(bool has_more) override;
 
  private:
-  EntriesCallbacks(DirectoryReaderOnDidReadCallback*,
+  EntriesCallbacks(OnDidGetEntriesCallback*,
                    ErrorCallbackBase*,
                    ExecutionContext*,
                    DirectoryReaderBase*,
                    const String& base_path);
-  Persistent<DirectoryReaderOnDidReadCallback> success_callback_;
+  Persistent<OnDidGetEntriesCallback> success_callback_;
   Persistent<DirectoryReaderBase> directory_reader_;
   String base_path_;
   PersistentHeapVector<Member<Entry>> entries_;
diff --git a/third_party/WebKit/Source/modules/filesystem/SyncCallbackHelper.h b/third_party/WebKit/Source/modules/filesystem/SyncCallbackHelper.h
index e566c6b..86d2ec0 100644
--- a/third_party/WebKit/Source/modules/filesystem/SyncCallbackHelper.h
+++ b/third_party/WebKit/Source/modules/filesystem/SyncCallbackHelper.h
@@ -115,6 +115,7 @@
 using EntryCallbacksSyncHelper =
     DOMFileSystemCallbacksSyncHelper<EntryCallbacks::OnDidGetEntryCallback,
                                      Entry>;
+
 using FileSystemCallbacksSyncHelper = DOMFileSystemCallbacksSyncHelper<
     FileSystemCallbacks::OnDidOpenFileSystemCallback,
     DOMFileSystem>;
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
index 1699b90..7c1598e 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
@@ -1144,7 +1144,7 @@
     return;
   }
 
-  if (local_streams_.Contains(stream))
+  if (getLocalStreams().Contains(stream))
     return;
 
   MediaErrorState media_error_state;
@@ -1156,7 +1156,6 @@
     return;
   }
 
-  local_streams_.push_back(stream);
   stream->RegisterObserver(this);
   for (auto& track : stream->getTracks()) {
     DCHECK(track->Component());
@@ -1164,14 +1163,12 @@
   }
 
   bool valid = peer_handler_->AddStream(stream->Descriptor(), constraints);
-  if (!valid)
+  if (!valid) {
     exception_state.ThrowDOMException(kSyntaxError,
                                       "Unable to add the provided stream.");
-  // Ensure |rtp_senders_| is up-to-date so that |addTrack| knows if a sender
-  // already exists for a track. When |addStream| and |removeStream| are
-  // are implemented using |addTrack| and |removeTrack| we can simply add and
-  // remove senders there instead. https://crbug.com/738929
-  getSenders();
+    return;
+  }
+  CreateMissingSendersForStream(stream);
 }
 
 void RTCPeerConnection::removeStream(MediaStream* stream,
@@ -1186,21 +1183,24 @@
     return;
   }
 
-  size_t pos = local_streams_.Find(stream);
-  if (pos == kNotFound)
+  if (!getLocalStreams().Contains(stream))
     return;
 
-  local_streams_.EraseAt(pos);
   stream->UnregisterObserver(this);
 
   peer_handler_->RemoveStream(stream->Descriptor());
+  RemoveUnusedSenders();
 }
 
 MediaStreamVector RTCPeerConnection::getLocalStreams() const {
-  // TODO(hbos): We should define this as "the streams of all senders" instead
-  // of a set that we add to and subtract from on |addStream| and
-  // |removeStream|. https://crbug.com/738918
-  return local_streams_;
+  MediaStreamVector local_streams;
+  for (const auto& rtp_sender : getSenders()) {
+    for (const auto& stream : rtp_sender->streams()) {
+      if (!local_streams.Contains(stream))
+        local_streams.push_back(stream);
+    }
+  }
+  return local_streams;
 }
 
 MediaStreamVector RTCPeerConnection::getRemoteStreams() const {
@@ -1267,33 +1267,24 @@
   return promise;
 }
 
-HeapVector<Member<RTCRtpSender>> RTCPeerConnection::getSenders() {
+HeapVector<Member<RTCRtpSender>> RTCPeerConnection::getSenders() const {
+  HeapVector<Member<RTCRtpSender>> rtp_senders;
+  // |rtp_senders_| and lower layer GetSenders() should match, but we still
+  // invoke GetSenders() to get a predictable list order.
+  // TODO(hbos): Change |rtp_senders_| from a map to a list and stop relying on
+  // GetSenders(). https://crbug.com/803021
   WebVector<std::unique_ptr<WebRTCRtpSender>> web_rtp_senders =
       peer_handler_->GetSenders();
-  HeapVector<Member<RTCRtpSender>> rtp_senders(web_rtp_senders.size());
   for (size_t i = 0; i < web_rtp_senders.size(); ++i) {
     uintptr_t id = web_rtp_senders[i]->Id();
     const auto it = rtp_senders_.find(id);
-    if (it != rtp_senders_.end()) {
-      rtp_senders[i] = it->value;
-    } else {
-      // There does not exist an |RTCRtpSender| for this |WebRTCRtpSender|
-      // yet, create it.
-      MediaStreamTrack* track = nullptr;
-      if (web_rtp_senders[i]->Track()) {
-        track = GetTrack(web_rtp_senders[i]->Track());
-        DCHECK(track);
-      }
-      RTCRtpSender* rtp_sender =
-          new RTCRtpSender(this, std::move(web_rtp_senders[i]), track);
-      rtp_senders_.insert(id, rtp_sender);
-      rtp_senders[i] = rtp_sender;
-    }
+    DCHECK(it != rtp_senders_.end());
+    rtp_senders.push_back(it->value);
   }
   return rtp_senders;
 }
 
-HeapVector<Member<RTCRtpReceiver>> RTCPeerConnection::getReceivers() {
+HeapVector<Member<RTCRtpReceiver>> RTCPeerConnection::getReceivers() const {
   return rtp_receivers_;
 }
 
@@ -1336,7 +1327,7 @@
   uintptr_t id = web_rtp_sender->Id();
   DCHECK(rtp_senders_.find(id) == rtp_senders_.end());
   RTCRtpSender* rtp_sender =
-      new RTCRtpSender(this, std::move(web_rtp_sender), track);
+      new RTCRtpSender(this, std::move(web_rtp_sender), track, streams);
   tracks_.insert(track->Component(), track);
   rtp_senders_.insert(id, rtp_sender);
   return rtp_sender;
@@ -1366,9 +1357,7 @@
   // being nulled.
   DCHECK(!sender->web_sender()->Track());
   sender->SetTrack(nullptr);
-  // TODO(hbos): When |addStream| and |removeStream| are implemented using
-  // |addTrack| and |removeTrack|, we should remove |sender| from |rtp_senders_|
-  // here. https://crbug.com/738929
+  rtp_senders_.erase(sender->web_sender()->Id());
 }
 
 RTCDataChannel* RTCPeerConnection::createDataChannel(
@@ -1426,6 +1415,50 @@
   return rtp_receivers_.end();
 }
 
+void RTCPeerConnection::CreateMissingSendersForStream(MediaStream* stream) {
+  WebVector<std::unique_ptr<WebRTCRtpSender>> web_rtp_senders =
+      peer_handler_->GetSenders();
+  for (size_t i = 0; i < web_rtp_senders.size(); ++i) {
+    uintptr_t id = web_rtp_senders[i]->Id();
+    const auto it = rtp_senders_.find(id);
+    // Any senders created by other means such as addTrack() will already exist
+    // in |rtp_senders_| and not be examined further.
+    if (it != rtp_senders_.end())
+      continue;
+    // Any sender that exist in the lower layer but not in blink must have been
+    // created as a result of the operation that called
+    // CreateMissingSendersForStream(). We create a blink sender under the
+    // assumption that it is associated with |stream|.
+    DCHECK(web_rtp_senders[i]->Track());
+    MediaStreamTrack* track = GetTrack(web_rtp_senders[i]->Track());
+    DCHECK(track);
+    DCHECK(stream->getTracks().Contains(track));
+    HeapVector<Member<MediaStream>> streams;
+    streams.push_back(stream);
+    RTCRtpSender* rtp_sender =
+        new RTCRtpSender(this, std::move(web_rtp_senders[i]), track, streams);
+    rtp_senders_.insert(id, rtp_sender);
+  }
+}
+
+void RTCPeerConnection::RemoveUnusedSenders() {
+  std::set<uintptr_t> used_sender_ids;
+  for (const auto& web_rtp_sender : peer_handler_->GetSenders()) {
+    used_sender_ids.insert(web_rtp_sender->Id());
+  }
+  // HeapHashMap does not support remove-while-iterating so we save all the IDs
+  // of senders we want to erase.
+  std::set<uintptr_t> unused_sender_ids;
+  for (const auto& rtp_sender : rtp_senders_.Values()) {
+    uintptr_t id = rtp_sender->web_sender()->Id();
+    if (used_sender_ids.find(id) == used_sender_ids.end())
+      unused_sender_ids.insert(id);
+  }
+  for (auto sender_id : unused_sender_ids) {
+    rtp_senders_.erase(sender_id);
+  }
+}
+
 RTCDTMFSender* RTCPeerConnection::createDTMFSender(
     MediaStreamTrack* track,
     ExceptionState& exception_state) {
@@ -1435,7 +1468,7 @@
   DCHECK(track);
 
   bool is_local_stream_track = false;
-  for (const auto& local_stream : local_streams_) {
+  for (const auto& local_stream : getLocalStreams()) {
     if (local_stream->getTracks().Contains(track)) {
       is_local_stream_track = true;
       break;
@@ -1467,10 +1500,13 @@
   DCHECK(track->Component());
   // Insert if not already present.
   tracks_.insert(track->Component(), track);
+  CreateMissingSendersForStream(stream);
 }
 
 void RTCPeerConnection::OnStreamRemoveTrack(MediaStream* stream,
                                             MediaStreamTrack* track) {
+  // Remove any senders that was removed from the lower layers as a result.
+  RemoveUnusedSenders();
   // Don't remove |track| from |tracks_|, it may be referenced by another
   // component. |tracks_| uses weak members and will automatically have |track|
   // removed if destroyed.
@@ -1811,7 +1847,6 @@
 }
 
 void RTCPeerConnection::Trace(blink::Visitor* visitor) {
-  visitor->Trace(local_streams_);
   visitor->Trace(tracks_);
   visitor->Trace(rtp_senders_);
   visitor->Trace(rtp_receivers_);
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.h b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.h
index 969abbf..a6b4700 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.h
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.h
@@ -159,8 +159,8 @@
                          MediaStreamTrack* selector = nullptr);
   ScriptPromise getStats(ScriptState*);
 
-  HeapVector<Member<RTCRtpSender>> getSenders();
-  HeapVector<Member<RTCRtpReceiver>> getReceivers();
+  HeapVector<Member<RTCRtpSender>> getSenders() const;
+  HeapVector<Member<RTCRtpReceiver>> getReceivers() const;
   RTCRtpSender* addTrack(MediaStreamTrack*, MediaStreamVector, ExceptionState&);
   void removeTrack(RTCRtpSender*, ExceptionState&);
   DEFINE_ATTRIBUTE_EVENT_LISTENER(track);
@@ -261,6 +261,19 @@
   MediaStreamTrack* GetTrack(const WebMediaStreamTrack&) const;
   HeapVector<Member<RTCRtpReceiver>>::iterator FindReceiver(
       const WebRTCRtpReceiver& web_receiver);
+  // addStream() and removeStream() result in senders being added or removed.
+  // When a legacy stream API has been invoked, these methods must be invoked to
+  // make blink layer |rtp_senders_| up-to-date. The assumption of
+  // CreateMissingSendersForStream() is that any lower layer senders found that
+  // don't exist in blink was just created for the specified stream.
+  // RemoveUnusedSenders() removes all blink senders that don't exist in the
+  // lower layers.
+  // TODO(hbos): Stop using legacy stream APIs and remove these methods. When
+  // addStream() and removeStream() are implemented on top of track-based APIs
+  // we don't have to do these tricks to keep |rtp_senders_| up-to-date.
+  // https://crbug.com/738929
+  void CreateMissingSendersForStream(MediaStream*);
+  void RemoveUnusedSenders();
 
   // The "Change" methods set the state asynchronously and fire the
   // corresponding event immediately after changing the state (if it was really
@@ -302,10 +315,8 @@
   ICEGatheringState ice_gathering_state_;
   ICEConnectionState ice_connection_state_;
 
-  MediaStreamVector local_streams_;
   // A map containing any track that is in use by the peer connection. This
-  // includes tracks of |local_streams_|, |remote_streams_|, |rtp_senders_| and
-  // |rtp_receivers_|.
+  // includes tracks of |rtp_senders_| and |rtp_receivers_|.
   HeapHashMap<WeakMember<MediaStreamComponent>, WeakMember<MediaStreamTrack>>
       tracks_;
   HeapHashMap<uintptr_t, Member<RTCRtpSender>> rtp_senders_;
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCRtpSender.cpp b/third_party/WebKit/Source/modules/peerconnection/RTCRtpSender.cpp
index d9c458e..97a8be97 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCRtpSender.cpp
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCRtpSender.cpp
@@ -51,8 +51,12 @@
 
 RTCRtpSender::RTCRtpSender(RTCPeerConnection* pc,
                            std::unique_ptr<WebRTCRtpSender> sender,
-                           MediaStreamTrack* track)
-    : pc_(pc), sender_(std::move(sender)), track_(track) {
+                           MediaStreamTrack* track,
+                           MediaStreamVector streams)
+    : pc_(pc),
+      sender_(std::move(sender)),
+      track_(track),
+      streams_(std::move(streams)) {
   DCHECK(pc_);
   DCHECK(sender_);
   DCHECK(track_);
@@ -88,9 +92,14 @@
   track_ = track;
 }
 
+MediaStreamVector RTCRtpSender::streams() const {
+  return streams_;
+}
+
 void RTCRtpSender::Trace(blink::Visitor* visitor) {
   visitor->Trace(pc_);
   visitor->Trace(track_);
+  visitor->Trace(streams_);
   ScriptWrappable::Trace(visitor);
 }
 
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCRtpSender.h b/third_party/WebKit/Source/modules/peerconnection/RTCRtpSender.h
index 9885541..143b32ad 100644
--- a/third_party/WebKit/Source/modules/peerconnection/RTCRtpSender.h
+++ b/third_party/WebKit/Source/modules/peerconnection/RTCRtpSender.h
@@ -6,6 +6,7 @@
 #define RTCRtpSender_h
 
 #include "bindings/core/v8/ScriptPromise.h"
+#include "modules/mediastream/MediaStream.h"
 #include "platform/bindings/ScriptWrappable.h"
 #include "platform/heap/GarbageCollected.h"
 #include "platform/heap/Member.h"
@@ -27,7 +28,8 @@
   // https://github.com/w3c/webrtc-pc/issues/1712
   RTCRtpSender(RTCPeerConnection*,
                std::unique_ptr<WebRTCRtpSender>,
-               MediaStreamTrack*);
+               MediaStreamTrack*,
+               MediaStreamVector streams);
 
   MediaStreamTrack* track();
   ScriptPromise replaceTrack(ScriptState*, MediaStreamTrack*);
@@ -36,6 +38,7 @@
   // Sets the track. This must be called when the |WebRTCRtpSender| has its
   // track updated, and the |track| must match the |WebRTCRtpSender::Track|.
   void SetTrack(MediaStreamTrack*);
+  MediaStreamVector streams() const;
 
   virtual void Trace(blink::Visitor*);
 
@@ -43,6 +46,7 @@
   Member<RTCPeerConnection> pc_;
   std::unique_ptr<WebRTCRtpSender> sender_;
   Member<MediaStreamTrack> track_;
+  MediaStreamVector streams_;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/picture_in_picture/DocumentPictureInPicture.cpp b/third_party/WebKit/Source/modules/picture_in_picture/DocumentPictureInPicture.cpp
index 52fba31a..21249f3 100644
--- a/third_party/WebKit/Source/modules/picture_in_picture/DocumentPictureInPicture.cpp
+++ b/third_party/WebKit/Source/modules/picture_in_picture/DocumentPictureInPicture.cpp
@@ -4,10 +4,19 @@
 
 #include "modules/picture_in_picture/DocumentPictureInPicture.h"
 
+#include "core/dom/DOMException.h"
+#include "core/dom/Document.h"
 #include "modules/picture_in_picture/PictureInPictureController.h"
 
 namespace blink {
 
+namespace {
+
+const char kNoPictureInPictureElement[] =
+    "There is no Picture-in-Picture element in this document.";
+
+}  // namespace
+
 // static
 bool DocumentPictureInPicture::pictureInPictureEnabled(Document& document) {
   return PictureInPictureController::Ensure(document).PictureInPictureEnabled();
@@ -16,10 +25,25 @@
 // static
 ScriptPromise DocumentPictureInPicture::exitPictureInPicture(
     ScriptState* script_state,
-    const Document&) {
+    Document& document) {
+  if (!PictureInPictureController::Ensure(document).PictureInPictureElement()) {
+    return ScriptPromise::RejectWithDOMException(
+        script_state,
+        DOMException::Create(kInvalidStateError, kNoPictureInPictureElement));
+  }
+
   // TODO(crbug.com/806249): Call element.exitPictureInPicture().
+  // TODO(crbug.com/806249): Trigger leavepictureinpicture event.
+
+  PictureInPictureController::Ensure(document).UnsetPictureInPictureElement();
 
   return ScriptPromise::CastUndefined(script_state);
 }
 
+// static
+HTMLVideoElement* DocumentPictureInPicture::pictureInPictureElement(
+    Document& document) {
+  return PictureInPictureController::Ensure(document).PictureInPictureElement();
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/picture_in_picture/DocumentPictureInPicture.h b/third_party/WebKit/Source/modules/picture_in_picture/DocumentPictureInPicture.h
index a0ae5fc4..5d6cb6fc 100644
--- a/third_party/WebKit/Source/modules/picture_in_picture/DocumentPictureInPicture.h
+++ b/third_party/WebKit/Source/modules/picture_in_picture/DocumentPictureInPicture.h
@@ -10,6 +10,7 @@
 namespace blink {
 
 class Document;
+class HTMLVideoElement;
 class ScriptPromise;
 class ScriptState;
 
@@ -18,7 +19,10 @@
 
  public:
   static bool pictureInPictureEnabled(Document&);
-  static ScriptPromise exitPictureInPicture(ScriptState*, const Document&);
+
+  static ScriptPromise exitPictureInPicture(ScriptState*, Document&);
+
+  static HTMLVideoElement* pictureInPictureElement(Document&);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/picture_in_picture/DocumentPictureInPicture.idl b/third_party/WebKit/Source/modules/picture_in_picture/DocumentPictureInPicture.idl
index 6ea3798..0b19578 100644
--- a/third_party/WebKit/Source/modules/picture_in_picture/DocumentPictureInPicture.idl
+++ b/third_party/WebKit/Source/modules/picture_in_picture/DocumentPictureInPicture.idl
@@ -11,4 +11,6 @@
     readonly attribute boolean pictureInPictureEnabled;
 
     [CallWith=ScriptState] Promise<void> exitPictureInPicture();
+
+    readonly attribute HTMLVideoElement? pictureInPictureElement;
 };
\ No newline at end of file
diff --git a/third_party/WebKit/Source/modules/picture_in_picture/HTMLVideoElementPictureInPicture.cpp b/third_party/WebKit/Source/modules/picture_in_picture/HTMLVideoElementPictureInPicture.cpp
index 5935554cf..22211f0 100644
--- a/third_party/WebKit/Source/modules/picture_in_picture/HTMLVideoElementPictureInPicture.cpp
+++ b/third_party/WebKit/Source/modules/picture_in_picture/HTMLVideoElementPictureInPicture.cpp
@@ -23,7 +23,8 @@
 const char kNotAvailable[] = "Picture-in-Picture is not available.";
 const char kUserGestureRequired[] =
     "Must be handling a user gesture to request picture in picture.";
-
+const char kDisablePictureInPicturePresent[] =
+    "\"disablePictureInPicture\" attribute is present.";
 }  // namespace
 
 // static
@@ -36,11 +37,16 @@
         script_state, DOMException::Create(kInvalidStateError, kDetachedError));
   }
 
-  switch (PictureInPictureController::Ensure(document).GetStatus()) {
+  switch (
+      PictureInPictureController::Ensure(document).IsElementAllowed(element)) {
     case Status::kDisabledByFeaturePolicy:
       return ScriptPromise::RejectWithDOMException(
           script_state,
           DOMException::Create(kSecurityError, kFeaturePolicyBlocked));
+    case Status::kDisabledByAttribute:
+      return ScriptPromise::RejectWithDOMException(
+          script_state, DOMException::Create(kInvalidStateError,
+                                             kDisablePictureInPicturePresent));
     case Status::kDisabledBySystem:
       return ScriptPromise::RejectWithDOMException(
           script_state,
@@ -57,10 +63,43 @@
   }
 
   // TODO(crbug.com/806249): Call element.enterPictureInPicture().
+  // TODO(crbug.com/806249): Trigger enterpictureinpicture event.
 
-  return ScriptPromise::RejectWithDOMException(
-      script_state,
-      DOMException::Create(kNotSupportedError, "Not implemented yet"));
+  PictureInPictureController::Ensure(document).SetPictureInPictureElement(
+      element);
+
+  return ScriptPromise::CastUndefined(script_state);
+}
+
+// static
+bool HTMLVideoElementPictureInPicture::FastHasAttribute(
+    const QualifiedName& name,
+    const HTMLVideoElement& element) {
+  DCHECK(name == HTMLNames::disablepictureinpictureAttr);
+  return element.FastHasAttribute(name);
+}
+
+// static
+void HTMLVideoElementPictureInPicture::SetBooleanAttribute(
+    const QualifiedName& name,
+    HTMLVideoElement& element,
+    bool value) {
+  DCHECK(name == HTMLNames::disablepictureinpictureAttr);
+  element.SetBooleanAttribute(name, value);
+
+  if (!value)
+    return;
+
+  // TODO(crbug.com/806249): Reject pending PiP requests.
+
+  Document& document = element.GetDocument();
+  if (PictureInPictureController::Ensure(document).PictureInPictureElement() ==
+      &element) {
+    // TODO(crbug.com/806249): Call element.exitPictureInPicture().
+    // TODO(crbug.com/806249): Trigger leavepictureinpicture event.
+
+    PictureInPictureController::Ensure(document).UnsetPictureInPictureElement();
+  }
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/picture_in_picture/HTMLVideoElementPictureInPicture.h b/third_party/WebKit/Source/modules/picture_in_picture/HTMLVideoElementPictureInPicture.h
index d7d50f1..dfbf9e73 100644
--- a/third_party/WebKit/Source/modules/picture_in_picture/HTMLVideoElementPictureInPicture.h
+++ b/third_party/WebKit/Source/modules/picture_in_picture/HTMLVideoElementPictureInPicture.h
@@ -5,6 +5,7 @@
 #ifndef HTMLVideoElementPictureInPicture_h
 #define HTMLVideoElementPictureInPicture_h
 
+#include "core/dom/QualifiedName.h"
 #include "modules/ModulesExport.h"
 #include "platform/heap/Handle.h"
 
@@ -19,6 +20,12 @@
 
  public:
   static ScriptPromise requestPictureInPicture(ScriptState*, HTMLVideoElement&);
+
+  static bool FastHasAttribute(const QualifiedName&, const HTMLVideoElement&);
+
+  static void SetBooleanAttribute(const QualifiedName&,
+                                  HTMLVideoElement&,
+                                  bool);
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/picture_in_picture/HTMLVideoElementPictureInPicture.idl b/third_party/WebKit/Source/modules/picture_in_picture/HTMLVideoElementPictureInPicture.idl
index 267d648..e8d386c 100644
--- a/third_party/WebKit/Source/modules/picture_in_picture/HTMLVideoElementPictureInPicture.idl
+++ b/third_party/WebKit/Source/modules/picture_in_picture/HTMLVideoElementPictureInPicture.idl
@@ -14,4 +14,7 @@
     // TODO(crbug.com/806249): Implement PiP video events.
     //attribute EventHandler onenterpictureinpicture;
     //attribute EventHandler onleavepictureinpicture;
+
+    [CEReactions, Reflect] attribute boolean disablePictureInPicture;
+
 };
\ No newline at end of file
diff --git a/third_party/WebKit/Source/modules/picture_in_picture/PictureInPictureController.cpp b/third_party/WebKit/Source/modules/picture_in_picture/PictureInPictureController.cpp
index dba5cd6..279d1151 100644
--- a/third_party/WebKit/Source/modules/picture_in_picture/PictureInPictureController.cpp
+++ b/third_party/WebKit/Source/modules/picture_in_picture/PictureInPictureController.cpp
@@ -5,6 +5,7 @@
 #include "modules/picture_in_picture/PictureInPictureController.h"
 
 #include "core/dom/Document.h"
+#include "core/html/media/HTMLVideoElement.h"
 #include "platform/feature_policy/FeaturePolicy.h"
 
 namespace blink {
@@ -33,13 +34,18 @@
 }
 
 bool PictureInPictureController::PictureInPictureEnabled() const {
-  return GetStatus() == Status::kEnabled;
+  return IsDocumentAllowed() == Status::kEnabled;
 }
 
-PictureInPictureController::Status PictureInPictureController::GetStatus()
-    const {
+PictureInPictureController::Status
+PictureInPictureController::IsDocumentAllowed() const {
   DCHECK(GetSupplementable());
 
+  // `picture_in_picture_enabled_` is set to false by the embedder when it
+  // or the system forbids the page from using Picture-in-Picture.
+  if (!picture_in_picture_enabled_)
+    return Status::kDisabledBySystem;
+
   // If document is not allowed to use the policy-controlled feature named
   // "picture-in-picture", return kDisabledByFeaturePolicy status.
   LocalFrame* frame = GetSupplementable()->GetFrame();
@@ -50,12 +56,17 @@
     return Status::kDisabledByFeaturePolicy;
   }
 
-  // TODO(crbug.com/806249): Handle status when disabled by attribute
+  return Status::kEnabled;
+}
 
-  // `picture_in_picture_enabled_` is set to false by the embedder when it
-  // or the system forbids the page from using Picture-in-Picture.
-  if (!picture_in_picture_enabled_)
-    return Status::kDisabledBySystem;
+PictureInPictureController::Status PictureInPictureController::IsElementAllowed(
+    HTMLVideoElement& element) const {
+  PictureInPictureController::Status status = IsDocumentAllowed();
+  if (status != Status::kEnabled)
+    return status;
+
+  if (element.FastHasAttribute(HTMLNames::disablepictureinpictureAttr))
+    return Status::kDisabledByAttribute;
 
   return Status::kEnabled;
 }
@@ -65,4 +76,22 @@
   picture_in_picture_enabled_ = value;
 }
 
+void PictureInPictureController::SetPictureInPictureElement(
+    HTMLVideoElement& element) {
+  picture_in_picture_element_ = &element;
+}
+
+void PictureInPictureController::UnsetPictureInPictureElement() {
+  picture_in_picture_element_ = nullptr;
+}
+
+HTMLVideoElement* PictureInPictureController::PictureInPictureElement() const {
+  return picture_in_picture_element_;
+}
+
+void PictureInPictureController::Trace(blink::Visitor* visitor) {
+  visitor->Trace(picture_in_picture_element_);
+  Supplement<Document>::Trace(visitor);
+}
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/picture_in_picture/PictureInPictureController.h b/third_party/WebKit/Source/modules/picture_in_picture/PictureInPictureController.h
index 9aecc45a8..c9817f2 100644
--- a/third_party/WebKit/Source/modules/picture_in_picture/PictureInPictureController.h
+++ b/third_party/WebKit/Source/modules/picture_in_picture/PictureInPictureController.h
@@ -10,6 +10,8 @@
 
 namespace blink {
 
+class HTMLVideoElement;
+
 class MODULES_EXPORT PictureInPictureController
     : public GarbageCollectedFinalized<PictureInPictureController>,
       public Supplement<Document> {
@@ -29,16 +31,29 @@
 
   enum class Status {
     kEnabled,
-    kDisabledByFeaturePolicy,
     kDisabledBySystem,
+    kDisabledByFeaturePolicy,
+    kDisabledByAttribute,
   };
 
-  Status GetStatus() const;
+  Status IsDocumentAllowed() const;
+
+  Status IsElementAllowed(HTMLVideoElement&) const;
+
+  void SetPictureInPictureElement(HTMLVideoElement&);
+
+  void UnsetPictureInPictureElement();
+
+  HTMLVideoElement* PictureInPictureElement() const;
+
+  void Trace(blink::Visitor*) override;
 
  private:
   explicit PictureInPictureController(Document&);
 
   bool picture_in_picture_enabled_ = true;
+
+  Member<HTMLVideoElement> picture_in_picture_element_;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/modules/serviceworkers/FetchEvent.idl b/third_party/WebKit/Source/modules/serviceworkers/FetchEvent.idl
index 8ff57c9c..16e30db 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/FetchEvent.idl
+++ b/third_party/WebKit/Source/modules/serviceworkers/FetchEvent.idl
@@ -10,7 +10,7 @@
     Exposed=ServiceWorker
 ] interface FetchEvent : ExtendableEvent {
     [SameObject] readonly attribute Request request;
-    readonly attribute DOMString? clientId;
+    readonly attribute DOMString clientId;
     readonly attribute boolean isReload;
 
     [CallWith=ScriptState, RaisesException] void respondWith(Promise<Response> r);
diff --git a/third_party/WebKit/Source/modules/serviceworkers/FetchEventInit.idl b/third_party/WebKit/Source/modules/serviceworkers/FetchEventInit.idl
index c373916..67706aba 100644
--- a/third_party/WebKit/Source/modules/serviceworkers/FetchEventInit.idl
+++ b/third_party/WebKit/Source/modules/serviceworkers/FetchEventInit.idl
@@ -6,6 +6,6 @@
 
 dictionary FetchEventInit : ExtendableEventInit {
   required Request request;
-  DOMString? clientId = null;
+  DOMString clientId = "";
   boolean isReload = false;
 };
diff --git a/third_party/WebKit/Source/platform/AsyncMethodRunner.h b/third_party/WebKit/Source/platform/AsyncMethodRunner.h
index 73a8cb4..b249fc5 100644
--- a/third_party/WebKit/Source/platform/AsyncMethodRunner.h
+++ b/third_party/WebKit/Source/platform/AsyncMethodRunner.h
@@ -45,9 +45,10 @@
  public:
   typedef void (TargetClass::*TargetMethod)();
 
-  static AsyncMethodRunner* Create(TargetClass* object,
-                                   TargetMethod method,
-                                   scoped_refptr<WebTaskRunner> task_runner) {
+  static AsyncMethodRunner* Create(
+      TargetClass* object,
+      TargetMethod method,
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
     return new AsyncMethodRunner(object, method, std::move(task_runner));
   }
 
@@ -116,7 +117,7 @@
  private:
   AsyncMethodRunner(TargetClass* object,
                     TargetMethod method,
-                    scoped_refptr<WebTaskRunner> task_runner)
+                    scoped_refptr<base::SingleThreadTaskRunner> task_runner)
       : timer_(std::move(task_runner),
                this,
                &AsyncMethodRunner<TargetClass>::Fired),
diff --git a/third_party/WebKit/Source/platform/Timer.cpp b/third_party/WebKit/Source/platform/Timer.cpp
index 9adf30c..cb544233 100644
--- a/third_party/WebKit/Source/platform/Timer.cpp
+++ b/third_party/WebKit/Source/platform/Timer.cpp
@@ -40,7 +40,8 @@
 
 namespace blink {
 
-TimerBase::TimerBase(scoped_refptr<WebTaskRunner> web_task_runner)
+TimerBase::TimerBase(
+    scoped_refptr<base::SingleThreadTaskRunner> web_task_runner)
     : web_task_runner_(std::move(web_task_runner)),
 #if DCHECK_IS_ON()
       thread_(CurrentThread()),
@@ -82,7 +83,8 @@
   return next_fire_time_ - current;
 }
 
-void TimerBase::MoveToNewTaskRunner(scoped_refptr<WebTaskRunner> task_runner) {
+void TimerBase::MoveToNewTaskRunner(
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
 #if DCHECK_IS_ON()
   DCHECK_EQ(thread_, CurrentThread());
   DCHECK(task_runner->RunsTasksInCurrentSequence());
@@ -107,11 +109,11 @@
 }
 
 // static
-scoped_refptr<WebTaskRunner> TimerBase::GetTimerTaskRunner() {
+scoped_refptr<base::SingleThreadTaskRunner> TimerBase::GetTimerTaskRunner() {
   return Platform::Current()->CurrentThread()->Scheduler()->TimerTaskRunner();
 }
 
-scoped_refptr<WebTaskRunner> TimerBase::TimerTaskRunner() const {
+scoped_refptr<base::SingleThreadTaskRunner> TimerBase::TimerTaskRunner() const {
   return web_task_runner_;
 }
 
diff --git a/third_party/WebKit/Source/platform/Timer.h b/third_party/WebKit/Source/platform/Timer.h
index ffcc1185..ff0d9c3 100644
--- a/third_party/WebKit/Source/platform/Timer.h
+++ b/third_party/WebKit/Source/platform/Timer.h
@@ -28,9 +28,9 @@
 
 #include "base/location.h"
 #include "base/memory/weak_ptr.h"
+#include "base/single_thread_task_runner.h"
 #include "base/time/time.h"
 #include "platform/PlatformExport.h"
-#include "platform/WebTaskRunner.h"
 #include "platform/heap/Handle.h"
 #include "platform/wtf/AddressSanitizer.h"
 #include "platform/wtf/Allocator.h"
@@ -46,7 +46,7 @@
   WTF_MAKE_NONCOPYABLE(TimerBase);
 
  public:
-  explicit TimerBase(scoped_refptr<WebTaskRunner>);
+  explicit TimerBase(scoped_refptr<base::SingleThreadTaskRunner>);
   virtual ~TimerBase();
 
   void Start(TimeDelta next_fire_interval,
@@ -93,19 +93,19 @@
     AugmentRepeatInterval(TimeDelta::FromSecondsD(delta));
   }
 
-  void MoveToNewTaskRunner(scoped_refptr<WebTaskRunner>);
+  void MoveToNewTaskRunner(scoped_refptr<base::SingleThreadTaskRunner>);
 
   struct PLATFORM_EXPORT Comparator {
     bool operator()(const TimerBase* a, const TimerBase* b) const;
   };
 
  protected:
-  static scoped_refptr<WebTaskRunner> GetTimerTaskRunner();
+  static scoped_refptr<base::SingleThreadTaskRunner> GetTimerTaskRunner();
 
  private:
   virtual void Fired() = 0;
 
-  virtual scoped_refptr<WebTaskRunner> TimerTaskRunner() const;
+  virtual scoped_refptr<base::SingleThreadTaskRunner> TimerTaskRunner() const;
 
   NO_SANITIZE_ADDRESS
   virtual bool CanFire() const { return true; }
@@ -119,7 +119,7 @@
   TimeTicks next_fire_time_;   // 0 if inactive
   TimeDelta repeat_interval_;  // 0 if not repeating
   base::Location location_;
-  scoped_refptr<WebTaskRunner> web_task_runner_;
+  scoped_refptr<base::SingleThreadTaskRunner> web_task_runner_;
 
 #if DCHECK_IS_ON()
   ThreadIdentifier thread_;
@@ -150,7 +150,7 @@
  public:
   using TimerFiredFunction = void (TimerFiredClass::*)(TimerBase*);
 
-  TaskRunnerTimer(scoped_refptr<WebTaskRunner> web_task_runner,
+  TaskRunnerTimer(scoped_refptr<base::SingleThreadTaskRunner> web_task_runner,
                   TimerFiredClass* o,
                   TimerFiredFunction f)
       : TimerBase(std::move(web_task_runner)), object_(o), function_(f) {}
diff --git a/third_party/WebKit/Source/platform/TimerTest.cpp b/third_party/WebKit/Source/platform/TimerTest.cpp
index 0745a38..ed9d4a7b 100644
--- a/third_party/WebKit/Source/platform/TimerTest.cpp
+++ b/third_party/WebKit/Source/platform/TimerTest.cpp
@@ -528,7 +528,7 @@
 
   ~TimerForTest() override = default;
 
-  TimerForTest(scoped_refptr<WebTaskRunner> web_task_runner,
+  TimerForTest(scoped_refptr<base::SingleThreadTaskRunner> web_task_runner,
                TimerFiredClass* timer_fired_class,
                TimerFiredFunction timer_fired_function)
       : TaskRunnerTimer<TimerFiredClass>(std::move(web_task_runner),
@@ -609,8 +609,9 @@
 
 class TaskObserver : public base::MessageLoop::TaskObserver {
  public:
-  TaskObserver(scoped_refptr<WebTaskRunner> task_runner,
-               std::vector<scoped_refptr<WebTaskRunner>>* run_order)
+  TaskObserver(
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+      std::vector<scoped_refptr<base::SingleThreadTaskRunner>>* run_order)
       : task_runner_(std::move(task_runner)), run_order_(run_order) {}
 
   void WillProcessTask(const base::PendingTask&) {}
@@ -620,14 +621,14 @@
   }
 
  private:
-  scoped_refptr<WebTaskRunner> task_runner_;
-  std::vector<scoped_refptr<WebTaskRunner>>* run_order_;
+  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+  std::vector<scoped_refptr<base::SingleThreadTaskRunner>>* run_order_;
 };
 
 }  // namespace
 
 TEST_F(TimerTest, MoveToNewTaskRunnerOneShot) {
-  std::vector<scoped_refptr<WebTaskRunner>> run_order;
+  std::vector<scoped_refptr<base::SingleThreadTaskRunner>> run_order;
 
   scoped_refptr<scheduler::TaskQueue> task_runner1(
       platform_->GetRendererScheduler()->NewTimerTaskQueue(
@@ -669,7 +670,7 @@
 }
 
 TEST_F(TimerTest, MoveToNewTaskRunnerRepeating) {
-  std::vector<scoped_refptr<WebTaskRunner>> run_order;
+  std::vector<scoped_refptr<base::SingleThreadTaskRunner>> run_order;
 
   scoped_refptr<scheduler::TaskQueue> task_runner1(
       platform_->GetRendererScheduler()->NewTimerTaskQueue(
diff --git a/third_party/WebKit/Source/platform/WebTaskRunner.cpp b/third_party/WebKit/Source/platform/WebTaskRunner.cpp
index a4e043d..430ea625 100644
--- a/third_party/WebKit/Source/platform/WebTaskRunner.cpp
+++ b/third_party/WebKit/Source/platform/WebTaskRunner.cpp
@@ -116,7 +116,7 @@
 // avoid copying the closure later in the call chain. Copying the bound state
 // can lead to data races with ref counted objects like StringImpl. See
 // crbug.com/679915 for more details.
-void PostCrossThreadTask(WebTaskRunner& task_runner,
+void PostCrossThreadTask(base::SingleThreadTaskRunner& task_runner,
                          const base::Location& location,
                          CrossThreadClosure task) {
   task_runner.PostDelayedTask(
@@ -124,7 +124,7 @@
       base::TimeDelta());
 }
 
-void PostDelayedCrossThreadTask(WebTaskRunner& task_runner,
+void PostDelayedCrossThreadTask(base::SingleThreadTaskRunner& task_runner,
                                 const base::Location& location,
                                 CrossThreadClosure task,
                                 TimeDelta delay) {
@@ -132,7 +132,7 @@
       location, base::BindOnce(&RunCrossThreadClosure, std::move(task)), delay);
 }
 
-TaskHandle PostCancellableTask(WebTaskRunner& task_runner,
+TaskHandle PostCancellableTask(base::SingleThreadTaskRunner& task_runner,
                                const base::Location& location,
                                base::OnceClosure task) {
   DCHECK(task_runner.RunsTasksInCurrentSequence());
@@ -144,7 +144,7 @@
   return TaskHandle(runner);
 }
 
-TaskHandle PostDelayedCancellableTask(WebTaskRunner& task_runner,
+TaskHandle PostDelayedCancellableTask(base::SingleThreadTaskRunner& task_runner,
                                       const base::Location& location,
                                       base::OnceClosure task,
                                       TimeDelta delay) {
diff --git a/third_party/WebKit/Source/platform/WebTaskRunner.h b/third_party/WebKit/Source/platform/WebTaskRunner.h
index c4e4767..dcc0aae 100644
--- a/third_party/WebKit/Source/platform/WebTaskRunner.h
+++ b/third_party/WebKit/Source/platform/WebTaskRunner.h
@@ -17,13 +17,8 @@
 
 namespace blink {
 
-// TODO(yutak): WebTaskRunner is soon to be deprecated. Use
-// base::SingleThreadTaskRunner instead. See: http://crbug.com/794845
-using WebTaskRunner = base::SingleThreadTaskRunner;
-
-// TaskHandle is associated to a task posted by
-// WebTaskRunner::postCancellableTask or
-// WebTaskRunner::postCancellableDelayedTask and cancels the associated task on
+// TaskHandle is associated to a task posted by PostCancellableTask() or
+// PostCancellableDelayedTask() and cancels the associated task on
 // TaskHandle::cancel() call or on TaskHandle destruction.
 class BLINK_PLATFORM_EXPORT TaskHandle {
  public:
@@ -49,9 +44,11 @@
 
  private:
   friend BLINK_PLATFORM_EXPORT WARN_UNUSED_RESULT TaskHandle
-  PostCancellableTask(WebTaskRunner&, const base::Location&, base::OnceClosure);
+  PostCancellableTask(base::SingleThreadTaskRunner&,
+                      const base::Location&,
+                      base::OnceClosure);
   friend BLINK_PLATFORM_EXPORT WARN_UNUSED_RESULT TaskHandle
-  PostDelayedCancellableTask(WebTaskRunner&,
+  PostDelayedCancellableTask(base::SingleThreadTaskRunner&,
                              const base::Location&,
                              base::OnceClosure,
                              TimeDelta delay);
@@ -61,20 +58,23 @@
 };
 
 // For cross-thread posting. Can be called from any thread.
-BLINK_PLATFORM_EXPORT void PostCrossThreadTask(WebTaskRunner&,
+BLINK_PLATFORM_EXPORT void PostCrossThreadTask(base::SingleThreadTaskRunner&,
                                                const base::Location&,
                                                CrossThreadClosure);
-BLINK_PLATFORM_EXPORT void PostDelayedCrossThreadTask(WebTaskRunner&,
-                                                      const base::Location&,
-                                                      CrossThreadClosure,
-                                                      TimeDelta delay);
+BLINK_PLATFORM_EXPORT void PostDelayedCrossThreadTask(
+    base::SingleThreadTaskRunner&,
+    const base::Location&,
+    CrossThreadClosure,
+    TimeDelta delay);
 
 // For same-thread cancellable task posting. Returns a TaskHandle object for
 // cancellation.
 BLINK_PLATFORM_EXPORT WARN_UNUSED_RESULT TaskHandle
-PostCancellableTask(WebTaskRunner&, const base::Location&, base::OnceClosure);
+PostCancellableTask(base::SingleThreadTaskRunner&,
+                    const base::Location&,
+                    base::OnceClosure);
 BLINK_PLATFORM_EXPORT WARN_UNUSED_RESULT TaskHandle
-PostDelayedCancellableTask(WebTaskRunner&,
+PostDelayedCancellableTask(base::SingleThreadTaskRunner&,
                            const base::Location&,
                            base::OnceClosure,
                            TimeDelta delay);
diff --git a/third_party/WebKit/Source/platform/WebThreadSupportingGC.h b/third_party/WebKit/Source/platform/WebThreadSupportingGC.h
index dadb634..05b6562e 100644
--- a/third_party/WebKit/Source/platform/WebThreadSupportingGC.h
+++ b/third_party/WebKit/Source/platform/WebThreadSupportingGC.h
@@ -6,9 +6,11 @@
 #define WebThreadSupportingGC_h
 
 #include <memory>
+#include "platform/WebTaskRunner.h"
 #include "platform/heap/GCTaskRunner.h"
 #include "platform/wtf/Allocator.h"
 #include "platform/wtf/Noncopyable.h"
+#include "platform/wtf/Time.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebThread.h"
 
diff --git a/third_party/WebKit/Source/platform/audio/PushPullFIFOTest.cpp b/third_party/WebKit/Source/platform/audio/PushPullFIFOTest.cpp
index b945d33..51d5e986 100644
--- a/third_party/WebKit/Source/platform/audio/PushPullFIFOTest.cpp
+++ b/third_party/WebKit/Source/platform/audio/PushPullFIFOTest.cpp
@@ -7,7 +7,6 @@
 #include <memory>
 #include <vector>
 #include "platform/CrossThreadFunctional.h"
-#include "platform/WebTaskRunner.h"
 #include "platform/audio/AudioUtilities.h"
 #include "platform/testing/TestingPlatformSupport.h"
 #include "platform/wtf/Functional.h"
diff --git a/third_party/WebKit/Source/platform/bindings/Microtask.h b/third_party/WebKit/Source/platform/bindings/Microtask.h
index 4ebde30f..6a128af 100644
--- a/third_party/WebKit/Source/platform/bindings/Microtask.h
+++ b/third_party/WebKit/Source/platform/bindings/Microtask.h
@@ -32,7 +32,6 @@
 #define Microtask_h
 
 #include "platform/PlatformExport.h"
-#include "platform/WebTaskRunner.h"
 #include "platform/wtf/Allocator.h"
 #include "platform/wtf/Functional.h"
 #include "v8/include/v8.h"
diff --git a/third_party/WebKit/Source/platform/bindings/ScriptWrappable.h b/third_party/WebKit/Source/platform/bindings/ScriptWrappable.h
index 1206845c..dfda278b 100644
--- a/third_party/WebKit/Source/platform/bindings/ScriptWrappable.h
+++ b/third_party/WebKit/Source/platform/bindings/ScriptWrappable.h
@@ -141,8 +141,7 @@
   }
 
   bool SetReturnValue(v8::ReturnValue<v8::Value> return_value) {
-    v8::Isolate* isolate = return_value.GetIsolate();
-    return_value.Set(main_world_wrapper_.Get().Get(isolate));
+    return_value.Set(main_world_wrapper_.Get());
     return ContainsWrapper();
   }
 
diff --git a/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitor.h b/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitor.h
index 8c316ed..b959d8f7 100644
--- a/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitor.h
+++ b/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitor.h
@@ -39,7 +39,6 @@
   inline void TraceTrait<ClassName>::TraceMarkedWrapper(             \
       const ScriptWrappableVisitor* visitor, const void* t) {        \
     const ClassName* traceable = ToWrapperTracingType(t);            \
-    DCHECK(GetHeapObjectHeader(traceable)->IsWrapperHeaderMarked()); \
     traceable->TraceWrappers(visitor);                               \
   }
 
diff --git a/third_party/WebKit/Source/platform/blob/BlobData.cpp b/third_party/WebKit/Source/platform/blob/BlobData.cpp
index b39b669..7c670dd 100644
--- a/third_party/WebKit/Source/platform/blob/BlobData.cpp
+++ b/third_party/WebKit/Source/platform/blob/BlobData.cpp
@@ -32,6 +32,7 @@
 
 #include <memory>
 #include "base/memory/scoped_refptr.h"
+#include "base/single_thread_task_runner.h"
 #include "mojo/public/cpp/bindings/strong_binding.h"
 #include "platform/CrossThreadFunctional.h"
 #include "platform/Histogram.h"
@@ -291,7 +292,7 @@
     auto provider = std::make_unique<BlobBytesProvider>();
     last_bytes_provider_ = provider.get();
 
-    scoped_refptr<WebTaskRunner> file_runner =
+    scoped_refptr<base::SingleThreadTaskRunner> file_runner =
         Platform::Current()->FileTaskRunner();
     if (file_runner) {
       // TODO(mek): Considering binding BytesProvider on the IO thread
diff --git a/third_party/WebKit/Source/platform/blob/BlobRegistry.cpp b/third_party/WebKit/Source/platform/blob/BlobRegistry.cpp
index 4fc47d903..44853c5 100644
--- a/third_party/WebKit/Source/platform/blob/BlobRegistry.cpp
+++ b/third_party/WebKit/Source/platform/blob/BlobRegistry.cpp
@@ -34,7 +34,6 @@
 #include "base/location.h"
 #include "base/memory/scoped_refptr.h"
 #include "platform/CrossThreadFunctional.h"
-#include "platform/WebTaskRunner.h"
 #include "platform/blob/BlobData.h"
 #include "platform/blob/BlobURL.h"
 #include "platform/weborigin/SecurityOrigin.h"
diff --git a/third_party/WebKit/Source/platform/exported/Platform.cpp b/third_party/WebKit/Source/platform/exported/Platform.cpp
index ff49b78cb..e6c1905 100644
--- a/third_party/WebKit/Source/platform/exported/Platform.cpp
+++ b/third_party/WebKit/Source/platform/exported/Platform.cpp
@@ -32,6 +32,7 @@
 
 #include <memory>
 
+#include "base/single_thread_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/trace_event/memory_dump_manager.h"
 #include "platform/Histogram.h"
@@ -39,6 +40,8 @@
 #include "platform/Language.h"
 #include "platform/MemoryCoordinator.h"
 #include "platform/PartitionAllocMemoryDumpProvider.h"
+#include "platform/WebTaskRunner.h"
+#include "platform/exported/WebClipboardImpl.h"
 #include "platform/font_family_names.h"
 #include "platform/fonts/FontCacheMemoryDumpProvider.h"
 #include "platform/heap/BlinkGCMemoryDumpProvider.h"
@@ -64,7 +67,6 @@
 #include "public/platform/modules/serviceworker/WebServiceWorkerCacheStorage.h"
 #include "public/platform/modules/webmidi/WebMIDIAccessor.h"
 #include "services/service_manager/public/cpp/connector.h"
-#include "third_party/WebKit/Source/platform/exported/WebClipboardImpl.h"
 #include "third_party/WebKit/common/origin_trials/trial_policy.h"
 
 namespace blink {
@@ -184,7 +186,7 @@
   return main_thread_;
 }
 
-WebTaskRunner* Platform::FileTaskRunner() const {
+base::SingleThreadTaskRunner* Platform::FileTaskRunner() const {
   return file_thread_ ? file_thread_->GetWebTaskRunner() : nullptr;
 }
 
diff --git a/third_party/WebKit/Source/platform/fonts/mac/FontCacheMac.mm b/third_party/WebKit/Source/platform/fonts/mac/FontCacheMac.mm
index 7908f124..b55abfd 100644
--- a/third_party/WebKit/Source/platform/fonts/mac/FontCacheMac.mm
+++ b/third_party/WebKit/Source/platform/fonts/mac/FontCacheMac.mm
@@ -33,7 +33,6 @@
 #include <memory>
 #include "base/location.h"
 #include "platform/LayoutTestSupport.h"
-#include "platform/WebTaskRunner.h"
 #include "platform/font_family_names.h"
 #include "platform/fonts/FontDescription.h"
 #include "platform/fonts/FontFaceCreationParams.h"
diff --git a/third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.h b/third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.h
index 5c05a21..fdc903b4 100644
--- a/third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.h
+++ b/third_party/WebKit/Source/platform/graphics/AcceleratedStaticBitmapImage.h
@@ -8,12 +8,11 @@
 #include <memory>
 
 #include "base/memory/weak_ptr.h"
+#include "base/single_thread_task_runner.h"
 #include "base/threading/thread_checker.h"
-#include "platform/WebTaskRunner.h"
 #include "platform/graphics/StaticBitmapImage.h"
 #include "platform/graphics/TextureHolder.h"
 
-
 class GrContext;
 
 namespace blink {
@@ -117,7 +116,7 @@
 
   // For RetainOriginalSkImageForCopyOnWrite()
   sk_sp<SkImage> original_skia_image_;
-  scoped_refptr<WebTaskRunner> original_skia_image_task_runner_;
+  scoped_refptr<base::SingleThreadTaskRunner> original_skia_image_task_runner_;
   PlatformThreadId original_skia_image_thread_id_;
   base::WeakPtr<WebGraphicsContext3DProviderWrapper>
       original_skia_image_context_provider_wrapper_;
diff --git a/third_party/WebKit/Source/platform/graphics/BitmapImage.h b/third_party/WebKit/Source/platform/graphics/BitmapImage.h
index e0c0b0a..df35612 100644
--- a/third_party/WebKit/Source/platform/graphics/BitmapImage.h
+++ b/third_party/WebKit/Source/platform/graphics/BitmapImage.h
@@ -105,7 +105,8 @@
   void SetDecoderForTesting(std::unique_ptr<DeferredImageDecoder> decoder) {
     decoder_ = std::move(decoder);
   }
-  void SetTaskRunnerForTesting(scoped_refptr<WebTaskRunner> task_runner) {
+  void SetTaskRunnerForTesting(
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
     task_runner_ = task_runner;
   }
 
@@ -232,7 +233,7 @@
   PaintImage::AnimationSequenceId reset_animation_sequence_id_ = 0;
 
   base::TickClock* clock_;
-  scoped_refptr<WebTaskRunner> task_runner_;
+  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
 
   // Value used in UMA tracking for the number of animation frames skipped
   // during catch-up.
diff --git a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
index 0b5e37b..8d398b9 100644
--- a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
+++ b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
@@ -28,10 +28,10 @@
 #include <memory>
 #include "base/location.h"
 #include "base/memory/ptr_util.h"
+#include "base/single_thread_task_runner.h"
 #include "components/viz/common/resources/transferable_resource.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
 #include "platform/Histogram.h"
-#include "platform/WebTaskRunner.h"
 #include "platform/graphics/CanvasHeuristicParameters.h"
 #include "platform/graphics/CanvasMetrics.h"
 #include "platform/graphics/CanvasResource.h"
diff --git a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridgeTest.cpp b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridgeTest.cpp
index 1fb8406..d4bfe6a6 100644
--- a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridgeTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridgeTest.cpp
@@ -28,6 +28,7 @@
 #include "base/location.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/run_loop.h"
+#include "base/single_thread_task_runner.h"
 #include "build/build_config.h"
 #include "cc/test/skia_common.h"
 #include "cc/test/stub_decode_cache.h"
@@ -38,7 +39,6 @@
 #include "gpu/command_buffer/common/capabilities.h"
 #include "platform/CrossThreadFunctional.h"
 #include "platform/WaitableEvent.h"
-#include "platform/WebTaskRunner.h"
 #include "platform/graphics/CanvasResourceHost.h"
 #include "platform/graphics/CanvasResourceProvider.h"
 #include "platform/graphics/StaticBitmapImage.h"
diff --git a/third_party/WebKit/Source/platform/graphics/MailboxTextureHolder.h b/third_party/WebKit/Source/platform/graphics/MailboxTextureHolder.h
index 8319494..0405ba7 100644
--- a/third_party/WebKit/Source/platform/graphics/MailboxTextureHolder.h
+++ b/third_party/WebKit/Source/platform/graphics/MailboxTextureHolder.h
@@ -6,8 +6,8 @@
 #define MailboxTextureHolder_h
 
 #include "base/memory/weak_ptr.h"
+#include "base/single_thread_task_runner.h"
 #include "platform/PlatformExport.h"
-#include "platform/WebTaskRunner.h"
 #include "platform/graphics/GraphicsTypes.h"
 #include "platform/graphics/TextureHolder.h"
 #include "platform/graphics/WebGraphicsContext3DProviderWrapper.h"
@@ -52,7 +52,7 @@
   unsigned texture_id_;
   IntSize size_;
   bool is_converted_from_skia_texture_;
-  scoped_refptr<WebTaskRunner> texture_thread_task_runner_;
+  scoped_refptr<base::SingleThreadTaskRunner> texture_thread_task_runner_;
   PlatformThreadId thread_id_;
   bool did_issue_ordering_barrier_ = false;
 };
diff --git a/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcher.h b/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcher.h
index d308716..bde027d3 100644
--- a/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcher.h
+++ b/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcher.h
@@ -8,7 +8,6 @@
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
 #include "platform/PlatformExport.h"
-#include "platform/WebTaskRunner.h"
 #include "platform/geometry/IntRect.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.cpp b/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.cpp
index d8dc12d..ffbc3373 100644
--- a/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.cpp
+++ b/third_party/WebKit/Source/platform/graphics/OffscreenCanvasFrameDispatcherImpl.cpp
@@ -5,6 +5,7 @@
 #include "platform/graphics/OffscreenCanvasFrameDispatcherImpl.h"
 
 #include <memory>
+#include "base/single_thread_task_runner.h"
 #include "components/viz/common/quads/compositor_frame.h"
 #include "components/viz/common/quads/texture_draw_quad.h"
 #include "components/viz/common/resources/resource_format.h"
@@ -71,7 +72,7 @@
 
 void UpdatePlaceholderImage(
     base::WeakPtr<OffscreenCanvasFrameDispatcher> dispatcher,
-    scoped_refptr<WebTaskRunner> task_runner,
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
     int placeholder_canvas_id,
     scoped_refptr<blink::StaticBitmapImage> image,
     unsigned resource_id) {
@@ -118,7 +119,7 @@
 void OffscreenCanvasFrameDispatcherImpl::PostImageToPlaceholder(
     scoped_refptr<StaticBitmapImage> image,
     unsigned resource_id) {
-  scoped_refptr<WebTaskRunner> dispatcher_task_runner =
+  scoped_refptr<base::SingleThreadTaskRunner> dispatcher_task_runner =
       Platform::Current()->CurrentThread()->GetWebTaskRunner();
 
   PostCrossThreadTask(
diff --git a/third_party/WebKit/Source/platform/graphics/OffscreenCanvasPlaceholder.cpp b/third_party/WebKit/Source/platform/graphics/OffscreenCanvasPlaceholder.cpp
index 3a9dfef4..36dbc1d 100644
--- a/third_party/WebKit/Source/platform/graphics/OffscreenCanvasPlaceholder.cpp
+++ b/third_party/WebKit/Source/platform/graphics/OffscreenCanvasPlaceholder.cpp
@@ -4,6 +4,7 @@
 
 #include "platform/graphics/OffscreenCanvasPlaceholder.h"
 
+#include "base/single_thread_task_runner.h"
 #include "platform/CrossThreadFunctional.h"
 #include "platform/WebTaskRunner.h"
 #include "platform/graphics/OffscreenCanvasFrameDispatcher.h"
@@ -72,7 +73,7 @@
 void OffscreenCanvasPlaceholder::SetPlaceholderFrame(
     scoped_refptr<StaticBitmapImage> new_frame,
     base::WeakPtr<OffscreenCanvasFrameDispatcher> dispatcher,
-    scoped_refptr<WebTaskRunner> task_runner,
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
     unsigned resource_id) {
   DCHECK(IsPlaceholderRegistered());
   DCHECK(new_frame);
diff --git a/third_party/WebKit/Source/platform/graphics/OffscreenCanvasPlaceholder.h b/third_party/WebKit/Source/platform/graphics/OffscreenCanvasPlaceholder.h
index 0f489d6..b4d0418f 100644
--- a/third_party/WebKit/Source/platform/graphics/OffscreenCanvasPlaceholder.h
+++ b/third_party/WebKit/Source/platform/graphics/OffscreenCanvasPlaceholder.h
@@ -8,8 +8,8 @@
 #include <memory>
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
+#include "base/single_thread_task_runner.h"
 #include "platform/PlatformExport.h"
-#include "platform/WebTaskRunner.h"
 
 namespace blink {
 
@@ -23,7 +23,7 @@
   virtual void SetPlaceholderFrame(
       scoped_refptr<StaticBitmapImage>,
       base::WeakPtr<OffscreenCanvasFrameDispatcher>,
-      scoped_refptr<WebTaskRunner>,
+      scoped_refptr<base::SingleThreadTaskRunner>,
       unsigned resource_id);
   void ReleasePlaceholderFrame();
 
@@ -47,7 +47,7 @@
 
   scoped_refptr<StaticBitmapImage> placeholder_frame_;
   base::WeakPtr<OffscreenCanvasFrameDispatcher> frame_dispatcher_;
-  scoped_refptr<WebTaskRunner> frame_dispatcher_task_runner_;
+  scoped_refptr<base::SingleThreadTaskRunner> frame_dispatcher_task_runner_;
   unsigned placeholder_frame_resource_id_ = 0;
 
   enum {
diff --git a/third_party/WebKit/Source/platform/graphics/TextureHolder.h b/third_party/WebKit/Source/platform/graphics/TextureHolder.h
index 19be985..7eccb72 100644
--- a/third_party/WebKit/Source/platform/graphics/TextureHolder.h
+++ b/third_party/WebKit/Source/platform/graphics/TextureHolder.h
@@ -68,11 +68,11 @@
       : context_provider_wrapper_(std::move(context_provider_wrapper)) {}
 
  private:
-  // Keep a clone of the WebTaskRunner. This is to handle the case where the
-  // AcceleratedStaticBitmapImage was created on one thread and transferred to
-  // another thread, and the original thread gone out of scope, and that we need
-  // to clear the resouces associated with that AcceleratedStaticBitmapImage on
-  // the original thread.
+  // Keep a clone of the SingleThreadTaskRunner. This is to handle the case
+  // where the AcceleratedStaticBitmapImage was created on one thread and
+  // transferred to another thread, and the original thread gone out of scope,
+  // and that we need to clear the resouces associated with that
+  // AcceleratedStaticBitmapImage on the original thread.
   base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper_;
   bool is_abandoned_ = false;
 };
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContext.cpp b/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContext.cpp
index ed10e59..dc8887ab 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContext.cpp
+++ b/third_party/WebKit/Source/platform/graphics/gpu/SharedGpuContext.cpp
@@ -4,6 +4,7 @@
 
 #include "platform/graphics/gpu/SharedGpuContext.h"
 
+#include "base/single_thread_task_runner.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
 #include "gpu/config/gpu_driver_bug_workaround_type.h"
 #include "gpu/config/gpu_feature_info.h"
@@ -121,7 +122,7 @@
     // SharedGpuContext encasulates the context provider: so we only have to do
     // this once per thread.
     WaitableEvent waitable_event;
-    scoped_refptr<WebTaskRunner> task_runner =
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner =
         Platform::Current()->MainThread()->GetWebTaskRunner();
     PostCrossThreadTask(
         *task_runner, FROM_HERE,
diff --git a/third_party/WebKit/Source/platform/graphics/test/FakeScrollableArea.h b/third_party/WebKit/Source/platform/graphics/test/FakeScrollableArea.h
index 8b62e01..c5653bf 100644
--- a/third_party/WebKit/Source/platform/graphics/test/FakeScrollableArea.h
+++ b/third_party/WebKit/Source/platform/graphics/test/FakeScrollableArea.h
@@ -56,7 +56,7 @@
     return FlooredIntSize(scroll_offset_);
   }
 
-  scoped_refptr<WebTaskRunner> GetTimerTaskRunner() const final {
+  scoped_refptr<base::SingleThreadTaskRunner> GetTimerTaskRunner() const final {
     if (!timer_task_runner_) {
       timer_task_runner_ = blink::scheduler::CreateWebTaskRunnerForTesting();
     }
@@ -73,7 +73,7 @@
 
  private:
   ScrollOffset scroll_offset_;
-  mutable scoped_refptr<WebTaskRunner> timer_task_runner_;
+  mutable scoped_refptr<base::SingleThreadTaskRunner> timer_task_runner_;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/heap/GCTaskRunner.h b/third_party/WebKit/Source/platform/heap/GCTaskRunner.h
index 6eb8b8e..824e5ca 100644
--- a/third_party/WebKit/Source/platform/heap/GCTaskRunner.h
+++ b/third_party/WebKit/Source/platform/heap/GCTaskRunner.h
@@ -34,7 +34,6 @@
 #include <memory>
 #include "base/location.h"
 #include "platform/CrossThreadFunctional.h"
-#include "platform/WebTaskRunner.h"
 #include "platform/heap/ThreadState.h"
 #include "platform/wtf/PtrUtil.h"
 #include "public/platform/WebThread.h"
diff --git a/third_party/WebKit/Source/platform/heap/HeapPage.cpp b/third_party/WebKit/Source/platform/heap/HeapPage.cpp
index 63e72a8..dfe76ca8 100644
--- a/third_party/WebKit/Source/platform/heap/HeapPage.cpp
+++ b/third_party/WebKit/Source/platform/heap/HeapPage.cpp
@@ -700,78 +700,6 @@
   memset(&object_start_bit_map_, 0, kReservedForBitmap);
 }
 
-bool NormalPageArena::Coalesce() {
-  // Don't coalesce arenas if there are not enough promptly freed entries
-  // to be coalesced.
-  //
-  // FIXME: This threshold is determined just to optimize blink_perf
-  // benchmarks. Coalescing is very sensitive to the threashold and
-  // we need further investigations on the coalescing scheme.
-  if (promptly_freed_size_ < 1024 * 1024)
-    return false;
-
-  if (GetThreadState()->SweepForbidden())
-    return false;
-
-  DCHECK(!HasCurrentAllocationArea());
-  TRACE_EVENT0("blink_gc", "BaseArena::coalesce");
-
-  double coalesce_start_time = WTF::CurrentTimeTicksInMilliseconds();
-
-  // Rebuild free lists.
-  free_list_.Clear();
-
-  for (NormalPage* page = static_cast<NormalPage*>(first_page_); page;
-       page = static_cast<NormalPage*>(page->Next())) {
-    page->object_start_bit_map()->Clear();
-    Address start_of_gap = page->Payload();
-    for (Address header_address = start_of_gap;
-         header_address < page->PayloadEnd();) {
-      HeapObjectHeader* header =
-          reinterpret_cast<HeapObjectHeader*>(header_address);
-      size_t size = header->size();
-      DCHECK_GT(size, 0u);
-      DCHECK_LT(size, BlinkPagePayloadSize());
-
-      if (header->IsFree()) {
-        // Zero the memory in the free list header to maintain the
-        // invariant that memory on the free list is zero filled.
-        // The rest of the memory is already on the free list and is
-        // therefore already zero filled.
-        SET_MEMORY_INACCESSIBLE(header_address, size < sizeof(FreeListEntry)
-                                                    ? size
-                                                    : sizeof(FreeListEntry));
-        CHECK_MEMORY_INACCESSIBLE(header_address, size);
-        header_address += size;
-        continue;
-      }
-      if (start_of_gap != header_address)
-        AddToFreeList(start_of_gap, header_address - start_of_gap);
-
-      page->object_start_bit_map()->SetBit(header_address);
-      header_address += size;
-      start_of_gap = header_address;
-    }
-
-    if (start_of_gap != page->PayloadEnd())
-      AddToFreeList(start_of_gap, page->PayloadEnd() - start_of_gap);
-
-    page->VerifyObjectStartBitmapIsConsistentWithPayload();
-  }
-
-  // After coalescing we do not have promptly freed objects.
-  promptly_freed_size_ = 0;
-
-  double coalesce_time =
-      WTF::CurrentTimeTicksInMilliseconds() - coalesce_start_time;
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(
-      CustomCountHistogram, time_for_heap_coalesce_histogram,
-      ("BlinkGC.TimeForCoalesce", 1, 10 * 1000, 50));
-  time_for_heap_coalesce_histogram.Count(coalesce_time);
-
-  return true;
-}
-
 void NormalPageArena::PromptlyFreeObject(HeapObjectHeader* header) {
   DCHECK(!GetThreadState()->SweepForbidden());
   Address address = reinterpret_cast<Address>(header);
@@ -979,24 +907,16 @@
   if (result)
     return result;
 
-  // 5. Coalesce promptly freed areas and then try to allocate from a free
-  // list.
-  if (Coalesce()) {
-    result = AllocateFromFreeList(allocation_size, gc_info_index);
-    if (result)
-      return result;
-  }
-
-  // 6. Complete sweeping.
+  // 5. Complete sweeping.
   GetThreadState()->CompleteSweep();
 
-  // 7. Check if we should trigger a GC.
+  // 6. Check if we should trigger a GC.
   GetThreadState()->ScheduleGCIfNeeded();
 
-  // 8. Add a new page to this heap.
+  // 7. Add a new page to this heap.
   AllocatePage();
 
-  // 9. Try to allocate from a free list. This allocation must succeed.
+  // 8. Try to allocate from a free list. This allocation must succeed.
   result = AllocateFromFreeList(allocation_size, gc_info_index);
   CHECK(result);
   return result;
@@ -1175,8 +1095,8 @@
 
 #if DCHECK_IS_ON() || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER)
   // The following logic delays reusing free lists for (at least) one GC
-  // cycle or coalescing. This is helpful to detect use-after-free errors
-  // that could be caused by lazy sweeping etc.
+  // cycle. This is helpful to detect use-after-free errors that could be caused
+  // by lazy sweeping etc.
   size_t allowed_count = 0;
   size_t forbidden_count = 0;
   GetAllowedAndForbiddenCounts(address, size, allowed_count, forbidden_count);
diff --git a/third_party/WebKit/Source/platform/heap/HeapPage.h b/third_party/WebKit/Source/platform/heap/HeapPage.h
index 5e23003..5d08e64 100644
--- a/third_party/WebKit/Source/platform/heap/HeapPage.h
+++ b/third_party/WebKit/Source/platform/heap/HeapPage.h
@@ -849,7 +849,6 @@
 
   void FreePage(NormalPage*);
 
-  bool Coalesce();
   void PromptlyFreeObject(HeapObjectHeader*);
   void PromptlyFreeObjectInFreeList(HeapObjectHeader*, size_t);
   bool ExpandObject(HeapObjectHeader*, size_t);
diff --git a/third_party/WebKit/Source/platform/heap/TraceTraits.h b/third_party/WebKit/Source/platform/heap/TraceTraits.h
index f77aac88..9d2732b 100644
--- a/third_party/WebKit/Source/platform/heap/TraceTraits.h
+++ b/third_party/WebKit/Source/platform/heap/TraceTraits.h
@@ -251,7 +251,6 @@
 void TraceTrait<T>::TraceMarkedWrapper(const ScriptWrappableVisitor* visitor,
                                        const void* t) {
   const T* traceable = ToWrapperTracingType(t);
-  DCHECK(GetHeapObjectHeader(traceable)->IsWrapperHeaderMarked());
   AdjustAndMarkTrait<T>::TraceMarkedWrapper(visitor, traceable);
 }
 
diff --git a/third_party/WebKit/public/platform/CORSStatus.h b/third_party/WebKit/Source/platform/loader/cors/CORSStatus.h
similarity index 100%
rename from third_party/WebKit/public/platform/CORSStatus.h
rename to third_party/WebKit/Source/platform/loader/cors/CORSStatus.h
diff --git a/third_party/WebKit/Source/platform/loader/fetch/BufferingDataPipeWriter.cpp b/third_party/WebKit/Source/platform/loader/fetch/BufferingDataPipeWriter.cpp
index 808e062..85a3773a 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/BufferingDataPipeWriter.cpp
+++ b/third_party/WebKit/Source/platform/loader/fetch/BufferingDataPipeWriter.cpp
@@ -16,7 +16,7 @@
 
 BufferingDataPipeWriter::BufferingDataPipeWriter(
     mojo::ScopedDataPipeProducerHandle handle,
-    WebTaskRunner* runner)
+    base::SingleThreadTaskRunner* runner)
     : handle_(std::move(handle)),
       watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL, runner) {
   watcher_.Watch(
diff --git a/third_party/WebKit/Source/platform/loader/fetch/BufferingDataPipeWriter.h b/third_party/WebKit/Source/platform/loader/fetch/BufferingDataPipeWriter.h
index ee0fbd0..a74a87cf 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/BufferingDataPipeWriter.h
+++ b/third_party/WebKit/Source/platform/loader/fetch/BufferingDataPipeWriter.h
@@ -5,10 +5,10 @@
 #ifndef BufferingDataPipeWriter_h
 #define BufferingDataPipeWriter_h
 
+#include "base/single_thread_task_runner.h"
 #include "mojo/public/cpp/system/data_pipe.h"
 #include "mojo/public/cpp/system/simple_watcher.h"
 #include "platform/PlatformExport.h"
-#include "platform/WebTaskRunner.h"
 #include "platform/wtf/Deque.h"
 #include "platform/wtf/Vector.h"
 
@@ -18,7 +18,8 @@
 // result, it is possible for a caller to miss write failures.
 class PLATFORM_EXPORT BufferingDataPipeWriter {
  public:
-  BufferingDataPipeWriter(mojo::ScopedDataPipeProducerHandle, WebTaskRunner*);
+  BufferingDataPipeWriter(mojo::ScopedDataPipeProducerHandle,
+                          base::SingleThreadTaskRunner*);
 
   // Writes buffer[0:num_bytes] to the data pipe. Returns true if there is no
   // error.
diff --git a/third_party/WebKit/Source/platform/loader/fetch/FetchContext.h b/third_party/WebKit/Source/platform/loader/fetch/FetchContext.h
index 213ab28c..483e8cd 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/FetchContext.h
+++ b/third_party/WebKit/Source/platform/loader/fetch/FetchContext.h
@@ -231,7 +231,7 @@
 
   virtual std::unique_ptr<WebURLLoader> CreateURLLoader(
       const ResourceRequest&,
-      scoped_refptr<WebTaskRunner>) {
+      scoped_refptr<base::SingleThreadTaskRunner>) {
     NOTREACHED();
     return nullptr;
   }
@@ -251,10 +251,10 @@
 
   // Returns a task runner intended for loading tasks. Should work even in a
   // worker context, where WebFrameScheduler doesn't exist, but the returned
-  // WebTaskRunner will not work after the context detaches (after Detach() is
-  // called, this will return a generic timer suitable for post-detach actions
-  // like keepalive requests.
-  virtual scoped_refptr<WebTaskRunner> GetLoadingTaskRunner() {
+  // base::SingleThreadTaskRunner will not work after the context detaches
+  // (after Detach() is called, this will return a generic timer suitable for
+  // post-detach actions like keepalive requests.
+  virtual scoped_refptr<base::SingleThreadTaskRunner> GetLoadingTaskRunner() {
     return Platform::Current()->CurrentThread()->GetWebTaskRunner();
   }
 
diff --git a/third_party/WebKit/Source/platform/loader/fetch/RawResource.cpp b/third_party/WebKit/Source/platform/loader/fetch/RawResource.cpp
index be4d5f2..2a0dab2 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/RawResource.cpp
+++ b/third_party/WebKit/Source/platform/loader/fetch/RawResource.cpp
@@ -246,7 +246,7 @@
 }
 
 bool RawResource::MatchPreload(const FetchParameters& params,
-                               WebTaskRunner* task_runner) {
+                               base::SingleThreadTaskRunner* task_runner) {
   if (!Resource::MatchPreload(params, task_runner))
     return false;
 
diff --git a/third_party/WebKit/Source/platform/loader/fetch/RawResource.h b/third_party/WebKit/Source/platform/loader/fetch/RawResource.h
index 605245e8..1dd5fa42 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/RawResource.h
+++ b/third_party/WebKit/Source/platform/loader/fetch/RawResource.h
@@ -108,7 +108,8 @@
                    unsigned long long total_bytes_to_be_sent) override;
   void DidDownloadData(int) override;
   void ReportResourceTimingToClients(const ResourceTimingInfo&) override;
-  bool MatchPreload(const FetchParameters&, WebTaskRunner*) override;
+  bool MatchPreload(const FetchParameters&,
+                    base::SingleThreadTaskRunner*) override;
   void NotifyFinished() override;
 
   // Used for preload matching.
diff --git a/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp b/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp
index fa980a8..addbf0a 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp
+++ b/third_party/WebKit/Source/platform/loader/fetch/Resource.cpp
@@ -30,11 +30,11 @@
 #include <cassert>
 #include <memory>
 
+#include "base/single_thread_task_runner.h"
 #include "build/build_config.h"
 #include "platform/Histogram.h"
 #include "platform/InstanceCounters.h"
 #include "platform/SharedBuffer.h"
-#include "platform/WebTaskRunner.h"
 #include "platform/instrumentation/tracing/TraceEvent.h"
 #include "platform/loader/fetch/CachedMetadata.h"
 #include "platform/loader/fetch/FetchParameters.h"
@@ -415,7 +415,7 @@
 }
 
 void Resource::TriggerNotificationForFinishObservers(
-    WebTaskRunner* task_runner) {
+    base::SingleThreadTaskRunner* task_runner) {
   if (finish_observers_.IsEmpty())
     return;
 
@@ -437,7 +437,7 @@
 }
 
 void Resource::FinishAsError(const ResourceError& error,
-                             WebTaskRunner* task_runner) {
+                             base::SingleThreadTaskRunner* task_runner) {
   error_ = error;
   is_revalidating_ = false;
 
@@ -454,7 +454,8 @@
   NotifyFinished();
 }
 
-void Resource::Finish(double load_finish_time, WebTaskRunner* task_runner) {
+void Resource::Finish(double load_finish_time,
+                      base::SingleThreadTaskRunner* task_runner) {
   DCHECK(!is_revalidating_);
   load_finish_time_ = load_finish_time;
   if (!ErrorOccurred())
@@ -701,7 +702,8 @@
   }
 }
 
-void Resource::AddClient(ResourceClient* client, WebTaskRunner* task_runner) {
+void Resource::AddClient(ResourceClient* client,
+                         base::SingleThreadTaskRunner* task_runner) {
   CHECK(!is_add_remove_client_prohibited_);
 
   WillAddClientOrObserver();
@@ -751,7 +753,7 @@
 }
 
 void Resource::AddFinishObserver(ResourceFinishObserver* client,
-                                 WebTaskRunner* task_runner) {
+                                 base::SingleThreadTaskRunner* task_runner) {
   CHECK(!is_add_remove_client_prohibited_);
   DCHECK(!finish_observers_.Contains(client));
 
@@ -1093,7 +1095,8 @@
   is_unused_preload_ = true;
 }
 
-bool Resource::MatchPreload(const FetchParameters& params, WebTaskRunner*) {
+bool Resource::MatchPreload(const FetchParameters& params,
+                            base::SingleThreadTaskRunner*) {
   DCHECK(is_unused_preload_);
   is_unused_preload_ = false;
 
diff --git a/third_party/WebKit/Source/platform/loader/fetch/Resource.h b/third_party/WebKit/Source/platform/loader/fetch/Resource.h
index 9f71669..ee738a61 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/Resource.h
+++ b/third_party/WebKit/Source/platform/loader/fetch/Resource.h
@@ -25,6 +25,7 @@
 #define Resource_h
 
 #include <memory>
+#include "base/single_thread_task_runner.h"
 #include "platform/MemoryCoordinator.h"
 #include "platform/PlatformExport.h"
 #include "platform/SharedBuffer.h"
@@ -32,6 +33,7 @@
 #include "platform/WebTaskRunner.h"
 #include "platform/instrumentation/tracing/web_process_memory_dump.h"
 #include "platform/loader/SubresourceIntegrity.h"
+#include "platform/loader/cors/CORSStatus.h"
 #include "platform/loader/fetch/CachedMetadataHandler.h"
 #include "platform/loader/fetch/IntegrityMetadata.h"
 #include "platform/loader/fetch/ResourceError.h"
@@ -50,7 +52,6 @@
 #include "platform/wtf/text/AtomicString.h"
 #include "platform/wtf/text/TextEncoding.h"
 #include "platform/wtf/text/WTFString.h"
-#include "public/platform/CORSStatus.h"
 #include "public/platform/WebDataConsumerHandle.h"
 #include "public/platform/WebScopedVirtualTimePauser.h"
 
@@ -108,7 +109,8 @@
 
   virtual WTF::TextEncoding Encoding() const { return WTF::TextEncoding(); }
   virtual void AppendData(const char*, size_t);
-  virtual void FinishAsError(const ResourceError&, WebTaskRunner*);
+  virtual void FinishAsError(const ResourceError&,
+                             base::SingleThreadTaskRunner*);
 
   void SetLinkPreload(bool is_link_preload) { link_preload_ = is_link_preload; }
   bool IsLinkPreload() const { return link_preload_; }
@@ -152,8 +154,9 @@
 
   // If this Resource is already finished when AddClient is called, the
   // ResourceClient will be notified asynchronously by a task scheduled
-  // on the given WebTaskRunner. Otherwise, the given WebTaskRunner is unused.
-  void AddClient(ResourceClient*, WebTaskRunner*);
+  // on the given base::SingleThreadTaskRunner. Otherwise, the given
+  // base::SingleThreadTaskRunner is unused.
+  void AddClient(ResourceClient*, base::SingleThreadTaskRunner*);
   void RemoveClient(ResourceClient*);
   // Once called, this resource will not be canceled until load finishes
   // even if associated with no client.
@@ -161,8 +164,10 @@
 
   // If this Resource is already finished when AddFinishObserver is called, the
   // ResourceFinishObserver will be notified asynchronously by a task scheduled
-  // on the given WebTaskRunner. Otherwise, the given WebTaskRunner is unused.
-  void AddFinishObserver(ResourceFinishObserver*, WebTaskRunner*);
+  // on the given base::SingleThreadTaskRunner. Otherwise, the given
+  // base::SingleThreadTaskRunner is unused.
+  void AddFinishObserver(ResourceFinishObserver*,
+                         base::SingleThreadTaskRunner*);
   void RemoveFinishObserver(ResourceFinishObserver*);
 
   bool IsUnusedPreload() const { return is_unused_preload_; }
@@ -205,7 +210,7 @@
 
   // Computes the status of an object after loading. Updates the expire date on
   // the cache entry file
-  virtual void Finish(double finish_time, WebTaskRunner*);
+  virtual void Finish(double finish_time, base::SingleThreadTaskRunner*);
   void FinishForTest() { Finish(0.0, nullptr); }
 
   virtual scoped_refptr<const SharedBuffer> ResourceBuffer() const {
@@ -249,7 +254,8 @@
 
   void MarkAsPreload();
   // Returns true if |this| resource is matched with the given parameters.
-  virtual bool MatchPreload(const FetchParameters&, WebTaskRunner*);
+  virtual bool MatchPreload(const FetchParameters&,
+                            base::SingleThreadTaskRunner*);
 
   bool CanReuseRedirectChain() const;
   bool MustRevalidateDueToCacheHeaders() const;
@@ -436,7 +442,7 @@
   void OnPurgeMemory() override;
 
   void CheckResourceIntegrity();
-  void TriggerNotificationForFinishObservers(WebTaskRunner*);
+  void TriggerNotificationForFinishObservers(base::SingleThreadTaskRunner*);
 
   Type type_;
   ResourceStatus status_;
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceClient.h b/third_party/WebKit/Source/platform/loader/fetch/ResourceClient.h
index 2b2168d5..01d111d 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/ResourceClient.h
+++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceClient.h
@@ -91,7 +91,8 @@
   // additional clients.
   friend class CSSFontFaceSrcValue;
 
-  void SetResource(Resource* new_resource, WebTaskRunner* task_runner) {
+  void SetResource(Resource* new_resource,
+                   base::SingleThreadTaskRunner* task_runner) {
     if (new_resource == resource_)
       return;
 
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcherTest.cpp b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcherTest.cpp
index f4fc1b94..1735ac7 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcherTest.cpp
+++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcherTest.cpp
@@ -31,7 +31,6 @@
 #include "platform/loader/fetch/ResourceFetcher.h"
 
 #include <memory>
-#include "platform/WebTaskRunner.h"
 #include "platform/exported/WrappedResourceResponse.h"
 #include "platform/heap/Handle.h"
 #include "platform/heap/HeapAllocator.h"
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceLoader.cpp b/third_party/WebKit/Source/platform/loader/fetch/ResourceLoader.cpp
index 4ac7f4d..721e29d 100644
--- a/third_party/WebKit/Source/platform/loader/fetch/ResourceLoader.cpp
+++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceLoader.cpp
@@ -30,7 +30,6 @@
 #include "platform/loader/fetch/ResourceLoader.h"
 
 #include "platform/SharedBuffer.h"
-#include "platform/WebTaskRunner.h"
 #include "platform/exported/WrappedResourceRequest.h"
 #include "platform/exported/WrappedResourceResponse.h"
 #include "platform/loader/cors/CORS.h"
diff --git a/third_party/WebKit/Source/platform/loader/testing/MockFetchContext.h b/third_party/WebKit/Source/platform/loader/testing/MockFetchContext.h
index 85e4622..e148664 100644
--- a/third_party/WebKit/Source/platform/loader/testing/MockFetchContext.h
+++ b/third_party/WebKit/Source/platform/loader/testing/MockFetchContext.h
@@ -86,7 +86,7 @@
 
   std::unique_ptr<WebURLLoader> CreateURLLoader(
       const ResourceRequest& request,
-      scoped_refptr<WebTaskRunner> task_runner) override {
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner) override {
     if (!url_loader_factory_) {
       url_loader_factory_ =
           Platform::Current()->CreateDefaultURLLoaderFactory();
@@ -104,21 +104,22 @@
     return frame_scheduler_.get();
   }
 
-  scoped_refptr<WebTaskRunner> GetLoadingTaskRunner() override {
+  scoped_refptr<base::SingleThreadTaskRunner> GetLoadingTaskRunner() override {
     return frame_scheduler_->GetTaskRunner(TaskType::kInternalTest);
   }
 
  private:
   class MockFrameScheduler final : public scheduler::FakeWebFrameScheduler {
    public:
-    MockFrameScheduler(scoped_refptr<WebTaskRunner> runner)
+    MockFrameScheduler(scoped_refptr<base::SingleThreadTaskRunner> runner)
         : runner_(std::move(runner)) {}
-    scoped_refptr<WebTaskRunner> GetTaskRunner(TaskType) override {
+    scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(
+        TaskType) override {
       return runner_;
     }
 
    private:
-    scoped_refptr<WebTaskRunner> runner_;
+    scoped_refptr<base::SingleThreadTaskRunner> runner_;
   };
 
   MockFetchContext(LoadPolicy load_policy)
@@ -130,7 +131,7 @@
         transfer_size_(-1) {}
 
   enum LoadPolicy load_policy_;
-  scoped_refptr<WebTaskRunner> runner_;
+  scoped_refptr<base::SingleThreadTaskRunner> runner_;
   scoped_refptr<const SecurityOrigin> security_origin_;
   std::unique_ptr<WebFrameScheduler> frame_scheduler_;
   std::unique_ptr<WebURLLoaderFactory> url_loader_factory_;
diff --git a/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.h b/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.h
index 1b612bb..71712b1 100644
--- a/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.h
+++ b/third_party/WebKit/Source/platform/mac/ScrollAnimatorMac.h
@@ -27,6 +27,7 @@
 #define ScrollAnimatorMac_h
 
 #include <memory>
+#include "base/single_thread_task_runner.h"
 #include "platform/Timer.h"
 #include "platform/WebTaskRunner.h"
 #include "platform/geometry/FloatPoint.h"
@@ -135,7 +136,7 @@
 
   void SendContentAreaScrolledTask();
   TaskHandle send_content_area_scrolled_task_handle_;
-  scoped_refptr<WebTaskRunner> task_runner_;
+  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
   ScrollOffset content_area_scrolled_timer_scroll_delta_;
 
   ScrollResult UserScroll(ScrollGranularity,
diff --git a/third_party/WebKit/Source/platform/network/NetworkStateNotifier.cpp b/third_party/WebKit/Source/platform/network/NetworkStateNotifier.cpp
index 2f772880..b18176b 100644
--- a/third_party/WebKit/Source/platform/network/NetworkStateNotifier.cpp
+++ b/third_party/WebKit/Source/platform/network/NetworkStateNotifier.cpp
@@ -29,6 +29,7 @@
 #include "net/nqe/effective_connection_type.h"
 #include "net/nqe/network_quality_estimator_params.h"
 #include "platform/CrossThreadFunctional.h"
+#include "platform/WebTaskRunner.h"
 #include "platform/wtf/Assertions.h"
 #include "platform/wtf/Functional.h"
 #include "platform/wtf/StdLibExtras.h"
@@ -80,7 +81,7 @@
     NetworkStateNotifier* notifier,
     NetworkStateNotifier::ObserverType type,
     NetworkStateNotifier::NetworkStateObserver* observer,
-    scoped_refptr<WebTaskRunner> task_runner)
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner)
     : notifier_(notifier),
       type_(type),
       observer_(observer),
@@ -143,7 +144,7 @@
 std::unique_ptr<NetworkStateNotifier::NetworkStateObserverHandle>
 NetworkStateNotifier::AddConnectionObserver(
     NetworkStateObserver* observer,
-    scoped_refptr<WebTaskRunner> task_runner) {
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
   AddObserverToMap(connection_observers_, observer, task_runner);
   return std::make_unique<NetworkStateNotifier::NetworkStateObserverHandle>(
       this, ObserverType::kConnectionType, observer, task_runner);
@@ -161,7 +162,7 @@
 std::unique_ptr<NetworkStateNotifier::NetworkStateObserverHandle>
 NetworkStateNotifier::AddOnLineObserver(
     NetworkStateObserver* observer,
-    scoped_refptr<WebTaskRunner> task_runner) {
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
   AddObserverToMap(on_line_state_observers_, observer, task_runner);
   return std::make_unique<NetworkStateNotifier::NetworkStateObserverHandle>(
       this, ObserverType::kOnLineState, observer, task_runner);
@@ -236,7 +237,7 @@
   DCHECK(IsMainThread());
   MutexLocker locker(mutex_);
   for (const auto& entry : map) {
-    scoped_refptr<WebTaskRunner> task_runner = entry.key;
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner = entry.key;
     PostCrossThreadTask(
         *task_runner, FROM_HERE,
         CrossThreadBind(&NetworkStateNotifier::NotifyObserversOnTaskRunner,
@@ -248,7 +249,7 @@
 void NetworkStateNotifier::NotifyObserversOnTaskRunner(
     ObserverListMap* map,
     ObserverType type,
-    scoped_refptr<WebTaskRunner> task_runner,
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
     const NetworkState& state) {
   ObserverList* observer_list = LockAndFindObserverList(*map, task_runner);
 
@@ -288,7 +289,7 @@
 void NetworkStateNotifier::AddObserverToMap(
     ObserverListMap& map,
     NetworkStateObserver* observer,
-    scoped_refptr<WebTaskRunner> task_runner) {
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
   DCHECK(task_runner->RunsTasksInCurrentSequence());
   DCHECK(observer);
 
@@ -305,7 +306,7 @@
 void NetworkStateNotifier::RemoveObserver(
     ObserverType type,
     NetworkStateObserver* observer,
-    scoped_refptr<WebTaskRunner> task_runner) {
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
   switch (type) {
     case ObserverType::kConnectionType:
       RemoveObserverFromMap(connection_observers_, observer,
@@ -321,7 +322,7 @@
 void NetworkStateNotifier::RemoveObserverFromMap(
     ObserverListMap& map,
     NetworkStateObserver* observer,
-    scoped_refptr<WebTaskRunner> task_runner) {
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
   DCHECK(task_runner->RunsTasksInCurrentSequence());
   DCHECK(observer);
 
@@ -343,7 +344,7 @@
 NetworkStateNotifier::ObserverList*
 NetworkStateNotifier::LockAndFindObserverList(
     ObserverListMap& map,
-    scoped_refptr<WebTaskRunner> task_runner) {
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
   MutexLocker locker(mutex_);
   ObserverListMap::iterator it = map.find(task_runner);
   return it == map.end() ? nullptr : it->value.get();
@@ -352,7 +353,7 @@
 void NetworkStateNotifier::CollectZeroedObservers(
     ObserverListMap& map,
     ObserverList* list,
-    scoped_refptr<WebTaskRunner> task_runner) {
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
   DCHECK(task_runner->RunsTasksInCurrentSequence());
   DCHECK(!list->iterating);
 
diff --git a/third_party/WebKit/Source/platform/network/NetworkStateNotifier.h b/third_party/WebKit/Source/platform/network/NetworkStateNotifier.h
index fa79cfb..3fe4b6b 100644
--- a/third_party/WebKit/Source/platform/network/NetworkStateNotifier.h
+++ b/third_party/WebKit/Source/platform/network/NetworkStateNotifier.h
@@ -29,9 +29,9 @@
 #include <memory>
 
 #include "base/rand_util.h"
+#include "base/single_thread_task_runner.h"
 #include "platform/CrossThreadCopier.h"
 #include "platform/PlatformExport.h"
-#include "platform/WebTaskRunner.h"
 #include "platform/wtf/Allocator.h"
 #include "platform/wtf/HashMap.h"
 #include "platform/wtf/Noncopyable.h"
@@ -90,14 +90,14 @@
     NetworkStateObserverHandle(NetworkStateNotifier*,
                                ObserverType,
                                NetworkStateObserver*,
-                               scoped_refptr<WebTaskRunner>);
+                               scoped_refptr<base::SingleThreadTaskRunner>);
     ~NetworkStateObserverHandle();
 
    private:
     NetworkStateNotifier* notifier_;
     ObserverType type_;
     NetworkStateObserver* observer_;
-    scoped_refptr<WebTaskRunner> task_runner_;
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
 
     DISALLOW_COPY_AND_ASSIGN(NetworkStateObserverHandle);
   };
@@ -232,10 +232,10 @@
   // and then added during notification.
   std::unique_ptr<NetworkStateObserverHandle> AddConnectionObserver(
       NetworkStateObserver*,
-      scoped_refptr<WebTaskRunner>);
+      scoped_refptr<base::SingleThreadTaskRunner>);
   std::unique_ptr<NetworkStateObserverHandle> AddOnLineObserver(
       NetworkStateObserver*,
-      scoped_refptr<WebTaskRunner>);
+      scoped_refptr<base::SingleThreadTaskRunner>);
 
   // Returns the randomization salt (weak and insecure) that should be used when
   // adding noise to the network quality metrics. This is known only to the
@@ -269,34 +269,35 @@
 
   // The ObserverListMap is cross-thread accessed, adding/removing Observers
   // running on a task runner.
-  using ObserverListMap =
-      HashMap<scoped_refptr<WebTaskRunner>, std::unique_ptr<ObserverList>>;
+  using ObserverListMap = HashMap<scoped_refptr<base::SingleThreadTaskRunner>,
+                                  std::unique_ptr<ObserverList>>;
 
   void NotifyObservers(ObserverListMap&, ObserverType, const NetworkState&);
   void NotifyObserversOnTaskRunner(ObserverListMap*,
                                    ObserverType,
-                                   scoped_refptr<WebTaskRunner>,
+                                   scoped_refptr<base::SingleThreadTaskRunner>,
                                    const NetworkState&);
 
   void AddObserverToMap(ObserverListMap&,
                         NetworkStateObserver*,
-                        scoped_refptr<WebTaskRunner>);
+                        scoped_refptr<base::SingleThreadTaskRunner>);
   void RemoveObserver(ObserverType,
                       NetworkStateObserver*,
-                      scoped_refptr<WebTaskRunner>);
+                      scoped_refptr<base::SingleThreadTaskRunner>);
   void RemoveObserverFromMap(ObserverListMap&,
                              NetworkStateObserver*,
-                             scoped_refptr<WebTaskRunner>);
+                             scoped_refptr<base::SingleThreadTaskRunner>);
 
-  ObserverList* LockAndFindObserverList(ObserverListMap&,
-                                        scoped_refptr<WebTaskRunner>);
+  ObserverList* LockAndFindObserverList(
+      ObserverListMap&,
+      scoped_refptr<base::SingleThreadTaskRunner>);
 
   // Removed observers are nulled out in the list in case the list is being
   // iterated over. Once done iterating, call this to clean up nulled
   // observers.
   void CollectZeroedObservers(ObserverListMap&,
                               ObserverList*,
-                              scoped_refptr<WebTaskRunner>);
+                              scoped_refptr<base::SingleThreadTaskRunner>);
 
   mutable Mutex mutex_;
   NetworkState state_;
diff --git a/third_party/WebKit/Source/platform/network/NetworkStateNotifierTest.cpp b/third_party/WebKit/Source/platform/network/NetworkStateNotifierTest.cpp
index 3bec382..4bcb4e3 100644
--- a/third_party/WebKit/Source/platform/network/NetworkStateNotifierTest.cpp
+++ b/third_party/WebKit/Source/platform/network/NetworkStateNotifierTest.cpp
@@ -121,13 +121,14 @@
   SaveData ObservedSaveData() const { return observed_save_data_; }
   int CallbackCount() const { return callback_count_; }
 
-  void AddObserverOnNotification(NetworkStateNotifier* notifier,
-                                 StateObserver* observer_to_add,
-                                 scoped_refptr<WebTaskRunner> task_runner) {
+  void AddObserverOnNotification(
+      NetworkStateNotifier* notifier,
+      StateObserver* observer_to_add,
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
     closure_ = base::BindOnce(
         [](StateObserver* observer, NetworkStateNotifier* notifier,
            StateObserver* observer_to_add,
-           scoped_refptr<WebTaskRunner> task_runner) {
+           scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
           observer->added_handle_ =
               notifier->AddConnectionObserver(observer_to_add, task_runner);
         },
@@ -170,8 +171,8 @@
     notifier_.SetOnLine(false);
   }
 
-  WebTaskRunner* GetTaskRunner() { return task_runner_.get(); }
-  WebTaskRunner* GetTaskRunner2() { return task_runner2_.get(); }
+  base::SingleThreadTaskRunner* GetTaskRunner() { return task_runner_.get(); }
+  base::SingleThreadTaskRunner* GetTaskRunner2() { return task_runner2_.get(); }
 
   void TearDown() override {
     // NetworkStateNotifier class is a singleton, so clear the override to avoid
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_unittest.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_unittest.cc
index 54a71fa..0bd15ed 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_unittest.cc
+++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_unittest.cc
@@ -288,6 +288,13 @@
   out_result->push_back(value);
 }
 
+void DisableQueueTestTask(EnqueueOrder value,
+                          std::vector<EnqueueOrder>* out_result,
+                          TaskQueue::QueueEnabledVoter* voter) {
+  out_result->push_back(value);
+  voter->SetQueueEnabled(false);
+}
+
 TEST_F(TaskQueueManagerTest, SingleQueuePosting) {
   Initialize(1u);
 
@@ -384,6 +391,55 @@
   EXPECT_THAT(run_order, ElementsAre(1, 2, 5, 6, 3, 4));
 }
 
+namespace {
+
+void InsertFenceAndPostTestTask(EnqueueOrder id,
+                                std::vector<EnqueueOrder>* run_order,
+                                scoped_refptr<TestTaskQueue> task_queue) {
+  run_order->push_back(id);
+  task_queue->InsertFence(TaskQueue::InsertFencePosition::kNow);
+  task_queue->PostTask(FROM_HERE,
+                       base::BindRepeating(&TestTask, id + 1, run_order));
+
+  // Force reload of immediate work queue. In real life the same effect can be
+  // achieved with cross-thread posting.
+  task_queue->GetTaskQueueImpl()->ReloadImmediateWorkQueueIfEmpty();
+}
+
+}  // namespace
+
+TEST_F(TaskQueueManagerTest, TaskQueueDisabledFromNestedLoop) {
+  InitializeWithRealMessageLoop(1u);
+  std::vector<EnqueueOrder> run_order;
+
+  std::vector<std::pair<base::Closure, bool>> tasks_to_post_from_nested_loop;
+
+  tasks_to_post_from_nested_loop.push_back(
+      std::make_pair(base::BindRepeating(&TestTask, 1, &run_order), false));
+  tasks_to_post_from_nested_loop.push_back(
+      std::make_pair(base::BindRepeating(&InsertFenceAndPostTestTask, 2,
+                                         &run_order, runners_[0]),
+                     true));
+
+  runners_[0]->PostTask(
+      FROM_HERE,
+      base::BindRepeating(&PostFromNestedRunloop, message_loop_.get(),
+                          base::RetainedRef(runners_[0]),
+                          base::Unretained(&tasks_to_post_from_nested_loop)));
+  base::RunLoop().RunUntilIdle();
+
+  // Task 1 shouldn't run first due to it being non-nestable and queue gets
+  // blocked after task 2. Task 1 runs after existing nested message loop
+  // due to being posted before inserting a fence.
+  // This test checks that breaks when nestable task is pushed into a redo
+  // queue.
+  EXPECT_THAT(run_order, ElementsAre(2, 1));
+
+  runners_[0]->RemoveFence();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_THAT(run_order, ElementsAre(2, 1, 3));
+}
+
 TEST_F(TaskQueueManagerTest, HasPendingImmediateWork_ImmediateTask) {
   Initialize(1u);
 
diff --git a/third_party/WebKit/Source/platform/scheduler/base/work_queue.cc b/third_party/WebKit/Source/platform/scheduler/base/work_queue.cc
index 75e357e..926da34 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/work_queue.cc
+++ b/third_party/WebKit/Source/platform/scheduler/base/work_queue.cc
@@ -86,6 +86,7 @@
   DCHECK(task.nestable == base::Nestable::kNonNestable);
 
   bool was_empty = work_queue_.empty();
+  bool was_blocked = BlockedByFence();
 #ifndef NDEBUG
   DCHECK(task.enqueue_order_set());
 #endif
@@ -107,7 +108,8 @@
   if (BlockedByFence())
     return;
 
-  if (was_empty) {
+  // Pushing task to front may unblock the fence.
+  if (was_empty || was_blocked) {
     work_queue_sets_->OnTaskPushedToEmptyQueue(this);
   } else {
     work_queue_sets_->OnFrontTaskChanged(this);
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorTest.cpp b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorTest.cpp
index 59f8fec..0c87b11 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorTest.cpp
+++ b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorTest.cpp
@@ -119,7 +119,7 @@
     ScrollableArea::SetScrollOffset(offset, type, behavior);
   }
 
-  scoped_refptr<WebTaskRunner> GetTimerTaskRunner() const final {
+  scoped_refptr<base::SingleThreadTaskRunner> GetTimerTaskRunner() const final {
     if (!timer_task_runner_) {
       timer_task_runner_ = blink::scheduler::CreateWebTaskRunnerForTesting();
     }
@@ -147,7 +147,7 @@
   ScrollOffset min_offset_;
   ScrollOffset max_offset_;
   Member<ScrollAnimator> animator;
-  mutable scoped_refptr<WebTaskRunner> timer_task_runner_;
+  mutable scoped_refptr<base::SingleThreadTaskRunner> timer_task_runner_;
 };
 
 class TestScrollAnimator : public ScrollAnimator {
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollableArea.h b/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
index 9f6d85e..a21ec91 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
+++ b/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
@@ -379,7 +379,8 @@
 
   // Returns the task runner to be used for scrollable area timers.
   // Ideally a frame-specific throttled one can be used.
-  virtual scoped_refptr<WebTaskRunner> GetTimerTaskRunner() const = 0;
+  virtual scoped_refptr<base::SingleThreadTaskRunner> GetTimerTaskRunner()
+      const = 0;
 
   // Callback for compositor-side scrolling.
   virtual void DidScroll(const gfx::ScrollOffset&);
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollbarTestSuite.h b/third_party/WebKit/Source/platform/scroll/ScrollbarTestSuite.h
index e62a9441..9213870 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollbarTestSuite.h
+++ b/third_party/WebKit/Source/platform/scroll/ScrollbarTestSuite.h
@@ -95,7 +95,7 @@
     ScrollableArea::SetScrollOrigin(origin);
   }
 
-  scoped_refptr<WebTaskRunner> GetTimerTaskRunner() const final {
+  scoped_refptr<base::SingleThreadTaskRunner> GetTimerTaskRunner() const final {
     return Platform::Current()->CurrentThread()->Scheduler()->TimerTaskRunner();
   }
 
diff --git a/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp b/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp
index 30a390c..81f8eee 100644
--- a/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp
+++ b/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp
@@ -31,7 +31,6 @@
 #include "base/path_service.h"
 #include "base/run_loop.h"
 #include "platform/SharedBuffer.h"
-#include "platform/WebTaskRunner.h"
 #include "platform/heap/Handle.h"
 #include "platform/wtf/text/StringUTF8Adaptor.h"
 #include "public/platform/FilePathConversion.h"
diff --git a/third_party/WebKit/Source/platform/wtf/VectorTraits.h b/third_party/WebKit/Source/platform/wtf/VectorTraits.h
index 65d551d1..c6376a0 100644
--- a/third_party/WebKit/Source/platform/wtf/VectorTraits.h
+++ b/third_party/WebKit/Source/platform/wtf/VectorTraits.h
@@ -42,9 +42,9 @@
   // slot in the vector's backing storage; it does not have to be equal to
   // what its constructor(s) would create, only be valid for those two uses.
   static constexpr bool kCanClearUnusedSlotsWithMemset =
-      std::is_trivially_constructible<T>::value &&
       std::is_trivially_destructible<T>::value &&
-      std::is_trivially_copyable<T>::value;
+      (!IsTraceable<T>::value || (std::is_trivially_constructible<T>::value &&
+                                  std::is_trivially_copyable<T>::value));
 
   static constexpr bool kCanMoveWithMemcpy =
       std::is_trivially_move_assignable<T>::value;
diff --git a/third_party/WebKit/common/service_worker/service_worker.mojom b/third_party/WebKit/common/service_worker/service_worker.mojom
index 041664a1..46bc6014 100644
--- a/third_party/WebKit/common/service_worker/service_worker.mojom
+++ b/third_party/WebKit/common/service_worker/service_worker.mojom
@@ -29,9 +29,24 @@
   // client with |client_uuid|.
   GetClient(string client_uuid) => (ServiceWorkerClientInfo client);
 
+  // Corresponds to Clients#openWindow(url). Requests the browser to open a tab
+  // with |url|.
+  // On success, |client| contains service worker client information of the
+  // newly opened window and |error_msg| is null.
+  // Otherwise, |client| is null and |error_msg| describes the failure.
+  OpenNewTab(url.mojom.Url url)
+    => (ServiceWorkerClientInfo? client, string? error_msg);
+
+  // Corresponds to PaymentRequestEvent#openWindow(url).
+  // Spec: https://w3c.github.io/payment-handler/#openwindow-method
+  // Requests the browser to open a payment handler window with |url|.
+  // On success, |client| contains service worker client information of the
+  // newly opened window and |error_msg| is null.
+  // Otherwise, |client| is null and |error_msg| describes the failure.
+  OpenPaymentHandlerWindow(url.mojom.Url url)
+    => (ServiceWorkerClientInfo? client, string? error_msg);
+
   // TODO(leonhsl): Impl all methods.
-  // OpenNewTab();
-  // OpenNewPopup();
   // PostMessageToClient();
   // FocusClient();
   // NavigateClient();
diff --git a/third_party/WebKit/public/platform/web_feature.mojom b/third_party/WebKit/public/platform/web_feature.mojom
index 93637b3..b0077f23 100644
--- a/third_party/WebKit/public/platform/web_feature.mojom
+++ b/third_party/WebKit/public/platform/web_feature.mojom
@@ -1653,7 +1653,6 @@
 
   kFeaturePolicyAllowAttributeDeprecatedSyntax = 2145,
   kSuppressHistoryEntryWithoutUserGesture = 2146,
-  kImageInputTypeFormDataWithNonEmptyValue = 2147,
   kWebAudioDezipperGainNodeGain = 2148,
   kWebAudioDezipperStereoPannerNodePan = 2149,
   kWebAudioDezipperDelayNodeDelayTime = 2150,
@@ -1868,6 +1867,7 @@
   kCSSGradient = 2355,
   kCSSPaintFunction = 2356,
   kWebkitCrossFade = 2357,
+  kDisablePictureInPictureAttribute = 2358,
 
   // 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/libjingle_xmpp/xmpp/xmpplogintask_unittest.cc b/third_party/libjingle_xmpp/xmpp/xmpplogintask_unittest.cc
index 11fc4f9..a7edbc6 100644
--- a/third_party/libjingle_xmpp/xmpp/xmpplogintask_unittest.cc
+++ b/third_party/libjingle_xmpp/xmpp/xmpplogintask_unittest.cc
@@ -22,6 +22,16 @@
 #include "third_party/webrtc/rtc_base/gunit.h"
 #include "third_party/webrtc/typedefs.h"
 
+// Macro to be used for switch-case fallthrough (required for enabling
+// -Wimplicit-fallthrough warning on Clang).
+#ifdef __clang__
+#define XLTT_FALLTHROUGH() [[clang::fallthrough]]
+#else
+#define XLTT_FALLTHROUGH() \
+  do {                     \
+  } while (0)
+#endif
+
 using buzz::Jid;
 using buzz::QName;
 using buzz::XmlElement;
@@ -92,7 +102,7 @@
       EXPECT_EQ("", handler_->StanzaActivity());
       if (endstage == XLTT_STAGE_CONNECT)
         return;
-      FALLTHROUGH();
+      XLTT_FALLTHROUGH();
     }
 
     case XLTT_STAGE_STREAMSTART: {
@@ -105,7 +115,7 @@
       EXPECT_EQ("", handler_->OutputActivity());
       if (endstage == XLTT_STAGE_STREAMSTART)
         return;
-      FALLTHROUGH();
+      XLTT_FALLTHROUGH();
     }
 
     case XLTT_STAGE_TLS_FEATURES: {
@@ -119,7 +129,7 @@
       EXPECT_EQ("", handler_->SessionActivity());
       if (endstage == XLTT_STAGE_TLS_FEATURES)
         return;
-      FALLTHROUGH();
+      XLTT_FALLTHROUGH();
     }
 
     case XLTT_STAGE_TLS_PROCEED: {
@@ -133,7 +143,7 @@
       EXPECT_EQ("", handler_->SessionActivity());
       if (endstage == XLTT_STAGE_TLS_PROCEED)
         return;
-      FALLTHROUGH();
+      XLTT_FALLTHROUGH();
     }
 
     case XLTT_STAGE_ENCRYPTED_START: {
@@ -146,7 +156,7 @@
       EXPECT_EQ("", handler_->OutputActivity());
       if (endstage == XLTT_STAGE_ENCRYPTED_START)
         return;
-      FALLTHROUGH();
+      XLTT_FALLTHROUGH();
     }
 
     case XLTT_STAGE_AUTH_FEATURES: {
@@ -168,7 +178,7 @@
       EXPECT_EQ("", handler_->SessionActivity());
       if (endstage == XLTT_STAGE_AUTH_FEATURES)
         return;
-      FALLTHROUGH();
+      XLTT_FALLTHROUGH();
     }
 
     case XLTT_STAGE_AUTH_SUCCESS: {
@@ -181,7 +191,7 @@
       EXPECT_EQ("", handler_->SessionActivity());
       if (endstage == XLTT_STAGE_AUTH_SUCCESS)
         return;
-      FALLTHROUGH();
+      XLTT_FALLTHROUGH();
     }
 
     case XLTT_STAGE_AUTHENTICATED_START: {
@@ -194,7 +204,7 @@
       EXPECT_EQ("", handler_->OutputActivity());
       if (endstage == XLTT_STAGE_AUTHENTICATED_START)
         return;
-      FALLTHROUGH();
+      XLTT_FALLTHROUGH();
     }
 
     case XLTT_STAGE_BIND_FEATURES: {
@@ -210,7 +220,7 @@
       EXPECT_EQ("", handler_->SessionActivity());
       if (endstage == XLTT_STAGE_BIND_FEATURES)
         return;
-      FALLTHROUGH();
+      XLTT_FALLTHROUGH();
     }
 
     case XLTT_STAGE_BIND_SUCCESS: {
@@ -225,7 +235,7 @@
       EXPECT_EQ("", handler_->SessionActivity());
       if (endstage == XLTT_STAGE_BIND_SUCCESS)
         return;
-      FALLTHROUGH();
+      XLTT_FALLTHROUGH();
     }
 
     case XLTT_STAGE_SESSION_SUCCESS: {
@@ -237,7 +247,7 @@
       EXPECT_EQ("", handler_->StanzaActivity());
       if (endstage == XLTT_STAGE_SESSION_SUCCESS)
         return;
-      FALLTHROUGH();
+      XLTT_FALLTHROUGH();
     }
     default:
       break;
diff --git a/third_party/metrics_proto/execution_context.proto b/third_party/metrics_proto/execution_context.proto
index bf29758f..ace0599 100644
--- a/third_party/metrics_proto/execution_context.proto
+++ b/third_party/metrics_proto/execution_context.proto
@@ -34,12 +34,12 @@
   // Browser process threads from content/public/browser/browser_thread.h,
   // some of which occur in other processes as well.
   UI_THREAD = 1;
-  FILE_THREAD = 2;
-  FILE_USER_BLOCKING_THREAD = 3;
+  FILE_THREAD = 2;                // Deprecated.
+  FILE_USER_BLOCKING_THREAD = 3;  // Deprecated.
   PROCESS_LAUNCHER_THREAD = 4;
-  CACHE_THREAD = 5;
+  CACHE_THREAD = 5;  // Deprecated.
   IO_THREAD = 6;
-  DB_THREAD = 7;
+  DB_THREAD = 7;  // Deprecated.
 
   // GPU process thread.
   GPU_MAIN_THREAD = 8;
diff --git a/tools/clang/pylib/clang/compile_db.py b/tools/clang/pylib/clang/compile_db.py
index c4eecb60..a78ab5e 100755
--- a/tools/clang/pylib/clang/compile_db.py
+++ b/tools/clang/pylib/clang/compile_db.py
@@ -72,9 +72,10 @@
 
 
 def GetNinjaPath():
+  ninja_executable = 'ninja.exe' if sys.platform == 'win32' else 'ninja'
   return os.path.join(
       os.path.dirname(os.path.realpath(__file__)),
-        '..', '..', '..', '..', 'third_party', 'depot_tools', 'ninja')
+        '..', '..', '..', '..', 'third_party', 'depot_tools', ninja_executable)
 
 
 # FIXME: This really should be a build target, rather than generated at runtime.
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index ab54d4f..fd5a0fc9 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -12489,6 +12489,8 @@
   <int value="411" label="PasswordProtectionWarningTrigger"/>
   <int value="412" label="PasswordProtectionRiskTrigger"/>
   <int value="413" label="EnableSymantecLegacyInfrastructure"/>
+  <int value="414" label="WebDriverOverridesIncompatiblePolicies"/>
+  <int value="415" label="DeviceKerberosEncryptionTypes"/>
 </enum>
 
 <enum name="EnterprisePolicyInvalidations">
@@ -15139,6 +15141,12 @@
   <int value="35" label="CRX_EXPECTED_HASH_INVALID"/>
 </enum>
 
+<enum name="ExtensionUpdaterUpdateResult">
+  <int value="0" label="No update"/>
+  <int value="1" label="Update success"/>
+  <int value="2" label="Update error"/>
+</enum>
+
 <enum name="ExtensionViewType">
   <int value="0" label="INVALID"/>
   <int value="1" label="APP_WINDOW"/>
@@ -17521,7 +17529,7 @@
   <int value="2144" label="WebkitBoxLineClampDoesSomething"/>
   <int value="2145" label="FeaturePolicyAllowAttributeDeprecatedSyntax"/>
   <int value="2146" label="SuppressHistoryEntryWithoutUserGesture"/>
-  <int value="2147" label="ImageInputTypeFormDataWithNonEmptyValue"/>
+  <int value="2147" label="OBSOLETE_ImageInputTypeFormDataWithNonEmptyValue"/>
   <int value="2148" label="WebAudioDezipperGainNodeGain"/>
   <int value="2149" label="WebAudioDezipperStereoPannerNodePan"/>
   <int value="2150" label="WebAudioDezipperDelayNodeDelayTime"/>
@@ -17735,6 +17743,7 @@
   <int value="2355" label="CSSGradient"/>
   <int value="2356" label="CSSPaintFunction"/>
   <int value="2357" label="WebkitCrossFade"/>
+  <int value="2358" label="DisablePictureInPictureAttribute"/>
 </enum>
 
 <enum name="FeedbackSource">
@@ -26175,6 +26184,8 @@
   <int value="262382944" label="GuestViewCrossProcessFrames:disabled"/>
   <int value="266322815" label="ChromeModernDesign:disabled"/>
   <int value="266702296" label="disable-plugin-power-saver"/>
+  <int value="268535107"
+      label="ash-new-touch-support-for-screen-magnification"/>
   <int value="270267831" label="enable-scripts-require-action"/>
   <int value="272631627" label="BookmarkAppsMac:enabled"/>
   <int value="274103741" label="enable-ntp-popular-sites"/>
@@ -43439,6 +43450,7 @@
 Called by update_traffic_annotation_histograms.py.-->
 
   <int value="485305" label="data_reduction_proxy_config"/>
+  <int value="516551" label="socket_bio_adapter"/>
   <int value="727478" label="metrics_report_ukm"/>
   <int value="727528" label="metrics_report_uma"/>
   <int value="1112842" label="oauth2_mint_token_flow"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index c5f8fd4..3b2d4ac 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -23925,6 +23925,33 @@
   <summary>An extension has been uninstalled.</summary>
 </histogram>
 
+<histogram name="Extensions.ExtensionUpdaterUpdateCalls" units="extensions">
+  <owner>mxnguyen@chromium.org</owner>
+  <summary>
+    The number of extensions that are passed over to the extension updater for
+    update check. Triggered when the extension updater starts doing update
+    check.
+  </summary>
+</histogram>
+
+<histogram name="Extensions.ExtensionUpdaterUpdateFoundCount"
+    units="extensions">
+  <owner>mxnguyen@chromium.org</owner>
+  <summary>
+    The number of extensions that have updates in an update check session.
+    Triggered when the extension updater found an update for an extension.
+  </summary>
+</histogram>
+
+<histogram name="Extensions.ExtensionUpdaterUpdateResults"
+    enum="ExtensionUpdaterUpdateResult">
+  <owner>mxnguyen@chromium.org</owner>
+  <summary>
+    Records the update results of extensions in an extension updater session,
+    grouped by ExtensionUpdaterUpdateResult.
+  </summary>
+</histogram>
+
 <histogram name="Extensions.ExternalExtensionEvent" enum="SideloadUIEvents">
   <owner>Please list the metric's owners. Add more owner tags as needed.</owner>
   <summary>
@@ -27671,15 +27698,6 @@
   </summary>
 </histogram>
 
-<histogram name="GPU.BlacklistFeatureTestResultsWin"
-    enum="GPUBlacklistFeatureTestResultsWin">
-  <owner>vmiura@chromium.org</owner>
-  <summary>
-    Counts number of browser invocations for which a GPU feature is blacklisted
-    in various Windows sub-versions.
-  </summary>
-</histogram>
-
 <histogram name="GPU.BlacklistFeatureTestResultsWindows"
     enum="GPUBlacklistFeatureTestResultsWindows">
   <owner>vmiura@chromium.org</owner>
@@ -104825,11 +104843,11 @@
 <histogram_suffixes name="GPUBlacklistPerFeature" separator=".">
   <owner>vmiura@chromium.org</owner>
   <suffix name="Accelerated2dCanvas" label="Accelerated2dCanvas"/>
-  <suffix name="AcceleratedCompositing" label="AcceleratedCompositing"/>
+  <suffix name="GpuCompositing" label="GpuCompositing"/>
+  <suffix name="GpuRasterization" label="GpuRasterization"/>
   <suffix name="Webgl" label="Webgl"/>
-  <suffix name="TextureSharing" label="TextureSharing"/>
+  <suffix name="Webgl2" label="Webgl2"/>
   <affected-histogram name="GPU.BlacklistFeatureTestResults"/>
-  <affected-histogram name="GPU.BlacklistFeatureTestResultsWin"/>
   <affected-histogram name="GPU.BlacklistFeatureTestResultsWindows"/>
 </histogram_suffixes>
 
diff --git a/tools/perf/benchmarks/start_with_url.py b/tools/perf/benchmarks/start_with_url.py
index 3ffa331..2d1de12 100644
--- a/tools/perf/benchmarks/start_with_url.py
+++ b/tools/perf/benchmarks/start_with_url.py
@@ -91,7 +91,7 @@
   def CreateCoreTimelineBasedMeasurementOptions(self):
     startup_category_filter = (
         chrome_trace_category_filter.ChromeTraceCategoryFilter(
-            filter_string=('loading,net,netlog,network,'
+            filter_string=('loading,net,netlog,network,offline_pages,'
                 'startup,toplevel,Java,EarlyJava')))
     options = timeline_based_measurement.Options(
         overhead_level=startup_category_filter)
diff --git a/tools/traffic_annotation/README.md b/tools/traffic_annotation/README.md
index 724df46e..4bd21ed8 100644
--- a/tools/traffic_annotation/README.md
+++ b/tools/traffic_annotation/README.md
@@ -99,4 +99,4 @@
 re-enable the test.
 
 CLANG_REVISION = '321529'
-LASTCHANGE=c67646fb6096ac1d87b516b2eaf2eb9968d2da73-refs/heads/master@{#531988}
+LASTCHANGE=cd208cb67b8c685ef22139bf46590637e86d03fe-refs/heads/master@{#533223}
diff --git a/tools/traffic_annotation/bin/win32/traffic_annotation_auditor.exe.sha1 b/tools/traffic_annotation/bin/win32/traffic_annotation_auditor.exe.sha1
index d7db886..18e0a53 100644
--- a/tools/traffic_annotation/bin/win32/traffic_annotation_auditor.exe.sha1
+++ b/tools/traffic_annotation/bin/win32/traffic_annotation_auditor.exe.sha1
@@ -1 +1 @@
-a6ddcce4579449e47f50101842b4a68c988f03b6
\ No newline at end of file
+66d4c1f79c2783151f8d46adf1b4092a357cc9bc
\ No newline at end of file
diff --git a/tools/traffic_annotation/bin/win32/traffic_annotation_extractor.exe.sha1 b/tools/traffic_annotation/bin/win32/traffic_annotation_extractor.exe.sha1
index fadd139..2147a07 100644
--- a/tools/traffic_annotation/bin/win32/traffic_annotation_extractor.exe.sha1
+++ b/tools/traffic_annotation/bin/win32/traffic_annotation_extractor.exe.sha1
@@ -1 +1 @@
-1e94944a3885d4a257e687b8ff5d11abb64925cf
\ No newline at end of file
+25d5732353ef266f3d08ad770b954e16eb34d094
\ No newline at end of file
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml
index 4c3f9478..69d08f8 100644
--- a/tools/traffic_annotation/summary/annotations.xml
+++ b/tools/traffic_annotation/summary/annotations.xml
@@ -196,6 +196,7 @@
  <item id="service_worker_navigation_preload" hash_code="129872904" type="0" content_hash_code="79473248" os_list="linux,windows" file_path="content/browser/service_worker/service_worker_fetch_dispatcher.cc"/>
  <item id="service_worker_write_to_cache_job" hash_code="117963307" type="0" content_hash_code="18065724" os_list="linux,windows" file_path="content/browser/service_worker/service_worker_write_to_cache_job.cc"/>
  <item id="signed_in_profile_avatar" hash_code="108903331" type="0" content_hash_code="72850619" os_list="linux,windows" file_path="chrome/browser/profiles/profile_downloader.cc"/>
+ <item id="socket_bio_adapter" hash_code="516551" type="0" content_hash_code="21643352" os_list="linux,windows" file_path="net/socket/socket_bio_adapter.cc"/>
  <item id="speech_recognition_downstream" hash_code="26096088" type="0" content_hash_code="120733233" os_list="linux,windows" file_path="content/browser/speech/speech_recognition_engine.cc"/>
  <item id="speech_recognition_upstream" hash_code="66846958" type="0" content_hash_code="7706219" os_list="linux,windows" file_path="content/browser/speech/speech_recognition_engine.cc"/>
  <item id="spellcheck_hunspell_dictionary" hash_code="117649486" type="0" content_hash_code="45660952" os_list="linux,windows" file_path="chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc"/>
diff --git a/ui/webui/resources/html/search_highlight_utils.html b/ui/webui/resources/html/search_highlight_utils.html
new file mode 100644
index 0000000..5f7a883
--- /dev/null
+++ b/ui/webui/resources/html/search_highlight_utils.html
@@ -0,0 +1 @@
+<script src="chrome://resources/js/search_highlight_utils.js"></script>
diff --git a/ui/webui/resources/js/compiled_resources2.gyp b/ui/webui/resources/js/compiled_resources2.gyp
index 25f388b..3b759c0 100644
--- a/ui/webui/resources/js/compiled_resources2.gyp
+++ b/ui/webui/resources/js/compiled_resources2.gyp
@@ -32,6 +32,13 @@
       'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
     {
+      'target_name': 'search_highlight_utils',
+      'dependencies': [
+        'cr',
+      ],
+      'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
+    },
+    {
       'target_name': 'icon',
       'dependencies': [
         'cr',
diff --git a/ui/webui/resources/js/search_highlight_utils.js b/ui/webui/resources/js/search_highlight_utils.js
new file mode 100644
index 0000000..6c552ea
--- /dev/null
+++ b/ui/webui/resources/js/search_highlight_utils.js
@@ -0,0 +1,76 @@
+// 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.
+
+cr.define('cr.search_highlight_utils', function() {
+  /** @type {string} */
+  const WRAPPER_CSS_CLASS = 'search-highlight-wrapper';
+
+  /** @type {string} */
+  const ORIGINAL_CONTENT_CSS_CLASS = 'search-highlight-original-content';
+
+  /** @type {string} */
+  const HIT_CSS_CLASS = 'search-highlight-hit';
+
+  /**
+   * Applies the highlight UI (yellow rectangle) around all matches in |node|.
+   * @param {!Node} node The text node to be highlighted. |node| ends up
+   *     being hidden.
+   * @param {!Array<string>} tokens The string tokens after splitting on the
+   *     relevant regExp. Even indices hold text that doesn't need highlighting,
+   *     odd indices hold the text to be highlighted. For example:
+   *     const r = new RegExp('(foo)', 'i');
+   *     'barfoobar foo bar'.split(r) => ['bar', 'foo', 'bar ', 'foo', ' bar']
+   */
+  function highlight(node, tokens) {
+    const wrapper = document.createElement('span');
+    wrapper.classList.add(WRAPPER_CSS_CLASS);
+    // Use existing node as placeholder to determine where to insert the
+    // replacement content.
+    node.parentNode.replaceChild(wrapper, node);
+
+    // Keep the existing node around for when the highlights are removed. The
+    // existing text node might be involved in data-binding and therefore should
+    // not be discarded.
+    const span = document.createElement('span');
+    span.classList.add(ORIGINAL_CONTENT_CSS_CLASS);
+    span.style.display = 'none';
+    span.appendChild(node);
+    wrapper.appendChild(span);
+
+    for (let i = 0; i < tokens.length; ++i) {
+      if (i % 2 == 0) {
+        wrapper.appendChild(document.createTextNode(tokens[i]));
+      } else {
+        const hitSpan = document.createElement('span');
+        hitSpan.classList.add(HIT_CSS_CLASS);
+        hitSpan.style.backgroundColor = '#ffeb3b';  // --var(--paper-yellow-500)
+        hitSpan.textContent = tokens[i];
+        wrapper.appendChild(hitSpan);
+      }
+    }
+  }
+
+  /**
+   * Finds all previous highlighted nodes under |node| (both within self and
+   * children's Shadow DOM) and replaces the highlights (yellow rectangles)
+   * with the original search node.
+   * @param {!Node} node
+   * @private
+   */
+  function findAndRemoveHighlights(node) {
+    const wrappers = node.querySelectorAll('* /deep/ .' + WRAPPER_CSS_CLASS);
+
+    for (let i = 0; i < wrappers.length; i++) {
+      const wrapper = wrappers[i];
+      const originalNode =
+          wrapper.querySelector('.' + ORIGINAL_CONTENT_CSS_CLASS);
+      wrapper.parentElement.replaceChild(originalNode.firstChild, wrapper);
+    }
+  }
+
+  return {
+    highlight: highlight,
+    findAndRemoveHighlights: findAndRemoveHighlights,
+  };
+});
diff --git a/ui/webui/resources/webui_resources.grd b/ui/webui/resources/webui_resources.grd
index d33f30d..9220ba4 100644
--- a/ui/webui/resources/webui_resources.grd
+++ b/ui/webui/resources/webui_resources.grd
@@ -369,6 +369,11 @@
       <structure name="IDR_WEBUI_HTML_WEBUI_LISTENER_TRACKER"
                  file="html/webui_listener_tracker.html" type="chrome_html"
                  compress="gzip" />
+      <if expr="not is_android and not is_ios">
+        <structure name="IDR_WEBUI_HTML_SEARCH_HIGHLIGHT_UTILS"
+                   file="html/search_highlight_utils.html" type="chrome_html"
+                   compress="gzip" />
+      </if>
 
       <structure name="IDR_WEBUI_JS_ACTION_LINK"
                  file="js/action_link.js" type="chrome_html" compress="gzip" />
@@ -531,6 +536,12 @@
                  file="js/webui_resource_test.js" type="chrome_html"
                  compress="gzip" />
       <if expr="not is_android and not is_ios">
+        <structure name="IDR_WEBUI_JS_SEARCH_HIGHLIGHT_UTILS"
+                   file="js/search_highlight_utils.js" type="chrome_html"
+                   compress="gzip" />
+      </if>
+
+      <if expr="not is_android">
         <part file="cr_components/cr_components_resources.grdp" />
         <part file="cr_elements_resources.grdp" />
         <part file="cr_polymer_resources.grdp" />