diff --git a/DEPS b/DEPS
index 9ab0e1e..a6df338 100644
--- a/DEPS
+++ b/DEPS
@@ -102,11 +102,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': 'ec0732433f28368b94973496fbdb990f967ba1f6',
+  'skia_revision': '22f673d42087853a151fcd5e95c129be83065cdc',
   # 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': '77fbb59f326019340db3592edacfeaa8024f4e69',
+  'v8_revision': 'aa6b10a829ac48388576a92db4a4ab3cf803a875',
   # 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.
@@ -114,7 +114,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': '46bcea50feeb22aaeaf09859fd8d3f8ecdd7f478',
+  'angle_revision': 'cbab27508edf116d73535f4cebf0dfb21d187c84',
   # 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.
@@ -126,7 +126,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': '1118a66bfe024e137324075ac4d9433b9425e373',
+  'pdfium_revision': '2d11d72e326140b9abeb6de2db1e28e5bf9d7e64',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling openmax_dl
   # and whatever else without interference from each other.
@@ -504,7 +504,7 @@
 
   # Build tools for Chrome OS. Note: This depends on third_party/pyelftools.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'ffe9e609259998c874d405c29d5dae2c2f1c9ace',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'a09f2ac039e085d3ffd2dc4445f6dc833d4420f5',
       'condition': 'checkout_linux',
   },
 
@@ -519,7 +519,7 @@
 
   # For Linux and Chromium OS.
   'src/third_party/cros_system_api': {
-      'url': Var('chromium_git') + '/chromiumos/platform/system_api.git' + '@' + 'a9ac639b38af7ad3d745975ad850cbde73fbb7ee',
+      'url': Var('chromium_git') + '/chromiumos/platform/system_api.git' + '@' + '8fd2b32dce02ef01f03eee8587a9247e538f38d0',
       'condition': 'checkout_linux',
   },
 
@@ -529,7 +529,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '0ae14e9aad83c1387df8dd565cce3748fce3dec7',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '621fe6f9b56a04d06b4a730cd2867d50282a6490',
 
   'src/third_party/devtools-node-modules':
     Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'),
@@ -996,7 +996,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '198d637dd3e21d837fac6b3186cc6bc72e2f7219',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '942b360d820f452707b5a496e3ee73ff48c88b1d',
+    Var('webrtc_git') + '/src.git' + '@' + '79ce820a1382054143be44d75a658daa313c0ace',
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/ash/system/message_center/arc/arc_notification_content_view.cc b/ash/system/message_center/arc/arc_notification_content_view.cc
index 59ec668..f1eea87c 100644
--- a/ash/system/message_center/arc/arc_notification_content_view.cc
+++ b/ash/system/message_center/arc/arc_notification_content_view.cc
@@ -308,7 +308,9 @@
     const message_center::Notification& notification) {
   control_buttons_view_.ShowSettingsButton(
       notification.should_show_settings_button());
-  control_buttons_view_.ShowCloseButton(!message_view->GetPinned());
+  control_buttons_view_.ShowCloseButton(!notification.pinned());
+  control_buttons_view_.ShowSnoozeButton(
+      notification.should_show_snooze_button());
   control_buttons_view_.SetBackgroundColor(
       GetControlButtonBackgroundColor(item_->GetShownContents()));
   UpdateControlButtonsVisibility();
@@ -335,18 +337,18 @@
 
   DCHECK(floating_control_buttons_widget_);
 
-  const bool target_visiblity =
+  const bool target_visibility =
       IsMouseHovered() || (control_buttons_view_.IsCloseButtonFocused()) ||
       (control_buttons_view_.IsSettingsButtonFocused());
 
-  if (target_visiblity == floating_control_buttons_widget_->IsVisible())
+  if (target_visibility == floating_control_buttons_widget_->IsVisible())
     return;
 
   // Add the guard to prevent an infinite loop. Changing visibility may generate
   // an event and it may call thie method again.
   base::AutoReset<bool> reset(&updating_control_buttons_visibility_, true);
 
-  if (target_visiblity)
+  if (target_visibility)
     floating_control_buttons_widget_->Show();
   else
     floating_control_buttons_widget_->Hide();
diff --git a/ash/system/message_center/arc/arc_notification_content_view.h b/ash/system/message_center/arc/arc_notification_content_view.h
index cecbb15..ac141cca 100644
--- a/ash/system/message_center/arc/arc_notification_content_view.h
+++ b/ash/system/message_center/arc/arc_notification_content_view.h
@@ -60,6 +60,7 @@
   void OnContainerAnimationEnded();
 
  private:
+  friend class ArcNotificationViewTest;
   friend class ArcNotificationContentViewTest;
 
   class EventForwarder;
diff --git a/ash/system/message_center/arc/arc_notification_item.h b/ash/system/message_center/arc/arc_notification_item.h
index 0a51ae8..c9d23e11 100644
--- a/ash/system/message_center/arc/arc_notification_item.h
+++ b/ash/system/message_center/arc/arc_notification_item.h
@@ -42,6 +42,9 @@
   // Called when the user wants to open an intrinsic setting of notification.
   // This is called from ArcNotificationContentView.
   virtual void OpenSettings() = 0;
+  // Called when the user wants to open an intrinsic snooze setting of
+  // notification. This is called from ArcNotificationContentView.
+  virtual void OpenSnooze() = 0;
   // Called when the user wants to toggle expansio of notification. This is
   // called from ArcNotificationContentView.
   virtual void ToggleExpansion() = 0;
diff --git a/ash/system/message_center/arc/arc_notification_item_impl.cc b/ash/system/message_center/arc/arc_notification_item_impl.cc
index 23eaa98..68a1e85 100644
--- a/ash/system/message_center/arc/arc_notification_item_impl.cc
+++ b/ash/system/message_center/arc/arc_notification_item_impl.cc
@@ -75,19 +75,34 @@
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DCHECK_EQ(notification_key_, data->key);
 
+  bool is_snooze_setting_shown =
+      (data->shown_contents ==
+       arc::mojom::ArcNotificationShownContents::SNOOZE_SHOWN);
+
   message_center::RichNotificationData rich_data;
-  rich_data.pinned = (data->no_clear || data->ongoing_event);
+  rich_data.pinned =
+      (data->no_clear || data->ongoing_event)  // Unclosable notification
+      || is_snooze_setting_shown;              // Snooze setting is unclosable
   rich_data.priority = ConvertAndroidPriority(data->priority);
   if (data->small_icon)
     rich_data.small_image = gfx::Image::CreateFrom1xBitmap(*data->small_icon);
 
   rich_data.accessible_name = base::UTF8ToUTF16(
       data->accessible_name.value_or(data->title + "\n" + data->message));
-  if (manager_->IsOpeningSettingsSupported()) {
+  if (manager_->IsOpeningSettingsSupported() && !is_snooze_setting_shown) {
     rich_data.settings_button_handler =
         message_center::SettingsButtonHandler::DELEGATE;
+  } else {
+    rich_data.settings_button_handler =
+        message_center::SettingsButtonHandler::NONE;
   }
 
+  bool is_snooze_supported =
+      (data->flags && (data->flags->value &
+                       arc::mojom::ArcNotificationFlags::SUPPORT_SNOOZE) != 0);
+  rich_data.should_show_snooze_button =
+      is_snooze_supported && !is_snooze_setting_shown;
+
   message_center::NotifierId notifier_id(
       message_center::NotifierId::ARC_APPLICATION,
       app_id.empty() ? kDefaultArcNotifierId : app_id);
@@ -156,6 +171,10 @@
   manager_->OpenNotificationSettings(notification_key_);
 }
 
+void ArcNotificationItemImpl::OpenSnooze() {
+  manager_->OpenNotificationSnoozeSettings(notification_key_);
+}
+
 void ArcNotificationItemImpl::ToggleExpansion() {
   switch (expand_state_) {
     case ArcNotificationExpandState::EXPANDED:
diff --git a/ash/system/message_center/arc/arc_notification_item_impl.h b/ash/system/message_center/arc/arc_notification_item_impl.h
index ab374a5..961e570 100644
--- a/ash/system/message_center/arc/arc_notification_item_impl.h
+++ b/ash/system/message_center/arc/arc_notification_item_impl.h
@@ -37,6 +37,7 @@
   void Close(bool by_user) override;
   void Click() override;
   void OpenSettings() override;
+  void OpenSnooze() override;
   void ToggleExpansion() override;
   void AddObserver(Observer* observer) override;
   void RemoveObserver(Observer* observer) override;
diff --git a/ash/system/message_center/arc/arc_notification_manager.cc b/ash/system/message_center/arc/arc_notification_manager.cc
index 9a2f2cef..b365468 100644
--- a/ash/system/message_center/arc/arc_notification_manager.cc
+++ b/ash/system/message_center/arc/arc_notification_manager.cc
@@ -331,6 +331,24 @@
   notifications_instance->OpenNotificationSettings(key);
 }
 
+void ArcNotificationManager::OpenNotificationSnoozeSettings(
+    const std::string& key) {
+  if (!base::ContainsKey(items_, key)) {
+    DVLOG(3) << "Chrome requests to show a snooze setting gut on the"
+             << "notification (key: " << key << "), but it is gone.";
+    return;
+  }
+
+  auto* notifications_instance = ARC_GET_INSTANCE_FOR_METHOD(
+      instance_owner_->holder(), OpenNotificationSnoozeSettings);
+
+  // On shutdown, the ARC channel may quit earlier than notifications.
+  if (!notifications_instance)
+    return;
+
+  notifications_instance->OpenNotificationSnoozeSettings(key);
+}
+
 bool ArcNotificationManager::IsOpeningSettingsSupported() const {
   const auto* notifications_instance = ARC_GET_INSTANCE_FOR_METHOD(
       instance_owner_->holder(), OpenNotificationSettings);
diff --git a/ash/system/message_center/arc/arc_notification_manager.h b/ash/system/message_center/arc/arc_notification_manager.h
index 19aac0b..8300df5 100644
--- a/ash/system/message_center/arc/arc_notification_manager.h
+++ b/ash/system/message_center/arc/arc_notification_manager.h
@@ -60,6 +60,7 @@
   void CreateNotificationWindow(const std::string& key);
   void CloseNotificationWindow(const std::string& key);
   void OpenNotificationSettings(const std::string& key);
+  void OpenNotificationSnoozeSettings(const std::string& key);
   bool IsOpeningSettingsSupported() const;
   void SendNotificationToggleExpansionOnChrome(const std::string& key);
 
diff --git a/ash/system/message_center/arc/arc_notification_view.cc b/ash/system/message_center/arc/arc_notification_view.cc
index 797e3db..1c73b46a 100644
--- a/ash/system/message_center/arc/arc_notification_view.cc
+++ b/ash/system/message_center/arc/arc_notification_view.cc
@@ -137,6 +137,11 @@
   content_view_->OnContainerAnimationStarted();
 }
 
+void ArcNotificationView::OnSnoozeButtonPressed(const ui::Event& event) {
+  if (item_)
+    return item_->OpenSnooze();
+}
+
 void ArcNotificationView::OnContainerAnimationEnded() {
   content_view_->OnContainerAnimationEnded();
 }
diff --git a/ash/system/message_center/arc/arc_notification_view.h b/ash/system/message_center/arc/arc_notification_view.h
index d2ecbcc..b820e6a 100644
--- a/ash/system/message_center/arc/arc_notification_view.h
+++ b/ash/system/message_center/arc/arc_notification_view.h
@@ -52,6 +52,7 @@
   bool IsManuallyExpandedOrCollapsed() const override;
   void OnContainerAnimationStarted() override;
   void OnContainerAnimationEnded() override;
+  void OnSnoozeButtonPressed(const ui::Event& event) override;
 
   // views::SlideOutController::Delegate:
   void OnSlideChanged() override;
diff --git a/ash/system/message_center/arc/arc_notification_view_unittest.cc b/ash/system/message_center/arc/arc_notification_view_unittest.cc
index 39f71e29..ce0866d 100644
--- a/ash/system/message_center/arc/arc_notification_view_unittest.cc
+++ b/ash/system/message_center/arc/arc_notification_view_unittest.cc
@@ -5,10 +5,13 @@
 #include <memory>
 
 #include "ash/shell.h"
+#include "ash/system/message_center/arc/arc_notification_constants.h"
 #include "ash/system/message_center/arc/arc_notification_content_view.h"
 #include "ash/system/message_center/arc/arc_notification_item.h"
+#include "ash/system/message_center/arc/arc_notification_surface.h"
 #include "ash/system/message_center/arc/arc_notification_view.h"
 #include "ash/system/message_center/arc/mock_arc_notification_item.h"
+#include "ash/system/message_center/arc/mock_arc_notification_surface.h"
 #include "ash/test/ash_test_base.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
@@ -61,25 +64,21 @@
   void SetUp() override {
     AshTestBase::SetUp();
 
-    const std::string notification_id("notification id");
-    item_ = std::make_unique<MockArcNotificationItem>(notification_id);
+    item_ = std::make_unique<MockArcNotificationItem>(kDefaultNotificationKey);
     message_center::MessageViewFactory::SetCustomNotificationViewFactory(
         base::BindRepeating(
             &ArcNotificationViewTest::CreateCustomMessageViewForTest,
             base::Unretained(this), item_.get()));
 
-    notification_ = std::make_unique<Notification>(
-        message_center::NOTIFICATION_TYPE_CUSTOM, notification_id,
-        base::UTF8ToUTF16("title"), base::UTF8ToUTF16("message"), gfx::Image(),
-        base::UTF8ToUTF16("display source"), GURL(),
-        message_center::NotifierId(message_center::NotifierId::ARC_APPLICATION,
-                                   "test_app_id"),
-        message_center::RichNotificationData(), nullptr);
+    std::unique_ptr<Notification> notification = CreateSimpleNotification();
 
     notification_view_.reset(static_cast<ArcNotificationView*>(
-        message_center::MessageViewFactory::Create(*notification_, true)));
+        message_center::MessageViewFactory::Create(*notification, true)));
     notification_view_->set_owned_by_client();
-    UpdateNotificationViews();
+    surface_ =
+        std::make_unique<MockArcNotificationSurface>(kDefaultNotificationKey);
+    notification_view_->content_view_->SetSurface(surface_.get());
+    UpdateNotificationViews(*notification);
 
     views::Widget::InitParams init_params(
         views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
@@ -96,6 +95,16 @@
     EXPECT_EQ(widget, notification_view_->GetWidget());
   }
 
+  std::unique_ptr<Notification> CreateSimpleNotification() {
+    return std::make_unique<Notification>(
+        message_center::NOTIFICATION_TYPE_CUSTOM, kDefaultNotificationId,
+        base::UTF8ToUTF16("title"), base::UTF8ToUTF16("message"), gfx::Image(),
+        base::UTF8ToUTF16("display source"), GURL(),
+        message_center::NotifierId(message_center::NotifierId::ARC_APPLICATION,
+                                   "test_app_id"),
+        message_center::RichNotificationData(), nullptr);
+  }
+
   void TearDown() override {
     widget()->Close();
     notification_view_.reset();
@@ -120,10 +129,10 @@
     widget()->OnKeyEvent(&event2);
   }
 
-  void UpdateNotificationViews() {
+  void UpdateNotificationViews(const Notification& notification) {
     MessageCenter::Get()->AddNotification(
-        std::make_unique<Notification>(*notification()));
-    notification_view()->UpdateWithNotification(*notification());
+        std::make_unique<Notification>(notification));
+    notification_view()->UpdateWithNotification(notification);
   }
 
   float GetNotificationSlideAmount() const {
@@ -155,13 +164,17 @@
         ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE, dx, 0));
   }
 
-  Notification* notification() { return notification_.get(); }
   ArcNotificationContentView* content_view() {
     return notification_view_->content_view_;
   }
   views::Widget* widget() { return notification_view_->GetWidget(); }
   ArcNotificationView* notification_view() { return notification_view_.get(); }
 
+ protected:
+  const std::string kDefaultNotificationKey = "notification_id";
+  const std::string kDefaultNotificationId =
+      kArcNotificationIdPrefix + kDefaultNotificationKey;
+
  private:
   std::unique_ptr<message_center::MessageView> CreateCustomMessageViewForTest(
       ArcNotificationItem* item,
@@ -172,6 +185,7 @@
     return message_view;
   }
 
+  std::unique_ptr<MockArcNotificationSurface> surface_;
   std::unique_ptr<Notification> notification_;
   std::unique_ptr<ArcNotificationView> notification_view_;
 
@@ -200,7 +214,7 @@
   ui::ScopedAnimationDurationScaleMode zero_duration_scope(
       ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
 
-  std::string notification_id = notification()->id();
+  std::string notification_id(kDefaultNotificationId);
 
   BeginScroll();
   EXPECT_EQ(0.f, GetNotificationSlideAmount());
@@ -225,7 +239,7 @@
       ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
 
   notification_view()->SetIsNested();
-  std::string notification_id = notification()->id();
+  std::string notification_id(kDefaultNotificationId);
 
   BeginScroll();
   EXPECT_EQ(0.f, GetNotificationSlideAmount());
@@ -252,10 +266,11 @@
   ui::ScopedAnimationDurationScaleMode zero_duration_scope(
       ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
 
-  notification()->set_pinned(true);
+  std::unique_ptr<Notification> notification = CreateSimpleNotification();
+  notification->set_pinned(true);
   notification_view()->SetIsNested();
-  UpdateNotificationViews();
-  std::string notification_id = notification()->id();
+  UpdateNotificationViews(*notification);
+  std::string notification_id(kDefaultNotificationId);
 
   BeginScroll();
   EXPECT_EQ(0.f, GetNotificationSlideAmount());
@@ -267,10 +282,32 @@
   EXPECT_FALSE(IsRemoved(notification_id));
 }
 
+TEST_F(ArcNotificationViewTest, SnoozeButton) {
+  ui::ScopedAnimationDurationScaleMode zero_duration_scope(
+      ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
+
+  message_center::RichNotificationData rich_data;
+  rich_data.pinned = true;
+  rich_data.should_show_snooze_button = true;
+  std::unique_ptr<Notification> notification = std::make_unique<Notification>(
+      message_center::NOTIFICATION_TYPE_CUSTOM, kDefaultNotificationId,
+      base::UTF8ToUTF16("title"), base::UTF8ToUTF16("message"), gfx::Image(),
+      base::UTF8ToUTF16("display source"), GURL(),
+      message_center::NotifierId(message_center::NotifierId::ARC_APPLICATION,
+                                 "test_app_id"),
+      rich_data, nullptr);
+
+  UpdateNotificationViews(*notification);
+  notification_view()->SetIsNested();
+
+  EXPECT_NE(nullptr,
+            notification_view()->GetControlButtonsView()->snooze_button());
+}
+
 #endif  // defined(OS_CHROMEOS)
 
 TEST_F(ArcNotificationViewTest, PressBackspaceKey) {
-  std::string notification_id = notification()->id();
+  std::string notification_id(kDefaultNotificationId);
   content_view()->RequestFocus();
 
   ui::InputMethod* input_method = content_view()->GetInputMethod();
@@ -287,7 +324,7 @@
 }
 
 TEST_F(ArcNotificationViewTest, PressBackspaceKeyOnEditBox) {
-  std::string notification_id = notification()->id();
+  std::string notification_id(kDefaultNotificationId);
   content_view()->RequestFocus();
 
   ui::InputMethod* input_method = content_view()->GetInputMethod();
diff --git a/ash/system/message_center/arc/mock_arc_notification_item.h b/ash/system/message_center/arc/mock_arc_notification_item.h
index 3a17ed81..11b5ee9 100644
--- a/ash/system/message_center/arc/mock_arc_notification_item.h
+++ b/ash/system/message_center/arc/mock_arc_notification_item.h
@@ -40,6 +40,7 @@
   void Click() override {}
   void ToggleExpansion() override {}
   void OpenSettings() override {}
+  void OpenSnooze() override {}
   void IncrementWindowRefCount() override {}
   void DecrementWindowRefCount() override {}
   arc::mojom::ArcNotificationType GetNotificationType() const override;
diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn
index 04a9639..10ccd5e4 100644
--- a/build/config/BUILDCONFIG.gn
+++ b/build/config/BUILDCONFIG.gn
@@ -568,6 +568,10 @@
   ]
 }
 
+if (is_desktop_linux) {
+  default_compiler_configs += [ "//build/config/linux:export_dynamic" ]
+}
+
 # Debug/release-related defines.
 if (is_debug) {
   default_compiler_configs += [ "//build/config:debug" ]
diff --git a/build/config/linux/BUILD.gn b/build/config/linux/BUILD.gn
index e3488ab..6ca9b6a9 100644
--- a/build/config/linux/BUILD.gn
+++ b/build/config/linux/BUILD.gn
@@ -99,3 +99,12 @@
     ]
   }
 }
+
+# Ensures all exported symbols are added to the dynamic symbol table.  This is
+# necessary to expose Chrome's custom operator new() and operator delete() (and
+# other memory-related symbols) to libraries.  Otherwise, they might
+# (de)allocate memory on a different heap, which would spell trouble if pointers
+# to heap-allocated memory are passed over shared library boundaries.
+config("export_dynamic") {
+  ldflags = [ "-rdynamic" ]
+}
diff --git a/build/config/linux/pkg-config.py b/build/config/linux/pkg-config.py
index 5ef7322..3327152 100755
--- a/build/config/linux/pkg-config.py
+++ b/build/config/linux/pkg-config.py
@@ -199,7 +199,6 @@
   cflags = []
   libs = []
   lib_dirs = []
-  ldflags = []
 
   for flag in all_flags[:]:
     if len(flag) == 0 or MatchesAnyRegexp(flag, strip_out):
@@ -212,7 +211,9 @@
     elif flag[:2] == '-I':
       includes.append(RewritePath(flag[2:], prefix, sysroot))
     elif flag[:3] == '-Wl':
-      ldflags.append(flag)
+      # Don't allow libraries to control ld flags.  These should be specified
+      # only in build files.
+      pass
     elif flag == '-pthread':
       # Many libs specify "-pthread" which we don't need since we always include
       # this anyway. Removing it here prevents a bunch of duplicate inclusions
@@ -224,7 +225,7 @@
   # Output a GN array, the first one is the cflags, the second are the libs. The
   # JSON formatter prints GN compatible lists when everything is a list of
   # strings.
-  print json.dumps([includes, cflags, libs, lib_dirs, ldflags])
+  print json.dumps([includes, cflags, libs, lib_dirs])
   return 0
 
 
diff --git a/build/config/linux/pkg_config.gni b/build/config/linux/pkg_config.gni
index edf07528..53ee353a 100644
--- a/build/config/linux/pkg_config.gni
+++ b/build/config/linux/pkg_config.gni
@@ -113,7 +113,6 @@
     if (!defined(invoker.ignore_libs) || !invoker.ignore_libs) {
       libs = pkgresult[2]
       lib_dirs = pkgresult[3]
-      ldflags = pkgresult[4]
     }
 
     forward_variables_from(invoker,
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml
index 01508fa9..1ccd230 100644
--- a/chrome/android/java/res/values/dimens.xml
+++ b/chrome/android/java/res/values/dimens.xml
@@ -571,4 +571,8 @@
 
     <!-- Chip list dimensions -->
     <dimen name="chip_list_padding">2.5dp</dimen>
+
+    <!-- Download manager dimensions -->
+    <dimen name="download_manager_image_width">150dp</dimen>
+    <dimen name="download_manager_image_padding">1dp</dimen>
 </resources>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
index 04b32215..0b41c412 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -138,6 +138,7 @@
 import org.chromium.chrome.browser.util.AccessibilityUtil;
 import org.chromium.chrome.browser.util.ColorUtils;
 import org.chromium.chrome.browser.util.FeatureUtilities;
+import org.chromium.chrome.browser.util.MathUtils;
 import org.chromium.chrome.browser.vr_shell.VrIntentUtils;
 import org.chromium.chrome.browser.vr_shell.VrShellDelegate;
 import org.chromium.chrome.browser.webapps.AddToHomescreenManager;
@@ -164,6 +165,7 @@
 import org.chromium.ui.base.PageTransition;
 import org.chromium.ui.base.WindowAndroid;
 import org.chromium.ui.display.DisplayAndroid;
+import org.chromium.ui.display.DisplayUtil;
 import org.chromium.ui.widget.Toast;
 import org.chromium.webapk.lib.client.WebApkNavigationClient;
 import org.chromium.webapk.lib.client.WebApkValidator;
@@ -275,6 +277,7 @@
     private int mUiMode;
     private int mDensityDpi;
     private int mScreenWidthDp;
+    private int mScreenHeightDp;
     private Runnable mRecordMultiWindowModeScreenWidthRunnable;
 
     private final DiscardableReferencePool mReferencePool = new DiscardableReferencePool();
@@ -1071,6 +1074,8 @@
             if (intentTimestamp != -1) {
                 recordIntentToCreationTime(getOnCreateTimestampMs() - intentTimestamp);
             }
+
+            recordDisplayDimensions();
         });
 
         DeferredStartupHandler.getInstance().addDeferredTask(() -> {
@@ -1101,7 +1106,7 @@
         // If the Activity was launched in multi-window mode, record a user action and the screen
         // width.
         recordMultiWindowModeChangedUserAction(true);
-        recordMultiWindowModeScreenWidth();
+        recordMultiWindowModeScreenSize(true, true);
     }
 
     /**
@@ -1148,6 +1153,7 @@
             mDensityDpi = getResources().getDisplayMetrics().densityDpi;
         }
         mScreenWidthDp = config.screenWidthDp;
+        mScreenHeightDp = config.screenHeightDp;
     }
 
     @Override
@@ -1827,8 +1833,11 @@
             }
         }
 
-        if (newConfig.screenWidthDp != mScreenWidthDp) {
+        boolean widthChanged = newConfig.screenWidthDp != mScreenWidthDp;
+        boolean heightChanged = newConfig.screenHeightDp != mScreenHeightDp;
+        if (widthChanged || heightChanged) {
             mScreenWidthDp = newConfig.screenWidthDp;
+            mScreenHeightDp = newConfig.screenHeightDp;
             final Activity activity = this;
 
             if (mRecordMultiWindowModeScreenWidthRunnable != null) {
@@ -1842,7 +1851,7 @@
             mRecordMultiWindowModeScreenWidthRunnable = () -> {
                 mRecordMultiWindowModeScreenWidthRunnable = null;
                 if (MultiWindowUtils.getInstance().isInMultiWindowMode(activity)) {
-                    recordMultiWindowModeScreenWidth();
+                    recordMultiWindowModeScreenSize(widthChanged, heightChanged);
                 }
             };
             mHandler.postDelayed(mRecordMultiWindowModeScreenWidthRunnable,
@@ -2309,11 +2318,22 @@
     }
 
     /**
-     * Records UMA histograms for the current screen width. Should only be called when the activity
+     * Records UMA histograms for the current screen size. Should only be called when the activity
      * is in Android N multi-window mode.
+     * @param widthChanged Whether the screen width changed since this method was last called.
+     * @param heightChanged Whether the screen height changed since this method was last called.
      */
-    protected void recordMultiWindowModeScreenWidth() {
-        if (!isTablet()) return;
+    protected void recordMultiWindowModeScreenSize(boolean widthChanged, boolean heightChanged) {
+        if (widthChanged) {
+            RecordHistogram.recordSparseSlowlyHistogram("Android.MultiWindowMode.ScreenWidth",
+                    MathUtils.clamp(mScreenWidthDp, 200, 1200));
+        }
+        if (heightChanged) {
+            RecordHistogram.recordSparseSlowlyHistogram("Android.MultiWindowMode.ScreenHeight",
+                    MathUtils.clamp(mScreenHeightDp, 200, 1200));
+        }
+
+        if (!isTablet() || !widthChanged) return;
 
         RecordHistogram.recordBooleanHistogram(
                 "Android.MultiWindowMode.IsTabletScreenWidthBelow600",
@@ -2325,6 +2345,22 @@
         }
     }
 
+    /**
+     * Records histograms related to display dimensions.
+     */
+    private void recordDisplayDimensions() {
+        DisplayAndroid display = DisplayAndroid.getNonMultiDisplay(this);
+        int displayWidth = DisplayUtil.pxToDp(display, display.getDisplayWidth());
+        int displayHeight = DisplayUtil.pxToDp(display, display.getDisplayHeight());
+        int largestDisplaySize = displayWidth > displayHeight ? displayWidth : displayHeight;
+        int smallestDisplaySize = displayWidth < displayHeight ? displayWidth : displayHeight;
+
+        RecordHistogram.recordSparseSlowlyHistogram("Android.DeviceSize.SmallestDisplaySize",
+                MathUtils.clamp(smallestDisplaySize, 0, 1000));
+        RecordHistogram.recordSparseSlowlyHistogram("Android.DeviceSize.LargestDisplaySize",
+                MathUtils.clamp(largestDisplaySize, 200, 1200));
+    }
+
     @Override
     public boolean onActivityResultWithNative(int requestCode, int resultCode, Intent intent) {
         if (super.onActivityResultWithNative(requestCode, resultCode, intent)) return true;
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 714241e..9c1a8164 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
@@ -248,6 +248,7 @@
     public static final String SOLE_INTEGRATION = "SoleIntegration";
     public static final String SOUND_CONTENT_SETTING = "SoundContentSetting";
     public static final String SPANNABLE_INLINE_AUTOCOMPLETE = "SpannableInlineAutocomplete";
+    public static final String SUBRESOURCE_FILTER = "SubresourceFilter";
     public static final String QUERY_IN_OMNIBOX = "QueryInOmnibox";
     public static final String TAB_REPARENTING = "TabReparenting";
     public static final String TRUSTED_WEB_ACTIVITY = "TrustedWebActivity";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity2.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity2.java
index 6fed6bd..6662363 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity2.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity2.java
@@ -21,7 +21,7 @@
     @Override
     protected void onDeferredStartupForMultiWindowMode() {
         RecordUserAction.record("Android.MultiWindowMode.MultiInstance.Enter");
-        recordMultiWindowModeScreenWidth();
+        recordMultiWindowModeScreenSize(true, true);
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListView.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListView.java
index 95544c7..f0db02b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListView.java
@@ -5,10 +5,16 @@
 package org.chromium.chrome.browser.download.home.list;
 
 import android.content.Context;
-import android.support.v7.widget.LinearLayoutManager;
+import android.graphics.Rect;
+import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.GridLayoutManager.SpanSizeLookup;
 import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.ItemDecoration;
+import android.support.v7.widget.RecyclerView.Recycler;
+import android.support.v7.widget.RecyclerView.State;
 import android.view.View;
 
+import org.chromium.chrome.R;
 import org.chromium.chrome.browser.modelutil.RecyclerViewModelChangeProcessor;
 
 /**
@@ -17,12 +23,21 @@
  */
 class DateOrderedListView {
     private final DecoratedListItemModel mModel;
+
+    private final int mImageWidthPx;
+    private final int mImagePaddingPx;
+
     private final RecyclerView mView;
 
     /** Creates an instance of a {@link DateOrderedListView} representing {@code model}. */
     public DateOrderedListView(Context context, DecoratedListItemModel model) {
         mModel = model;
 
+        mImageWidthPx =
+                context.getResources().getDimensionPixelSize(R.dimen.download_manager_image_width);
+        mImagePaddingPx = context.getResources().getDimensionPixelOffset(
+                R.dimen.download_manager_image_padding);
+
         DateOrderedListViewBinder viewBinder = new DateOrderedListViewBinder();
         DateOrderedListViewAdapter adapter = new DateOrderedListViewAdapter(mModel, viewBinder);
         RecyclerViewModelChangeProcessor<DecoratedListItemModel, ListItemViewHolder>
@@ -33,8 +48,11 @@
         mView = new RecyclerView(context);
         mView.setHasFixedSize(true);
         mView.getItemAnimator().setChangeDuration(0);
-        mView.setLayoutManager(
-                new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false));
+        mView.getItemAnimator().setMoveDuration(0);
+        mView.setLayoutManager(new GridLayoutManagerImpl(context));
+        mView.addItemDecoration(new ItemDecorationImpl());
+
+        // Do the final hook up to the underlying data adapter.
         mView.setAdapter(adapter);
     }
 
@@ -42,4 +60,50 @@
     public View getView() {
         return mView;
     }
+
+    private class GridLayoutManagerImpl extends GridLayoutManager {
+        /** Creates an instance of a {@link GridLayoutManagerImpl}. */
+        public GridLayoutManagerImpl(Context context) {
+            super(context, 1 /* spanCount */, VERTICAL, false /* reverseLayout */);
+            setSpanSizeLookup(new SpanSizeLookupImpl());
+        }
+
+        // GridLayoutManager implementation.
+        @Override
+        public void onLayoutChildren(Recycler recycler, State state) {
+            assert getOrientation() == VERTICAL;
+
+            int availableWidth = getWidth() - mImagePaddingPx;
+            int columnWidth = mImageWidthPx - mImagePaddingPx;
+            setSpanCount(Math.max(1, availableWidth / columnWidth));
+
+            super.onLayoutChildren(recycler, state);
+        }
+
+        private class SpanSizeLookupImpl extends SpanSizeLookup {
+            // SpanSizeLookup implementation.
+            @Override
+            public int getSpanSize(int position) {
+                return ListUtils.getSpanSize(mModel.getItemAt(position), getSpanCount());
+            }
+        }
+    }
+
+    private class ItemDecorationImpl extends ItemDecoration {
+        // ItemDecoration implementation.
+        @Override
+        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {
+            int position = parent.getChildAdapterPosition(view);
+            if (position < 0 || position >= mModel.getItemCount()) return;
+
+            switch (ListUtils.getViewTypeForItem(mModel.getItemAt(position))) {
+                case ListUtils.IMAGE:
+                    outRect.left = mImagePaddingPx;
+                    outRect.right = mImagePaddingPx;
+                    outRect.top = mImagePaddingPx;
+                    outRect.bottom = mImagePaddingPx;
+                    break;
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListViewAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListViewAdapter.java
index 85ddfe8..69343364 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListViewAdapter.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListViewAdapter.java
@@ -6,13 +6,8 @@
 
 import android.support.v7.widget.RecyclerView;
 
-import org.chromium.chrome.browser.download.home.list.DateOrderedListViewBinder.ViewType;
-import org.chromium.chrome.browser.download.home.list.ListItem.DateListItem;
-import org.chromium.chrome.browser.download.home.list.ListItem.OfflineItemListItem;
-import org.chromium.chrome.browser.download.home.list.ListItem.ViewListItem;
+import org.chromium.chrome.browser.download.home.list.ListUtils.ViewType;
 import org.chromium.chrome.browser.modelutil.RecyclerViewAdapter;
-import org.chromium.components.offline_items_collection.OfflineItemFilter;
-import org.chromium.components.offline_items_collection.OfflineItemState;
 
 /**
  * A helper {@link RecyclerView.Adapter} implementation meant to glue a {@link ListItemModel}
@@ -36,35 +31,6 @@
     @Override
     public @ViewType int getItemViewType(int position) {
         ListItem item = mModel.getItemAt(position);
-
-        if (item instanceof ViewListItem) return DateOrderedListViewBinder.CUSTOM_VIEW;
-        if (item instanceof DateListItem) {
-            if (item instanceof OfflineItemListItem) {
-                OfflineItemListItem offlineItem = (OfflineItemListItem) item;
-
-                if (offlineItem.item.state == OfflineItemState.IN_PROGRESS) {
-                    return DateOrderedListViewBinder.IN_PROGRESS;
-                }
-
-                switch (offlineItem.item.filter) {
-                    case OfflineItemFilter.FILTER_VIDEO:
-                        return DateOrderedListViewBinder.VIDEO;
-                    case OfflineItemFilter.FILTER_IMAGE:
-                        return DateOrderedListViewBinder.IMAGE;
-                    case OfflineItemFilter.FILTER_ALL:
-                    case OfflineItemFilter.FILTER_PAGE:
-                    case OfflineItemFilter.FILTER_AUDIO:
-                    case OfflineItemFilter.FILTER_OTHER:
-                    case OfflineItemFilter.FILTER_DOCUMENT:
-                    default:
-                        return DateOrderedListViewBinder.GENERIC;
-                }
-            } else {
-                return DateOrderedListViewBinder.DATE;
-            }
-        }
-
-        assert false;
-        return DateOrderedListViewBinder.GENERIC;
+        return ListUtils.getViewTypeForItem(item);
     }
 }
\ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListViewBinder.java
index 239650c7..fbd8052 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListViewBinder.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListViewBinder.java
@@ -4,45 +4,31 @@
 
 package org.chromium.chrome.browser.download.home.list;
 
-import android.support.annotation.IntDef;
 import android.view.ViewGroup;
 
+import org.chromium.chrome.browser.download.home.list.ListUtils.ViewType;
 import org.chromium.chrome.browser.modelutil.RecyclerViewAdapter.ViewBinder;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
 /**
  * A {@link ViewBinder} responsible for connecting a {@link DateOrderedListModel} with a underlying
  * {@link ViewHolder}.
  */
 class DateOrderedListViewBinder implements ViewBinder<DecoratedListItemModel, ListItemViewHolder> {
-    /** The potential types of list items that could be displayed. */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({DATE, IN_PROGRESS, GENERIC, VIDEO, IMAGE, CUSTOM_VIEW})
-    public @interface ViewType {}
-    public static final int DATE = 0;
-    public static final int IN_PROGRESS = 1;
-    public static final int GENERIC = 2;
-    public static final int VIDEO = 3;
-    public static final int IMAGE = 4;
-    public static final int CUSTOM_VIEW = 5;
-
     // ViewBinder implementation.
     @Override
     public ListItemViewHolder onCreateViewHolder(ViewGroup parent, @ViewType int viewType) {
         switch (viewType) {
-            case DATE:
+            case ListUtils.DATE:
                 return new ListItemViewHolder.DateViewHolder(parent);
-            case IN_PROGRESS:
+            case ListUtils.IN_PROGRESS:
                 return new ListItemViewHolder.InProgressViewHolder(parent);
-            case GENERIC:
+            case ListUtils.GENERIC:
                 return new ListItemViewHolder.GenericViewHolder(parent);
-            case VIDEO:
+            case ListUtils.VIDEO:
                 return new ListItemViewHolder.VideoViewHolder(parent);
-            case IMAGE:
+            case ListUtils.IMAGE:
                 return new ListItemViewHolder.ImageViewHolder(parent);
-            case CUSTOM_VIEW:
+            case ListUtils.CUSTOM_VIEW:
                 return new ListItemViewHolder.CustomViewHolder(parent);
         }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/ListUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/ListUtils.java
new file mode 100644
index 0000000..1b3b04e
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/ListUtils.java
@@ -0,0 +1,84 @@
+// 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.
+
+package org.chromium.chrome.browser.download.home.list;
+
+import android.support.annotation.IntDef;
+
+import org.chromium.chrome.browser.download.home.list.ListItem.DateListItem;
+import org.chromium.chrome.browser.download.home.list.ListItem.OfflineItemListItem;
+import org.chromium.chrome.browser.download.home.list.ListItem.ViewListItem;
+import org.chromium.components.offline_items_collection.OfflineItemFilter;
+import org.chromium.components.offline_items_collection.OfflineItemState;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/** Utility methods for representing {@link ListItem}s in a {@link RecyclerView} list. */
+class ListUtils {
+    /** The potential types of list items that could be displayed. */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({DATE, IN_PROGRESS, GENERIC, VIDEO, IMAGE, CUSTOM_VIEW})
+    public @interface ViewType {}
+    public static final int DATE = 0;
+    public static final int IN_PROGRESS = 1;
+    public static final int GENERIC = 2;
+    public static final int VIDEO = 3;
+    public static final int IMAGE = 4;
+    public static final int CUSTOM_VIEW = 5;
+
+    private ListUtils() {}
+
+    /**
+     * Analyzes a {@link ListItem} and finds the most appropriate {@link ViewType} based on the
+     * current state.
+     * @param item The {@link ListItem} to determine the {@link ViewType} for.
+     * @return     The type of {@link ViewType} to use for a particular {@link ListItem}.
+     * @see        ViewType
+     */
+    public static @ViewType int getViewTypeForItem(ListItem item) {
+        if (item instanceof ViewListItem) return ListUtils.CUSTOM_VIEW;
+        if (item instanceof DateListItem) {
+            if (item instanceof OfflineItemListItem) {
+                OfflineItemListItem offlineItem = (OfflineItemListItem) item;
+
+                if (offlineItem.item.state == OfflineItemState.IN_PROGRESS) {
+                    return ListUtils.IN_PROGRESS;
+                }
+
+                switch (offlineItem.item.filter) {
+                    case OfflineItemFilter.FILTER_VIDEO:
+                        return ListUtils.VIDEO;
+                    case OfflineItemFilter.FILTER_IMAGE:
+                        return ListUtils.IMAGE;
+                    case OfflineItemFilter.FILTER_ALL:
+                    case OfflineItemFilter.FILTER_PAGE:
+                    case OfflineItemFilter.FILTER_AUDIO:
+                    case OfflineItemFilter.FILTER_OTHER:
+                    case OfflineItemFilter.FILTER_DOCUMENT:
+                    default:
+                        return ListUtils.GENERIC;
+                }
+            } else {
+                return ListUtils.DATE;
+            }
+        }
+
+        assert false;
+        return ListUtils.GENERIC;
+    }
+
+    /**
+     * Analyzes a {@link ListItem} and finds the best span size based on the current state.  Span
+     * size determines how many columns this {@link ListItem}'s {@link View} will take up in the
+     * overall list.
+     * @param item      The {@link ListItem} to determine the span size for.
+     * @param spanCount The maximum span amount of columns {@code item} can take up.
+     * @return          The number of columns {@code item} should take.
+     * @see             GridLayoutManager.SpanSizeLookup
+     */
+    public static int getSpanSize(ListItem item, int spanCount) {
+        return getViewTypeForItem(item) == IMAGE ? 1 : spanCount;
+    }
+}
\ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SiteSettingsCategory.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SiteSettingsCategory.java
index 361ec92..09fdfb3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SiteSettingsCategory.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SiteSettingsCategory.java
@@ -331,7 +331,7 @@
      * Returns whether the Ads category is enabled via an experiment flag.
      */
     public static boolean adsCategoryEnabled() {
-        return ChromeFeatureList.isEnabled("SubresourceFilterExperimentalUI");
+        return ChromeFeatureList.isEnabled(ChromeFeatureList.SUBRESOURCE_FILTER);
     }
 
     /**
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index c7706ed7e..9299e6b4 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -458,6 +458,7 @@
   "java/src/org/chromium/chrome/browser/download/home/list/ListItem.java",
   "java/src/org/chromium/chrome/browser/download/home/list/ListItemModel.java",
   "java/src/org/chromium/chrome/browser/download/home/list/ListItemViewHolder.java",
+  "java/src/org/chromium/chrome/browser/download/home/list/ListUtils.java",
   "java/src/org/chromium/chrome/browser/download/home/list/UiUtils.java",
   "java/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorFactory.java",
   "java/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorNotificationBridgeUi.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/SubresourceFilterTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/SubresourceFilterTest.java
index fe8f66c..578ad1e2 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/SubresourceFilterTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/SubresourceFilterTest.java
@@ -37,11 +37,7 @@
  * End to end tests of SubresourceFilter ad filtering on Android.
  */
 @RunWith(ChromeJUnit4ClassRunner.class)
-@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE,
-        "enable-features=SubresourceFilter<SB,SubresourceFilterExperimentalUI",
-        "force-fieldtrials=SB/Enabled",
-        "force-fieldtrial-params=SB.Enabled:enable_presets/liverun_on_better_ads_violating_sites"})
-
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
 public final class SubresourceFilterTest {
     @Rule
     public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index 7343bd6..6b321fd 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-69.0.3446.0_rc-r1.afdo.bz2
\ No newline at end of file
+chromeos-chrome-amd64-69.0.3447.0_rc-r1.afdo.bz2
\ No newline at end of file
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index 36c460d0..ee9ff6c 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -4302,8 +4302,8 @@
     Device Location
   </message>
   <!-- Administrator facing strings for Active Directory screens. -->
-  <message name="IDS_AD_MACHINE_NAME_INPUT_LABEL" desc="Admin-facing. Label for machine name input field on the AD domain join screen. User should tell us the name of his machine.">
-    Chromebook machine name
+  <message name="IDS_AD_MACHINE_NAME_INPUT_LABEL" desc="Admin-facing. Label for device name input field on the AD domain join screen. User should tell us the name of his device.">
+    Chromebook device name
   </message>
   <message name="IDS_AD_DOMAIN_JOIN_WELCOME_MESSAGE" desc="Admin-facing. Welcome message on the AD domain join screen.">
     Join device to domain
@@ -4312,7 +4312,7 @@
     More options
   </message>
   <message name="IDS_AD_ORG_UNIT_HINT" desc="Admin-facing. Hint for the Active Directory Organizational units input on the 'More options' dialog.">
-    Computer OU (e.g. OU=Chromebooks,DC=example,DC=com)
+    Device OU (e.g. OU=Chromebooks,DC=example,DC=com)
   </message>
   <message name="IDS_AD_ENCRYPTION_SELECTION_SELECT" desc="Admin-facing. Title for kerberos encryption types selection.">
     Select encryption types
@@ -4338,38 +4338,35 @@
   <message name="IDS_AD_DOMAIN_JOIN_UNKNOWN_ERROR" desc="Admin-facing. Default error text on the Active Directory join screen">
     Oops!  Something went wrong when trying to join the domain. Please try again.
   </message>
-  <message name="IDS_AD_MACHINENAME_INVALID" desc="Admin-facing. Alert message about invalid machine name">
-    Invalid machine name
+  <message name="IDS_AD_MACHINENAME_INVALID" desc="Admin-facing alert message. Admin entered a bad device name.">
+    The device name is invalid. Enter a valid device name to try again.
   </message>
-  <message name="IDS_AD_MACHINENAME_TOO_LONG" desc="Admin-facing. Alert message about too long machine name">
-    Machine name too long
+  <message name="IDS_AD_MACHINENAME_TOO_LONG" desc="Admin-facing alert message. Admin entered a device name that was too long.">
+    The device name is too long. Enter a shorter name to try again.
   </message>
-  <message name="IDS_AD_USER_DENIED_TO_JOIN_MACHINE" desc="Admin-facing. Alert message user was denied to join machine to the domain">
-    Failed to join the machine to the domain. This might be due to insufficient privileges for your account on the server.
+  <message name="IDS_AD_USER_DENIED_TO_JOIN_MACHINE" desc="Admin-facing alert message. Admin doesn’t have privileges to add devices to the domain. 'Devices' refers to Chromebook computers. 'Domain' is the Windows domain that accounts are registered to.">
+    Can't join the domain. Check your account to see if you have sufficient privileges to add devices.
   </message>
-  <message name="IDS_AD_USER_HIT_JOIN_QUOTA" desc="Admin-facing. Alert message that user can't add more machines to the domain">
-    Failed to join the machine to the domain. This might be due to exceeding the maximum number of allowed machine joins for your account on the server.
+  <message name="IDS_AD_USER_HIT_JOIN_QUOTA" desc="Admin-facing alert message. Administrator has reached the limit of devices that can be added.">
+    Can't join the device to the domain. Make sure you haven’t exceeded the number of devices you can add.
   </message>
-  <message name="IDS_AD_OU_DOES_NOT_EXIST" desc="Admin-facing. Alert message that user joins the machine to non-existing organizational unit.">
-    Failed to join the machine to the domain. Organizational unit does not exist.
+  <message name="IDS_AD_OU_DOES_NOT_EXIST" desc="Admin-facing alert message.  Admin entered the name of the organizational unit incorrectly.">
+    Can’t find an organizational unit with that name. Please try again.
   </message>
-  <message name="IDS_AD_OU_INVALID" desc="Admin-facing. Alert message that user joins the machine to invalid organizational unit.">
-    Failed to join the machine to the domain. Organizational unit is invalid.
+  <message name="IDS_AD_OU_ACCESS_DENIED" desc="Admin-facing alert message. The admin is using an account that doesn’t have privileges to add devices to the organizational unit.">
+    Can't join the device to the domain. Check your account to make sure you have privileges to add devices.
   </message>
-  <message name="IDS_AD_OU_ACCESS_DENIED" desc="Admin-facing. Alert message that user does not have rights to join the machine to specified organizational unit.">
-    Failed to join the machine to the domain. This might be due to insufficient privileges for your account for the organizational unit.
+  <message name="IDS_AD_OU_SETTING_FAILED" desc="Admin-facing alert message. Settings for the organizational unit are incorrect.">
+    Can’t join the domain. Make sure the settings are correct for the organizational unit.
   </message>
-  <message name="IDS_AD_OU_SETTING_FAILED" desc="Admin-facing. Alert message that user could not join the machine to specified organizational unit due to unknown reason.">
-    Failed to join the machine to the domain. This might be due to issues with the organizational unit.
-  </message>
-  <message name="IDS_AD_NOT_SUPPORTED_ENCRYPTION" desc="Admin-facing. Alert message that user could not join the machine to due to not supported encryption types.">
-    Can't join the machine to the domain. The server does not support specified Kerberos encryption types. Check "More options" for encryption settings.
+  <message name="IDS_AD_NOT_SUPPORTED_ENCRYPTION" desc="Admin-facing. Alert message that user could not join the device to due to not supported encryption types.">
+    Can't join the device to the domain. The server does not support specified Kerberos encryption types. Check "More options" for encryption settings.
   </message>
   <message name="IDS_AD_BOARD_NOT_SUPPORTED" desc="Admin-facing. Alert message that the Chromebook model is not supported for Active Directory">
     Chrome <ph name="MS_AD_NAME">Microsoft® Active Directory®</ph> integration is only supported on x86_64 platforms. Chromebooks built on top of an ARM or x86 platform do not support this functionality.
   </message>
   <!-- User facing strings for Active Directory screens. -->
-  <message name="IDS_AD_DOMAIN_AUTH_WELCOME_MESSAGE" desc="Welcome message on the AD Authentication user screen. Include the domain (realm) the machine joined to.">
+  <message name="IDS_AD_DOMAIN_AUTH_WELCOME_MESSAGE" desc="Welcome message on the AD Authentication user screen. Include the domain (realm) the device joined to.">
     Sign in to <ph name="REALM">$1<ex>example.com</ex></ph>
   </message>
   <message name="IDS_AD_ENROLLMENT_LOGIN_USER" desc="Label for userPrincipalName input field on the AD domain join user screen. Looks like user@example.com where example.com is the realm.">
@@ -4418,7 +4415,7 @@
     The username and password you entered do not match
   </message>
   <message name="IDS_AD_PASSWORD_EXPIRED" desc="Alert message about expired password in the Active Directory">
-    Oops!  Looks like your password expired. Please renew it on another machine and try again.
+    Oops!  Looks like your password expired. Please renew it on another device and try again.
   </message>
   <message name="IDS_AD_AUTH_NETWORK_ERROR" desc="Error message to show when there is a problem contacting the logon server when authenticating for Active Directory enrollment.">
     Oops!  There was a problem contacting the logon server. Please check your network connection and the domain name, then try again.
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 7e64395..f675cb42 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -10156,9 +10156,6 @@
     <message name="IDS_ALWAYS_ALLOW_ADS" desc="Explanation associated with a toggle to allow ads after ads have been blocked on the page. To be used on pages where the ad blocking UI is governed by a persistent permissions-based whitelist.">
       Always allow ads on this site
     </message>
-    <message name="IDS_ALLOW_ADS" desc="Explanation associated with a toggle to allow ads after ads have been blocked on the page. To be used on pages where the ad blocking UI is governed by a per-tab whitelist.">
-      Allow ads on this site
-    </message>
     <message name="IDS_BLOCKED_ADS_INFOBAR_MESSAGE" desc="The mini infobar message shown to users on Android when Chrome has blocked ads on the site because the site tends to show intrusive ads. Will be presented as a sentence, next to a Details link to expand the infobar.">
       Ads blocked.
     </message>
diff --git a/chrome/app/vector_icons/sync_paused.icon b/chrome/app/vector_icons/sync_paused.icon
index 78b7b09..6eb251b 100644
--- a/chrome/app/vector_icons/sync_paused.icon
+++ b/chrome/app/vector_icons/sync_paused.icon
@@ -3,50 +3,38 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 2, 2,
-R_H_LINE_TO, 12,
-R_V_LINE_TO, 12,
-H_LINE_TO, 2,
-V_LINE_TO, 2,
+MOVE_TO, 6.67f, 4.23f,
+V_LINE_TO, 2.84f,
+R_ARC_TO, 5.48f, 5.48f, 0, 0, 0, -1.49f, 0.64f,
+R_LINE_TO, 0.97f, 0.97f,
+R_CUBIC_TO, 0.17f, -0.08f, 0.33f, -0.16f, 0.51f, -0.22f,
 CLOSE,
-R_MOVE_TO, 0, 0,
-R_H_LINE_TO, 12,
-R_V_LINE_TO, 12,
-H_LINE_TO, 2,
-V_LINE_TO, 2,
+R_MOVE_TO, -4.76f, -0.63f,
+LINE_TO, 3.48f, 5.18f,
+R_ARC_TO, 5.28f, 5.28f, 0, 0, 0, 0.76f, 6.58f,
+R_LINE_TO, -1.57f, 1.57f,
+R_H_LINE_TO, 4,
+R_V_LINE_TO, -4,
+R_LINE_TO, -1.49f, 1.49f,
+ARC_TO, 4, 4, 0, 0, 1, 4, 8,
+R_CUBIC_TO, 0, -0.67f, 0.17f, -1.29f, 0.45f, -1.85f,
+LINE_TO, 9.84f, 11.54f,
+R_ARC_TO, 3.53f, 3.53f, 0, 0, 1, -0.51f, 0.23f,
+R_V_LINE_TO, 1.39f,
+R_ARC_TO, 5.48f, 5.48f, 0, 0, 0, 1.49f, -0.64f,
+R_LINE_TO, 1.57f, 1.57f,
+R_LINE_TO, 0.85f, -0.85f,
+LINE_TO, 2.76f, 2.76f,
+R_LINE_TO, -0.85f, 0.85f,
 CLOSE,
-MOVE_TO, 7, 5.18f,
-V_LINE_TO, 4.13f,
-R_CUBIC_TO, -0.4f, 0.11f, -0.77f, 0.27f, -1.11f, 0.48f,
-R_LINE_TO, 0.73f, 0.73f,
-R_CUBIC_TO, 0.13f, -0.06f, 0.25f, -0.12f, 0.39f, -0.16f,
-CLOSE,
-R_MOVE_TO, -3.57f, -0.47f,
-R_LINE_TO, 1.18f, 1.18f,
-R_ARC_TO, 3.96f, 3.96f, 0, 0, 0, 0.57f, 4.93f,
-LINE_TO, 4, 12,
-R_H_LINE_TO, 3,
-V_LINE_TO, 9,
-R_LINE_TO, -1.12f, 1.12f,
-ARC_TO, 3, 3, 0, 0, 1, 5, 8,
-R_CUBIC_TO, 0, -0.5f, 0.13f, -0.97f, 0.34f, -1.38f,
-R_LINE_TO, 4.04f, 4.04f,
-R_CUBIC_TO, -0.12f, 0.07f, -0.25f, 0.13f, -0.38f, 0.17f,
-R_V_LINE_TO, 1.05f,
-R_CUBIC_TO, 0.4f, -0.1f, 0.78f, -0.27f, 1.12f, -0.48f,
-R_LINE_TO, 1.18f, 1.18f,
-R_LINE_TO, 0.64f, -0.63f,
-LINE_TO, 4.07f, 4.07f,
-R_LINE_TO, -0.64f, 0.64f,
-CLOSE,
-MOVE_TO, 12, 4,
-H_LINE_TO, 9,
-R_V_LINE_TO, 3,
-R_LINE_TO, 1.12f, -1.12f,
-R_CUBIC_TO, 0.54f, 0.55f, 0.88f, 1.29f, 0.88f, 2.12f,
-R_CUBIC_TO, 0, 0.5f, -0.12f, 0.97f, -0.34f, 1.39f,
-R_LINE_TO, 0.73f, 0.73f,
-R_ARC_TO, 3.96f, 3.96f, 0, 0, 0, -0.57f, -4.93f,
-LINE_TO, 12, 4,
+R_MOVE_TO, 11.43f, -0.94f,
+R_H_LINE_TO, -4,
+R_V_LINE_TO, 4,
+R_LINE_TO, 1.49f, -1.49f,
+ARC_TO, 4, 4, 0, 0, 1, 12, 8,
+R_CUBIC_TO, 0, 0.67f, -0.17f, 1.29f, -0.45f, 1.85f,
+R_LINE_TO, 0.97f, 0.97f,
+R_ARC_TO, 5.28f, 5.28f, 0, 0, 0, -0.76f, -6.58f,
+R_LINE_TO, 1.57f, -1.57f,
 CLOSE
 
diff --git a/chrome/app/vector_icons/sync_problem.icon b/chrome/app/vector_icons/sync_problem.icon
index e512d9f..0361e3d 100644
--- a/chrome/app/vector_icons/sync_problem.icon
+++ b/chrome/app/vector_icons/sync_problem.icon
@@ -2,37 +2,38 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-MOVE_TO, 6, 24,
-R_CUBIC_TO, 0, 4.42f, 1.82f, 8.4f, 4.71f, 11.29f,
-LINE_TO, 6, 40,
-R_H_LINE_TO, 12,
-V_LINE_TO, 28,
-R_LINE_TO, -4.47f, 4.47f,
-CUBIC_TO, 11.35f, 30.3f, 10, 27.31f, 10, 24,
-R_CUBIC_TO, 0, -5.22f, 3.34f, -9.65f, 8, -11.3f,
-V_LINE_TO, 8.52f,
-CUBIC_TO, 11.1f, 10.3f, 6, 16.55f, 6, 24,
-CLOSE,
-R_MOVE_TO, 16, 10,
+CANVAS_DIMENSIONS, 16,
+MOVE_TO, 2, 8,
+R_CUBIC_TO, 0, 1.47f, 0.61f, 2.8f, 1.57f, 3.76f,
+LINE_TO, 2, 13.33f,
 R_H_LINE_TO, 4,
 R_V_LINE_TO, -4,
+R_LINE_TO, -1.49f, 1.49f,
+ARC_TO, 4, 4, 0, 0, 1, 3.33f, 8,
+R_CUBIC_TO, 0, -1.74f, 1.11f, -3.22f, 2.67f, -3.77f,
+V_LINE_TO, 2.84f,
+ARC_TO, 5.33f, 5.33f, 0, 0, 0, 2, 8,
+CLOSE,
+R_MOVE_TO, 5.33f, 3.33f,
+R_H_LINE_TO, 1.33f,
+V_LINE_TO, 10,
+H_LINE_TO, 7.33f,
+R_V_LINE_TO, 1.33f,
+CLOSE,
+MOVE_TO, 14, 2.67f,
 R_H_LINE_TO, -4,
 R_V_LINE_TO, 4,
+R_LINE_TO, 1.49f, -1.49f,
+ARC_TO, 4, 4, 0, 0, 1, 12.67f, 8,
+R_CUBIC_TO, 0, 1.74f, -1.11f, 3.22f, -2.67f, 3.77f,
+R_V_LINE_TO, 1.39f,
+ARC_TO, 5.33f, 5.33f, 0, 0, 0, 14, 8,
+R_CUBIC_TO, 0, -1.47f, -0.61f, -2.8f, -1.57f, -3.76f,
+LINE_TO, 14, 2.67f,
 CLOSE,
-MOVE_TO, 42, 8,
-H_LINE_TO, 30,
-R_V_LINE_TO, 12,
-R_LINE_TO, 4.47f, -4.47f,
-CUBIC_TO, 36.65f, 17.7f, 38, 20.69f, 38, 24,
-R_CUBIC_TO, 0, 5.22f, -3.34f, 9.65f, -8, 11.3f,
-R_V_LINE_TO, 4.17f,
-CUBIC_TO, 36.9f, 37.7f, 42, 31.45f, 42, 24,
-R_CUBIC_TO, 0, -4.42f, -1.82f, -8.4f, -4.71f, -11.29f,
-LINE_TO, 42, 8,
-CLOSE,
-MOVE_TO, 22, 26,
-R_H_LINE_TO, 4,
-V_LINE_TO, 14,
-R_H_LINE_TO, -4,
-R_V_LINE_TO, 12,
+R_MOVE_TO, -6.67f, 6,
+R_H_LINE_TO, 1.33f,
+R_V_LINE_TO, -4,
+H_LINE_TO, 7.33f,
+R_V_LINE_TO, 4,
 CLOSE
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc
index b35d6f9..98a7f4a 100644
--- a/chrome/browser/android/chrome_feature_list.cc
+++ b/chrome/browser/android/chrome_feature_list.cc
@@ -148,7 +148,7 @@
     &password_manager::features::kPasswordSearchMobile,
     &password_manager::features::kPasswordsKeyboardAccessory,
     &signin::kUnifiedConsent,
-    &subresource_filter::kSafeBrowsingSubresourceFilterExperimentalUI,
+    &subresource_filter::kSafeBrowsingSubresourceFilter,
 };
 
 const base::Feature* FindFeatureExposedToJava(const std::string& feature_name) {
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index db3d8c1..249e5e4b 100644
--- a/chrome/browser/browser_process_impl.cc
+++ b/chrome/browser/browser_process_impl.cc
@@ -104,6 +104,7 @@
 #include "components/previews/core/previews_features.h"
 #include "components/rappor/public/rappor_utils.h"
 #include "components/rappor/rappor_service_impl.h"
+#include "components/sessions/core/session_id_generator.h"
 #include "components/signin/core/browser/profile_management_switches.h"
 #include "components/subresource_filter/content/browser/content_ruleset_service.h"
 #include "components/subresource_filter/core/browser/ruleset_service.h"
@@ -425,6 +426,8 @@
   if (webrtc_log_uploader_)
     webrtc_log_uploader_->StartShutdown();
 
+  sessions::SessionIdGenerator::GetInstance()->Shutdown();
+
   if (local_state_)
     local_state_->CommitPendingWrite();
 
@@ -1085,6 +1088,8 @@
       local_state_path, local_state_task_runner_.get(), policy_service(),
       std::move(pref_registry), false, std::move(delegate));
   DCHECK(local_state_);
+
+  sessions::SessionIdGenerator::GetInstance()->Init(local_state_.get());
 }
 
 void BrowserProcessImpl::PreCreateThreads(
diff --git a/chrome/browser/captive_portal/captive_portal_tab_helper_unittest.cc b/chrome/browser/captive_portal/captive_portal_tab_helper_unittest.cc
index 93c8da2..187f990 100644
--- a/chrome/browser/captive_portal/captive_portal_tab_helper_unittest.cc
+++ b/chrome/browser/captive_portal/captive_portal_tab_helper_unittest.cc
@@ -138,6 +138,7 @@
 
     EXPECT_CALL(mock_reloader(), OnAbort()).Times(1);
     navigation->Fail(net::ERR_TIMED_OUT);
+    navigation->AbortCommit();
     content::RenderFrameHostTester::For(navigation->GetFinalRenderFrameHost())
         ->SimulateNavigationStop();
 
diff --git a/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager.cc b/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager.cc
index 0fe96bec..d538c2f2 100644
--- a/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager.cc
+++ b/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager.cc
@@ -99,7 +99,6 @@
   StartObserveNetwork();
   account_id_ = user->GetAccountId();
   GetUserStatus();
-  GetUserKerberosFiles();
 
   // Setting environment variables for GSSAPI library.
   std::unique_ptr<base::Environment> env(base::Environment::Create());
@@ -374,17 +373,6 @@
   return base::Singleton<AuthPolicyCredentialsManagerFactory>::get();
 }
 
-// static
-KeyedService*
-AuthPolicyCredentialsManagerFactory::BuildForProfileIfActiveDirectory(
-    Profile* profile) {
-  const user_manager::User* user =
-      chromeos::ProfileHelper::Get()->GetUserByProfile(profile);
-  if (!user || !user->IsActiveDirectoryUser())
-    return nullptr;
-  return GetInstance()->GetServiceForBrowserContext(profile, true /* create */);
-}
-
 AuthPolicyCredentialsManagerFactory::AuthPolicyCredentialsManagerFactory()
     : BrowserContextKeyedServiceFactory(
           "AuthPolicyCredentialsManager",
@@ -392,9 +380,21 @@
 
 AuthPolicyCredentialsManagerFactory::~AuthPolicyCredentialsManagerFactory() {}
 
+bool AuthPolicyCredentialsManagerFactory::ServiceIsCreatedWithBrowserContext()
+    const {
+  return true;
+}
+
 KeyedService* AuthPolicyCredentialsManagerFactory::BuildServiceInstanceFor(
     content::BrowserContext* context) const {
+  // UserManager is usually not initialized in tests.
+  if (!user_manager::UserManager::IsInitialized())
+    return nullptr;
   Profile* profile = Profile::FromBrowserContext(context);
+  const user_manager::User* user =
+      chromeos::ProfileHelper::Get()->GetUserByProfile(profile);
+  if (!user || !user->IsActiveDirectoryUser())
+    return nullptr;
   return new AuthPolicyCredentialsManager(profile);
 }
 
diff --git a/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager.h b/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager.h
index 7297148..db91b7c 100644
--- a/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager.h
+++ b/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager.h
@@ -131,18 +131,18 @@
  public:
   static AuthPolicyCredentialsManagerFactory* GetInstance();
 
-  // Returns nullptr in case profile is not Active Directory. Otherwise returns
-  // valid AuthPolicyCredentialsManager. Lifetime is managed by
-  // BrowserContextKeyedServiceFactory.
-  static KeyedService* BuildForProfileIfActiveDirectory(Profile* profile);
-
  private:
   friend struct base::DefaultSingletonTraits<
       AuthPolicyCredentialsManagerFactory>;
+  friend class AuthPolicyCredentialsManagerTest;
 
   AuthPolicyCredentialsManagerFactory();
   ~AuthPolicyCredentialsManagerFactory() override;
 
+  bool ServiceIsCreatedWithBrowserContext() const override;
+
+  // Returns nullptr in case profile is not Active Directory. Otherwise returns
+  // valid AuthPolicyCredentialsManager.
   KeyedService* BuildServiceInstanceFor(
       content::BrowserContext* context) const override;
 
diff --git a/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager_unittest.cc b/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager_unittest.cc
index 3fef6ab..8d02676 100644
--- a/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager_unittest.cc
+++ b/chrome/browser/chromeos/authpolicy/auth_policy_credentials_manager_unittest.cc
@@ -28,9 +28,10 @@
 
 namespace {
 
-const char kProfileSigninNotificationId[] = "chrome://settings/signin/";
-const char kDisplayName[] = "DisplayName";
-const char kGivenName[] = "Given Name";
+constexpr char kProfileSigninNotificationId[] = "chrome://settings/signin/";
+constexpr char kProfileEmail[] = "user@example.com";
+constexpr char kDisplayName[] = "DisplayName";
+constexpr char kGivenName[] = "Given Name";
 
 MATCHER_P(UserAccountDataEq, value, "Compares two UserAccountData") {
   const user_manager::UserManager::UserAccountData& expected_data = value;
@@ -54,22 +55,24 @@
     fake_auth_policy_client()->DisableOperationDelayForTesting();
 
     TestingProfile::Builder profile_builder;
-    profile_builder.SetProfileName("user@gmail.com");
-    profile_ = profile_builder.Build();
-    account_id_ = AccountId::AdFromUserEmailObjGuid(
-        profile()->GetProfileUserName(), "1234567890");
+    profile_builder.SetProfileName(kProfileEmail);
+    account_id_ =
+        AccountId::AdFromUserEmailObjGuid(kProfileEmail, "1234567890");
     mock_user_manager()->AddUser(account_id_);
-    display_service_ =
-        std::make_unique<NotificationDisplayServiceTester>(profile());
 
     base::RunLoop run_loop;
     fake_auth_policy_client()->set_on_get_status_closure(
         run_loop.QuitClosure());
 
-    auth_policy_credentials_manager_ = static_cast<
-        AuthPolicyCredentialsManager*>(
-        AuthPolicyCredentialsManagerFactory::BuildForProfileIfActiveDirectory(
-            profile()));
+    profile_ = profile_builder.Build();
+    display_service_ =
+        std::make_unique<NotificationDisplayServiceTester>(profile());
+
+    auth_policy_credentials_manager_ =
+        static_cast<AuthPolicyCredentialsManager*>(
+            AuthPolicyCredentialsManagerFactory::GetInstance()
+                ->GetServiceForBrowserContext(profile(), false /* create */));
+    EXPECT_TRUE(auth_policy_credentials_manager_);
 
     EXPECT_CALL(*mock_user_manager(),
                 SaveForceOnlineSignin(account_id(), false));
diff --git a/chrome/browser/chromeos/crostini/crostini_manager.cc b/chrome/browser/chromeos/crostini/crostini_manager.cc
index 3f41992a..fc0b16c 100644
--- a/chrome/browser/chromeos/crostini/crostini_manager.cc
+++ b/chrome/browser/chromeos/crostini/crostini_manager.cc
@@ -744,31 +744,28 @@
     Profile* profile,
     const std::string& vm_name,
     const std::string& container_name) {
-  std::string container_username = ContainerUserNameForProfile(profile);
   std::string vsh_crosh = base::StringPrintf(
       "chrome-extension://%s/html/crosh.html?command=vmshell",
       kCrostiniCroshBuiltinAppId);
   std::string vm_name_param = net::EscapeQueryParamValue(
       base::StringPrintf("--vm_name=%s", vm_name.c_str()), false);
+  std::string container_name_param = net::EscapeQueryParamValue(
+      base::StringPrintf("--target_container=%s", container_name.c_str()),
+      false);
   std::string owner_id_param = net::EscapeQueryParamValue(
       base::StringPrintf("--owner_id=%s",
                          CryptohomeIdForProfile(profile).c_str()),
       false);
-  std::string lxd_dir =
-      net::EscapeQueryParamValue("LXD_DIR=/mnt/stateful/lxd", false);
-  std::string lxd_conf =
-      net::EscapeQueryParamValue("LXD_CONF=/mnt/stateful/lxd_conf", false);
+
+  std::vector<base::StringPiece> pieces = {
+      vsh_crosh, vm_name_param, container_name_param, owner_id_param};
+
+  GURL vsh_in_crosh_url(base::JoinString(pieces, "&args[]="));
+
   const extensions::Extension* crosh_extension =
       extensions::ExtensionRegistry::Get(profile)->GetInstalledExtension(
           kCrostiniCroshBuiltinAppId);
 
-  std::vector<base::StringPiece> pieces = {
-      vsh_crosh,      vm_name_param, owner_id_param,     "--",
-      lxd_dir,        lxd_conf,      "run_container.sh", "--container_name",
-      container_name, "--user",      container_username, "--shell"};
-
-  GURL vsh_in_crosh_url(base::JoinString(pieces, "&args[]="));
-
   AppLaunchParams launch_params(
       profile, crosh_extension, extensions::LAUNCH_CONTAINER_WINDOW,
       WindowOpenDisposition::NEW_WINDOW, extensions::SOURCE_APP_LAUNCHER);
diff --git a/chrome/browser/chromeos/cryptauth/gcm_device_info_provider_impl.cc b/chrome/browser/chromeos/cryptauth/gcm_device_info_provider_impl.cc
index 97f89b1..f713081 100644
--- a/chrome/browser/chromeos/cryptauth/gcm_device_info_provider_impl.cc
+++ b/chrome/browser/chromeos/cryptauth/gcm_device_info_provider_impl.cc
@@ -46,6 +46,16 @@
     // phones/tablets, but it must be set due to server API verification.
     gcm_device_info.set_device_display_diagonal_mils(0);
 
+    // Set all supported features.
+    gcm_device_info.add_supported_software_features(
+        cryptauth::SoftwareFeature::BETTER_TOGETHER_CLIENT);
+    gcm_device_info.add_supported_software_features(
+        cryptauth::SoftwareFeature::EASY_UNLOCK_CLIENT);
+    gcm_device_info.add_supported_software_features(
+        cryptauth::SoftwareFeature::MAGIC_TETHER_CLIENT);
+    gcm_device_info.add_supported_software_features(
+        cryptauth::SoftwareFeature::SMS_CONNECT_CLIENT);
+
     return gcm_device_info;
   }());
 
diff --git a/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc b/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc
index d7b7eb5ad..34463fc 100644
--- a/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc
+++ b/chrome/browser/chromeos/login/existing_user_controller_browsertest.cc
@@ -116,6 +116,75 @@
   }
 }
 
+std::string GetKerberosConfigFileName() {
+  std::unique_ptr<base::Environment> env(base::Environment::Create());
+  std::string config_file;
+  EXPECT_TRUE(env->GetVar("KRB5_CONFIG", &config_file));
+  return config_file;
+}
+
+std::string GetKerberosCredentialsCacheFileName() {
+  std::unique_ptr<base::Environment> env(base::Environment::Create());
+  std::string creds_file;
+  EXPECT_TRUE(env->GetVar("KRB5CCNAME", &creds_file));
+  EXPECT_EQ(kKrb5CCFilePrefix, creds_file.substr(0, strlen(kKrb5CCFilePrefix)));
+  return creds_file.substr(strlen(kKrb5CCFilePrefix));
+}
+
+// Helper class to wait when both Kerberos credentials cache and config file
+// changed.
+class KerberosFilesChangeWaiter {
+ public:
+  // If |files_must_exist| is true and a file already exists the class does not
+  // wait when it changes.
+  explicit KerberosFilesChangeWaiter(bool files_must_exist) {
+    barrier_closure_ = base::BarrierClosure(2, loop_.QuitClosure());
+
+    watch_callback_ = base::BindRepeating(
+        [](const base::RepeatingClosure& barrier_closure,
+           const base::FilePath& path, bool error) -> void {
+          EXPECT_FALSE(error);
+          barrier_closure.Run();
+        },
+        barrier_closure_);
+
+    config_watcher_ = std::make_unique<base::FilePathWatcher>();
+    MaybeStartWatch(&config_watcher_,
+                    base::FilePath(GetKerberosConfigFileName()),
+                    files_must_exist);
+
+    creds_watcher_ = std::make_unique<base::FilePathWatcher>();
+    MaybeStartWatch(&creds_watcher_,
+                    base::FilePath(GetKerberosCredentialsCacheFileName()),
+                    files_must_exist);
+  }
+
+  // Should be called once.
+  void Wait() {
+    loop_.Run();
+    config_watcher_.reset();
+    creds_watcher_.reset();
+  }
+
+ private:
+  void MaybeStartWatch(std::unique_ptr<base::FilePathWatcher>* watcher,
+                       const base::FilePath& path,
+                       bool files_must_exist) {
+    (*watcher)->Watch(path, false /* recursive */, watch_callback_);
+    if (!files_must_exist && base::PathExists(path)) {
+      watch_callback_.Run(path, false /* error */);
+      watcher->reset();
+    }
+  }
+  base::RunLoop loop_;
+  base::RepeatingClosure barrier_closure_;
+
+  base::RepeatingCallback<void(const base::FilePath& path, bool error)>
+      watch_callback_;
+  std::unique_ptr<base::FilePathWatcher> config_watcher_;
+  std::unique_ptr<base::FilePathWatcher> creds_watcher_;
+};
+
 }  // namespace
 
 class ExistingUserControllerTest : public policy::DevicePolicyCrosBrowserTest {
@@ -822,22 +891,6 @@
     return config;
   }
 
-  std::string GetKerberosConfigFileName() {
-    std::unique_ptr<base::Environment> env(base::Environment::Create());
-    std::string config_file;
-    EXPECT_TRUE(env->GetVar("KRB5_CONFIG", &config_file));
-    return config_file;
-  }
-
-  std::string GetKerberosCredentialsCacheFileName() {
-    std::unique_ptr<base::Environment> env(base::Environment::Create());
-    std::string creds_file;
-    EXPECT_TRUE(env->GetVar("KRB5CCNAME", &creds_file));
-    EXPECT_EQ(kKrb5CCFilePrefix,
-              creds_file.substr(0, strlen(kKrb5CCFilePrefix)));
-    return creds_file.substr(strlen(kKrb5CCFilePrefix));
-  }
-
   void CheckKerberosFiles(bool enable_dns_cname_lookup) {
     std::string file_contents;
     EXPECT_TRUE(base::ReadFileToString(
@@ -852,27 +905,7 @@
 
   // Applies policy and waits until both config and credentials files changed.
   void ApplyPolicyAndWaitFilesChanged(bool enable_dns_cname_lookup) {
-    base::RunLoop loop;
-    base::RepeatingClosure barrier_closure(
-        base::BarrierClosure(2, loop.QuitClosure()));
-
-    auto watch_callback = base::BindRepeating(
-        [](const base::RepeatingClosure& barrier_closure,
-           const base::FilePath& path, bool error) -> void {
-          LOG(ERROR) << "Changed " << path.value();
-          EXPECT_FALSE(error);
-          barrier_closure.Run();
-        },
-        barrier_closure);
-
-    base::FilePathWatcher config_watcher;
-    config_watcher.Watch(base::FilePath(GetKerberosConfigFileName()),
-                         false /* recursive */, watch_callback);
-
-    base::FilePathWatcher creds_watcher;
-    creds_watcher.Watch(base::FilePath(GetKerberosCredentialsCacheFileName()),
-                        false /* recursive */, watch_callback);
-
+    KerberosFilesChangeWaiter files_change_waiter(true /* files_must_exist */);
     policy::PolicyMap policies;
     policies.Set(policy::key::kDisableAuthNegotiateCnameLookup,
                  policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
@@ -880,7 +913,7 @@
                  std::make_unique<base::Value>(!enable_dns_cname_lookup),
                  nullptr);
     UpdateProviderPolicy(policies);
-    loop.Run();
+    files_change_waiter.Wait();
   }
 
  private:
@@ -932,6 +965,8 @@
   existing_user_controller()->CompleteLogin(user_context);
 
   profile_prepared_observer.Wait();
+  KerberosFilesChangeWaiter files_change_waiter(false /* files_must_exist */);
+  files_change_waiter.Wait();
   CheckKerberosFiles(true /* enable_dns_cname_lookup */);
 }
 
@@ -953,6 +988,8 @@
   existing_user_controller()->CompleteLogin(user_context);
 
   profile_prepared_observer.Wait();
+  KerberosFilesChangeWaiter files_change_waiter(false /* files_must_exist */);
+  files_change_waiter.Wait();
   CheckKerberosFiles(true /* enable_dns_cname_lookup */);
 
   ApplyPolicyAndWaitFilesChanged(false /* enable_dns_cname_lookup */);
@@ -978,8 +1015,9 @@
       chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
       content::NotificationService::AllSources());
   existing_user_controller()->Login(user_context, SigninSpecifics());
-
   profile_prepared_observer.Wait();
+  KerberosFilesChangeWaiter files_change_waiter(false /* files_must_exist */);
+  files_change_waiter.Wait();
   CheckKerberosFiles(true /* enable_dns_cname_lookup */);
 }
 
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.cc b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
index ce0daf6..f579a85 100644
--- a/chrome/browser/extensions/api/developer_private/developer_private_api.cc
+++ b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
@@ -870,7 +870,7 @@
     ScriptingPermissionsModifier modifier(browser_context(), extension);
     if (!modifier.CanAffectExtension())
       return RespondNow(Error(kCannotChangeHostPermissions));
-    modifier.SetAllowedOnAllUrls(*update.run_on_all_urls);
+    modifier.SetWithholdAllUrls(!(*update.run_on_all_urls));
   }
 
   return RespondNow(NoArguments());
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc b/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc
index 5f3a822..484ae6e 100644
--- a/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc
+++ b/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc
@@ -85,7 +85,7 @@
 
 bool HasAllUrlsPermission(const Extension* extension,
                           content::BrowserContext* context) {
-  return ScriptingPermissionsModifier(context, extension).IsAllowedOnAllUrls();
+  return !ScriptingPermissionsModifier(context, extension).HasWithheldAllUrls();
 }
 
 bool HasPrefsPermission(bool (*has_pref)(const std::string&,
@@ -369,7 +369,7 @@
   const std::string& id = extension->id();
 
   ScriptingPermissionsModifier(profile(), base::WrapRefCounted(extension))
-      .SetAllowedOnAllUrls(false);
+      .SetWithholdAllUrls(true);
 
   TestExtensionPrefSetting(
       base::Bind(&HasPrefsPermission, &util::IsIncognitoEnabled, profile(), id),
@@ -1309,8 +1309,8 @@
       ExtensionBuilder("test").AddPermission("<all_urls>").Build();
   service()->AddExtension(extension.get());
   ScriptingPermissionsModifier modifier(profile(), extension.get());
-  EXPECT_TRUE(modifier.IsAllowedOnAllUrls());
-  modifier.SetAllowedOnAllUrls(false);
+  EXPECT_FALSE(modifier.HasWithheldAllUrls());
+  modifier.SetWithholdAllUrls(true);
 
   auto run_add_host_permission = [this, extension](base::StringPiece host,
                                                    bool should_succeed,
@@ -1354,8 +1354,8 @@
       ExtensionBuilder("test").AddPermission("<all_urls>").Build();
   service()->AddExtension(extension.get());
   ScriptingPermissionsModifier modifier(profile(), extension.get());
-  EXPECT_TRUE(modifier.IsAllowedOnAllUrls());
-  modifier.SetAllowedOnAllUrls(false);
+  EXPECT_FALSE(modifier.HasWithheldAllUrls());
+  modifier.SetWithholdAllUrls(true);
 
   auto run_remove_host_permission = [this, extension](
                                         base::StringPiece host,
diff --git a/chrome/browser/extensions/api/developer_private/extension_info_generator.cc b/chrome/browser/extensions/api/developer_private/extension_info_generator.cc
index 0b0d24d3..a4a97694 100644
--- a/chrome/browser/extensions/api/developer_private/extension_info_generator.cc
+++ b/chrome/browser/extensions/api/developer_private/extension_info_generator.cc
@@ -535,7 +535,7 @@
       browser_context_, base::WrapRefCounted(&extension));
   info->run_on_all_urls.is_enabled = permissions_modifier.CanAffectExtension();
   info->run_on_all_urls.is_active = info->run_on_all_urls.is_enabled &&
-                                    permissions_modifier.IsAllowedOnAllUrls();
+                                    !permissions_modifier.HasWithheldAllUrls();
 
   // Runtime warnings.
   std::vector<std::string> warnings =
diff --git a/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc b/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc
index 33d4116..2f6a46e 100644
--- a/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc
+++ b/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc
@@ -412,7 +412,7 @@
   // Revoke the all urls permission.
   ScriptingPermissionsModifier permissions_modifier(profile(),
                                                     all_urls_extension);
-  permissions_modifier.SetAllowedOnAllUrls(false);
+  permissions_modifier.SetWithholdAllUrls(true);
 
   // Now the extension want all urls, but not have it granted.
   info = GenerateExtensionInfo(all_urls_extension->id());
diff --git a/chrome/browser/extensions/api/web_request/web_request_apitest.cc b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
index af4ddbde..564856a 100644
--- a/chrome/browser/extensions/api/web_request/web_request_apitest.cc
+++ b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
@@ -782,7 +782,7 @@
       LoadExtension(test_data_dir_.AppendASCII("webrequest_activetab"));
   ASSERT_TRUE(extension) << message_;
   ScriptingPermissionsModifier(profile(), base::WrapRefCounted(extension))
-      .SetAllowedOnAllUrls(false);
+      .SetWithholdAllUrls(true);
   EXPECT_TRUE(listener.WaitUntilSatisfied());
 
   // Navigate the browser to a page in a new tab.
@@ -1737,7 +1737,7 @@
       LoadExtension(test_data_dir_.AppendASCII("webrequest_activetab"));
   ASSERT_TRUE(extension) << message_;
   ScriptingPermissionsModifier(profile(), base::WrapRefCounted(extension))
-      .SetAllowedOnAllUrls(false);
+      .SetWithholdAllUrls(true);
   EXPECT_TRUE(listener.WaitUntilSatisfied());
 
   // Navigate the browser to a page in a new tab.
diff --git a/chrome/browser/extensions/extension_action_runner_browsertest.cc b/chrome/browser/extensions/extension_action_runner_browsertest.cc
index 1f462ed3..d64443c9 100644
--- a/chrome/browser/extensions/extension_action_runner_browsertest.cc
+++ b/chrome/browser/extensions/extension_action_runner_browsertest.cc
@@ -173,7 +173,7 @@
     ScriptingPermissionsModifier modifier(profile(), extension);
     if (withhold_permissions == WITHHOLD_PERMISSIONS &&
         modifier.CanAffectExtension()) {
-      modifier.SetAllowedOnAllUrls(false);
+      modifier.SetWithholdAllUrls(true);
     }
   }
 
@@ -435,7 +435,7 @@
 
   // Enable the extension to run on all urls.
   ScriptingPermissionsModifier modifier(profile(), extension);
-  modifier.SetAllowedOnAllUrls(true);
+  modifier.SetWithholdAllUrls(false);
   EXPECT_TRUE(RunAllPendingInRenderer(web_contents));
 
   // Navigate again - this time, the extension should execute immediately (and
@@ -447,7 +447,7 @@
 
   // Revoke all urls permissions.
   inject_success_listener.Reset();
-  modifier.SetAllowedOnAllUrls(false);
+  modifier.SetWithholdAllUrls(true);
   EXPECT_TRUE(RunAllPendingInRenderer(web_contents));
 
   // Re-navigate; the extension should again need permission to run.
@@ -466,7 +466,7 @@
   const Extension* extension = LoadExtension(
       test_data_dir_.AppendASCII("blocked_actions/content_scripts"));
   ASSERT_TRUE(extension);
-  ScriptingPermissionsModifier(profile(), extension).SetAllowedOnAllUrls(false);
+  ScriptingPermissionsModifier(profile(), extension).SetWithholdAllUrls(true);
 
   ui_test_utils::NavigateToURL(browser(), url);
   content::WebContents* web_contents =
diff --git a/chrome/browser/extensions/extension_action_runner_unittest.cc b/chrome/browser/extensions/extension_action_runner_unittest.cc
index 18435a26..285ef3ff 100644
--- a/chrome/browser/extensions/extension_action_runner_unittest.cc
+++ b/chrome/browser/extensions/extension_action_runner_unittest.cc
@@ -118,7 +118,7 @@
   PermissionsUpdater(profile()).InitializePermissions(extension_.get());
 
   ScriptingPermissionsModifier(profile(), extension_.get())
-      .SetAllowedOnAllUrls(false);
+      .SetWithholdAllUrls(true);
   return extension_.get();
 }
 
@@ -354,7 +354,7 @@
 
   // Enable the extension on all urls.
   ScriptingPermissionsModifier permissions_modifier(profile(), extension);
-  permissions_modifier.SetAllowedOnAllUrls(true);
+  permissions_modifier.SetWithholdAllUrls(false);
 
   EXPECT_FALSE(RequiresUserConsent(extension));
   // This should carry across navigations, and websites.
@@ -362,7 +362,7 @@
   EXPECT_FALSE(RequiresUserConsent(extension));
 
   // Turning off the preference should have instant effect.
-  permissions_modifier.SetAllowedOnAllUrls(false);
+  permissions_modifier.SetWithholdAllUrls(true);
   EXPECT_TRUE(RequiresUserConsent(extension));
 
   // And should also persist across navigations and websites.
diff --git a/chrome/browser/extensions/extension_context_menu_model.cc b/chrome/browser/extensions/extension_context_menu_model.cc
index fc816fa..51474cd 100644
--- a/chrome/browser/extensions/extension_context_menu_model.cc
+++ b/chrome/browser/extensions/extension_context_menu_model.cc
@@ -374,7 +374,7 @@
     content::WebContents* web_contents) const {
   ScriptingPermissionsModifier modifier(profile_, extension);
   DCHECK(modifier.CanAffectExtension());
-  if (modifier.IsAllowedOnAllUrls())
+  if (!modifier.HasWithheldAllUrls())
     return PAGE_ACCESS_RUN_ON_ALL_SITES;
   if (modifier.HasGrantedHostPermission(
           GetActiveWebContents()->GetLastCommittedURL()))
@@ -428,18 +428,18 @@
   switch (command_id) {
     case PAGE_ACCESS_RUN_ON_CLICK:
       if (current_access == PAGE_ACCESS_RUN_ON_ALL_SITES)
-        modifier.SetAllowedOnAllUrls(false);
+        modifier.SetWithholdAllUrls(true);
       if (modifier.HasGrantedHostPermission(url))
         modifier.RemoveGrantedHostPermission(url);
       break;
     case PAGE_ACCESS_RUN_ON_SITE:
       if (current_access == PAGE_ACCESS_RUN_ON_ALL_SITES)
-        modifier.SetAllowedOnAllUrls(false);
+        modifier.SetWithholdAllUrls(true);
       if (!modifier.HasGrantedHostPermission(url))
         modifier.GrantHostPermission(url);
       break;
     case PAGE_ACCESS_RUN_ON_ALL_SITES:
-      modifier.SetAllowedOnAllUrls(true);
+      modifier.SetWithholdAllUrls(false);
       break;
     default:
       NOTREACHED();
diff --git a/chrome/browser/extensions/extension_context_menu_model_unittest.cc b/chrome/browser/extensions/extension_context_menu_model_unittest.cc
index 96d24cd..e79c2786 100644
--- a/chrome/browser/extensions/extension_context_menu_model_unittest.cc
+++ b/chrome/browser/extensions/extension_context_menu_model_unittest.cc
@@ -623,7 +623,7 @@
   const Extension* extension =
       AddExtensionWithHostPermission("extension", manifest_keys::kBrowserAction,
                                      Manifest::INTERNAL, "*://*/*");
-  ScriptingPermissionsModifier(profile(), extension).SetAllowedOnAllUrls(false);
+  ScriptingPermissionsModifier(profile(), extension).SetWithholdAllUrls(true);
   EXPECT_TRUE(registry()->enabled_extensions().Contains(extension->id()));
 
   const GURL kActiveUrl("http://www.example.com/");
diff --git a/chrome/browser/extensions/permissions_updater_unittest.cc b/chrome/browser/extensions/permissions_updater_unittest.cc
index 336d0ed4..26b4fbf 100644
--- a/chrome/browser/extensions/permissions_updater_unittest.cc
+++ b/chrome/browser/extensions/permissions_updater_unittest.cc
@@ -356,8 +356,7 @@
     PermissionsUpdater updater(profile());
     updater.InitializePermissions(extension.get());
 
-    ScriptingPermissionsModifier(profile(), extension)
-        .SetAllowedOnAllUrls(false);
+    ScriptingPermissionsModifier(profile(), extension).SetWithholdAllUrls(true);
 
     // All-hosts was withheld, so the extension shouldn't have access to any
     // site (like foo.com).
diff --git a/chrome/browser/extensions/scripting_permissions_modifier.cc b/chrome/browser/extensions/scripting_permissions_modifier.cc
index 3db2095..8e2b49e9 100644
--- a/chrome/browser/extensions/scripting_permissions_modifier.cc
+++ b/chrome/browser/extensions/scripting_permissions_modifier.cc
@@ -34,18 +34,19 @@
   return result;
 }
 
-// Returns true if the extension must be allowed to access all urls.
-bool ExtensionMustBeAllowedOnAllUrls(const Extension& extension) {
-  // Some extensions must retain privilege to execute on all urls. Specifically,
-  // extensions that don't show up in chrome:extensions (where withheld
-  // permissions couldn't be granted), extensions that are part of chrome or
-  // corporate policy, and extensions that are whitelisted to script everywhere
-  // must always have permission to run on a page.
-  return !extension.ShouldDisplayInExtensionSettings() ||
-         Manifest::IsPolicyLocation(extension.location()) ||
-         Manifest::IsComponentLocation(extension.location()) ||
-         PermissionsData::CanExecuteScriptEverywhere(extension.id(),
-                                                     extension.location());
+// Returns true if Chrome can potentially withhold permissions from the
+// extension.
+bool CanWithholdFromExtension(const Extension& extension) {
+  // Some extensions must retain privilege to all requested host permissions.
+  // Specifically, extensions that don't show up in chrome:extensions (where
+  // withheld permissions couldn't be granted), extensions that are part of
+  // chrome or corporate policy, and extensions that are whitelisted to script
+  // everywhere must always have permission to run on a page.
+  return extension.ShouldDisplayInExtensionSettings() &&
+         !Manifest::IsPolicyLocation(extension.location()) &&
+         !Manifest::IsComponentLocation(extension.location()) &&
+         !PermissionsData::CanExecuteScriptEverywhere(extension.id(),
+                                                      extension.location());
 }
 
 // Partitions |permissions| into two sets of permissions, placing any
@@ -92,20 +93,36 @@
     return false;
 
   // Certain extensions are always exempt from having permissions withheld.
-  if (ExtensionMustBeAllowedOnAllUrls(extension))
+  if (!CanWithholdFromExtension(extension))
     return false;
 
   return true;
 }
 
-base::Optional<bool> GetPrefValue(const ExtensionPrefs& prefs,
-                                  const ExtensionId& id) {
-  bool allowed = false;
+base::Optional<bool> GetWithholdPermissionsPrefValue(
+    const ExtensionPrefs& prefs,
+    const ExtensionId& id) {
+  bool permissions_allowed = false;
   if (!prefs.ReadPrefAsBoolean(id, kExtensionAllowedOnAllUrlsPrefName,
-                               &allowed)) {
+                               &permissions_allowed)) {
     return base::nullopt;
   }
-  return allowed;
+  // NOTE: For legacy reasons, the preference stores whether the extension was
+  // allowed access to all its host permissions, rather than if Chrome should
+  // withhold permissions. Invert the boolean for backwards compatibility.
+  return !permissions_allowed;
+}
+
+void SetWithholdPermissionsPrefValue(ExtensionPrefs* prefs,
+                                     const ExtensionId& id,
+                                     bool should_withhold) {
+  // NOTE: For legacy reasons, the preference stores whether the extension was
+  // allowed access to all its host permissions, rather than if Chrome should
+  // withhold permissions. Invert the boolean for backwards compatibility.
+  bool permissions_allowed = !should_withhold;
+  prefs->UpdateExtensionPref(
+      id, kExtensionAllowedOnAllUrlsPrefName,
+      std::make_unique<base::Value>(permissions_allowed));
 }
 
 }  // namespace
@@ -121,19 +138,19 @@
 
 ScriptingPermissionsModifier::~ScriptingPermissionsModifier() {}
 
-void ScriptingPermissionsModifier::SetAllowedOnAllUrls(bool allowed) {
+void ScriptingPermissionsModifier::SetWithholdAllUrls(bool should_withhold) {
   DCHECK(CanAffectExtension());
 
-  if (IsAllowedOnAllUrls() == allowed)
+  if (HasWithheldAllUrls() == should_withhold)
     return;
 
-  extension_prefs_->UpdateExtensionPref(extension_->id(),
-                                        kExtensionAllowedOnAllUrlsPrefName,
-                                        std::make_unique<base::Value>(allowed));
-  if (allowed)
-    GrantWithheldImpliedAllHosts();
-  else
+  SetWithholdPermissionsPrefValue(extension_prefs_, extension_->id(),
+                                  should_withhold);
+
+  if (should_withhold)
     WithholdImpliedAllHosts();
+  else
+    GrantWithheldImpliedAllHosts();
 
   // If this was an update to permissions, we also need to sync the change.
   // TODO(devlin): This isn't currently necessary. We should remove it and add
@@ -144,14 +161,14 @@
     sync_service->SyncExtensionChangeIfNeeded(*extension_);
 }
 
-bool ScriptingPermissionsModifier::IsAllowedOnAllUrls() const {
+bool ScriptingPermissionsModifier::HasWithheldAllUrls() const {
   DCHECK(CanAffectExtension());
 
   base::Optional<bool> pref_value =
-      GetPrefValue(*extension_prefs_, extension_->id());
+      GetWithholdPermissionsPrefValue(*extension_prefs_, extension_->id());
   if (!pref_value.has_value()) {
-    // If there is no value present, default to true.
-    return true;
+    // If there is no value present, default to false.
+    return false;
   }
   return *pref_value;
 }
@@ -261,8 +278,8 @@
   bool should_withhold = false;
   if (ShouldConsiderExtension(extension)) {
     base::Optional<bool> pref_value =
-        GetPrefValue(extension_prefs, extension.id());
-    should_withhold = pref_value.has_value() && pref_value.value() == false;
+        GetWithholdPermissionsPrefValue(extension_prefs, extension.id());
+    should_withhold = pref_value.has_value() && pref_value.value() == true;
   }
 
   should_withhold &= permissions.ShouldWarnAllHosts();
diff --git a/chrome/browser/extensions/scripting_permissions_modifier.h b/chrome/browser/extensions/scripting_permissions_modifier.h
index bc6309d..88ad28e 100644
--- a/chrome/browser/extensions/scripting_permissions_modifier.h
+++ b/chrome/browser/extensions/scripting_permissions_modifier.h
@@ -31,18 +31,18 @@
                                const scoped_refptr<const Extension>& extension);
   ~ScriptingPermissionsModifier();
 
-  // Sets whether the extension should be allowed to execute on all urls without
-  // explicit user consent. Used when the features::kRuntimeHostPermissions
-  // feature is enabled.
+  // Sets whether Chrome should withhold <all_urls>-style permissions from the
+  // extension. Used when the features::kRuntimeHostPermissions feature is
+  // enabled.
   // This may only be called for extensions that can be affected (i.e., for
   // which CanAffectExtension() returns true). Anything else will DCHECK.
-  void SetAllowedOnAllUrls(bool allowed);
+  void SetWithholdAllUrls(bool withhold);
 
-  // Returns whether the extension is allowed to execute scripts on all urls
-  // without user consent.
+  // Returns whether Chrome has withheld <all_urls>-style permissions from the
+  // extension.
   // This may only be called for extensions that can be affected (i.e., for
   // which CanAffectExtension() returns true). Anything else will DCHECK.
-  bool IsAllowedOnAllUrls() const;
+  bool HasWithheldAllUrls() const;
 
   // Returns true if the associated extension can be affected by
   // features::kRuntimeHostPermissions.
diff --git a/chrome/browser/extensions/scripting_permissions_modifier_unittest.cc b/chrome/browser/extensions/scripting_permissions_modifier_unittest.cc
index 6da48dee..8363bb5d 100644
--- a/chrome/browser/extensions/scripting_permissions_modifier_unittest.cc
+++ b/chrome/browser/extensions/scripting_permissions_modifier_unittest.cc
@@ -152,7 +152,7 @@
 
   // Then, withhold the all-hosts permissions.
   ScriptingPermissionsModifier modifier(profile(), extension);
-  modifier.SetAllowedOnAllUrls(false);
+  modifier.SetWithholdAllUrls(true);
 
   EXPECT_TRUE(SetsAreEqual(
       permissions_data->active_permissions().scriptable_hosts().patterns(),
@@ -168,7 +168,7 @@
       all_host_patterns));
 
   // Finally, re-grant the withheld permissions.
-  modifier.SetAllowedOnAllUrls(true);
+  modifier.SetWithholdAllUrls(false);
 
   // We should be back to our initial state - all requested permissions are
   // granted.
@@ -211,11 +211,11 @@
   EXPECT_TRUE(
       permissions_data->withheld_permissions().scriptable_hosts().is_empty());
   ScriptingPermissionsModifier modifier(profile(), extension);
-  EXPECT_TRUE(modifier.IsAllowedOnAllUrls());
+  EXPECT_FALSE(modifier.HasWithheldAllUrls());
 
   // Revoke access.
-  modifier.SetAllowedOnAllUrls(false);
-  EXPECT_FALSE(modifier.IsAllowedOnAllUrls());
+  modifier.SetWithholdAllUrls(true);
+  EXPECT_TRUE(modifier.HasWithheldAllUrls());
   EXPECT_TRUE(
       permissions_data->active_permissions().scriptable_hosts().is_empty());
   EXPECT_TRUE(SetsAreEqual(
@@ -236,7 +236,7 @@
   // withheld.
   enabled_scope = std::make_unique<RuntimeHostPermissionsEnabledScope>();
   updater.InitializePermissions(extension.get());
-  EXPECT_FALSE(modifier.IsAllowedOnAllUrls());
+  EXPECT_TRUE(modifier.HasWithheldAllUrls());
   EXPECT_TRUE(
       permissions_data->active_permissions().scriptable_hosts().is_empty());
   EXPECT_TRUE(SetsAreEqual(
@@ -259,7 +259,7 @@
   PermissionsUpdater(profile()).InitializePermissions(extension.get());
 
   ScriptingPermissionsModifier modifier(profile(), extension);
-  modifier.SetAllowedOnAllUrls(false);
+  modifier.SetWithholdAllUrls(true);
 
   const GURL kUrl("https://www.google.com/");
   const GURL kUrl2("https://www.chromium.org/");
diff --git a/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer_unittest.cc
index b7cea5b..c971af98 100644
--- a/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer_unittest.cc
@@ -323,6 +323,7 @@
   std::unique_ptr<content::NavigationSimulator> navigation =
       content::NavigationSimulator::CreateRendererInitiated(url, main_rfh());
   navigation->Fail(net::ERR_TIMED_OUT);
+  navigation->AbortCommit();
   content::RenderFrameHostTester::For(navigation->GetFinalRenderFrameHost())
       ->SimulateNavigationStop();
 
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index 2c87e52a..d3b6716f 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -103,6 +103,7 @@
 #include "components/rappor/rappor_service_impl.h"
 #include "components/safe_browsing/common/safe_browsing_prefs.h"
 #include "components/search_engines/template_url_prepopulate_data.h"
+#include "components/sessions/core/session_id_generator.h"
 #include "components/signin/core/browser/profile_management_switches.h"
 #include "components/startup_metric_utils/browser/startup_metric_utils.h"
 #include "components/subresource_filter/core/browser/ruleset_service.h"
@@ -365,6 +366,7 @@
   RegisterNetworkContextCreationPrefs(registry);
   RegisterScreenshotPrefs(registry);
   safe_browsing::RegisterLocalStatePrefs(registry);
+  sessions::SessionIdGenerator::RegisterPrefs(registry);
   SigninManagerFactory::RegisterPrefs(registry);
   SSLConfigServiceManager::RegisterPrefs(registry);
   startup_metric_utils::RegisterPrefs(registry);
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index 2515784..7991560d 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -459,8 +459,6 @@
   configuration_policy_provider_ =
       policy::UserPolicyManagerFactoryChromeOS::CreateForProfile(
           this, force_immediate_policy_load, io_task_runner_);
-  chromeos::AuthPolicyCredentialsManagerFactory::
-      BuildForProfileIfActiveDirectory(this);
 #else
   configuration_policy_provider_ =
       policy::UserCloudPolicyManagerFactory::CreateForOriginalBrowserContext(
diff --git a/chrome/browser/profiling_host/background_profiling_triggers.cc b/chrome/browser/profiling_host/background_profiling_triggers.cc
index a4dda2e7..c835d07 100644
--- a/chrome/browser/profiling_host/background_profiling_triggers.cc
+++ b/chrome/browser/profiling_host/background_profiling_triggers.cc
@@ -19,15 +19,20 @@
 namespace heap_profiling {
 
 namespace {
-// Check memory usage every hour. Trigger slow report if needed.
-const int kRepeatingCheckMemoryDelayInHours = 1;
-const int kThrottledReportRepeatingCheckMemoryDelayInHours = 12;
 
 #if defined(OS_ANDROID)
+// Check memory usage every 10 minutes. Trigger slow report if needed.
+const int kRepeatingCheckMemoryDelayInMinutes = 10;
+const int kThrottledReportRepeatingCheckMemoryDelayInHours = 1;
+
 const size_t kBrowserProcessMallocTriggerKb = 100 * 1024;    // 100 MB
 const size_t kGPUProcessMallocTriggerKb = 40 * 1024;         // 40 MB
 const size_t kRendererProcessMallocTriggerKb = 125 * 1024;   // 125 MB
 #else
+// Check memory usage every hour. Trigger slow report if needed.
+const int kRepeatingCheckMemoryDelayInMinutes = 60;
+const int kThrottledReportRepeatingCheckMemoryDelayInHours = 12;
+
 const size_t kBrowserProcessMallocTriggerKb = 400 * 1024;    // 400 MB
 const size_t kGPUProcessMallocTriggerKb = 400 * 1024;        // 400 MB
 const size_t kRendererProcessMallocTriggerKb = 500 * 1024;   // 500 MB
@@ -75,11 +80,12 @@
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
 
   // Register a repeating timer to check memory usage periodically.
-  timer_.Start(FROM_HERE,
-               base::TimeDelta::FromHours(kRepeatingCheckMemoryDelayInHours),
-               base::BindRepeating(
-                   &BackgroundProfilingTriggers::PerformMemoryUsageChecks,
-                   weak_ptr_factory_.GetWeakPtr()));
+  timer_.Start(
+      FROM_HERE,
+      base::TimeDelta::FromMinutes(kRepeatingCheckMemoryDelayInMinutes),
+      base::BindRepeating(
+          &BackgroundProfilingTriggers::PerformMemoryUsageChecks,
+          weak_ptr_factory_.GetWeakPtr()));
 }
 
 bool BackgroundProfilingTriggers::IsAllowedToUpload() const {
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_impl.cc b/chrome/browser/resource_coordinator/local_site_characteristics_data_impl.cc
index c6874e06..1eaac67 100644
--- a/chrome/browser/resource_coordinator/local_site_characteristics_data_impl.cc
+++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_impl.cc
@@ -84,30 +84,30 @@
 
 SiteFeatureUsage LocalSiteCharacteristicsDataImpl::UpdatesFaviconInBackground()
     const {
-  return GetFeatureUsage(
-      site_characteristics_.updates_favicon_in_background(),
-      GetStaticProactiveTabDiscardParams().favicon_update_observation_window);
+  return GetFeatureUsage(site_characteristics_.updates_favicon_in_background(),
+                         GetStaticProactiveTabFreezeAndDiscardParams()
+                             .favicon_update_observation_window);
 }
 
 SiteFeatureUsage LocalSiteCharacteristicsDataImpl::UpdatesTitleInBackground()
     const {
-  return GetFeatureUsage(
-      site_characteristics_.updates_title_in_background(),
-      GetStaticProactiveTabDiscardParams().title_update_observation_window);
+  return GetFeatureUsage(site_characteristics_.updates_title_in_background(),
+                         GetStaticProactiveTabFreezeAndDiscardParams()
+                             .title_update_observation_window);
 }
 
 SiteFeatureUsage LocalSiteCharacteristicsDataImpl::UsesAudioInBackground()
     const {
-  return GetFeatureUsage(
-      site_characteristics_.uses_audio_in_background(),
-      GetStaticProactiveTabDiscardParams().audio_usage_observation_window);
+  return GetFeatureUsage(site_characteristics_.uses_audio_in_background(),
+                         GetStaticProactiveTabFreezeAndDiscardParams()
+                             .audio_usage_observation_window);
 }
 
 SiteFeatureUsage
 LocalSiteCharacteristicsDataImpl::UsesNotificationsInBackground() const {
   return GetFeatureUsage(
       site_characteristics_.uses_notifications_in_background(),
-      GetStaticProactiveTabDiscardParams()
+      GetStaticProactiveTabFreezeAndDiscardParams()
           .notifications_usage_observation_window);
 }
 
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_impl_unittest.cc b/chrome/browser/resource_coordinator/local_site_characteristics_data_impl_unittest.cc
index 59587c1..398a0d22 100644
--- a/chrome/browser/resource_coordinator/local_site_characteristics_data_impl_unittest.cc
+++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_impl_unittest.cc
@@ -164,9 +164,9 @@
 
   // Advance the clock by a time lower than the miniumum observation time for
   // the audio feature.
-  test_clock_.Advance(
-      GetStaticProactiveTabDiscardParams().audio_usage_observation_window -
-      base::TimeDelta::FromSeconds(1));
+  test_clock_.Advance(GetStaticProactiveTabFreezeAndDiscardParams()
+                          .audio_usage_observation_window -
+                      base::TimeDelta::FromSeconds(1));
 
   // The audio feature usage is still unknown as the observation window hasn't
   // expired.
@@ -192,7 +192,7 @@
 
   // Advance the clock and make sure that notifications feature gets
   // reported as unused.
-  test_clock_.Advance(GetStaticProactiveTabDiscardParams()
+  test_clock_.Advance(GetStaticProactiveTabFreezeAndDiscardParams()
                           .notifications_usage_observation_window);
   EXPECT_EQ(SiteFeatureUsage::kSiteFeatureNotInUse,
             local_site_data->UsesNotificationsInBackground());
@@ -246,7 +246,7 @@
   local_site_data->NotifyLoadedSiteBackgrounded();
   local_site_data->NotifyUsesAudioInBackground();
 
-  test_clock_.Advance(GetStaticProactiveTabDiscardParams()
+  test_clock_.Advance(GetStaticProactiveTabFreezeAndDiscardParams()
                           .notifications_usage_observation_window -
                       base::TimeDelta::FromSeconds(1));
   EXPECT_EQ(SiteFeatureUsage::kSiteFeatureInUse,
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_store.cc b/chrome/browser/resource_coordinator/local_site_characteristics_data_store.cc
index 6941849..876241d9 100644
--- a/chrome/browser/resource_coordinator/local_site_characteristics_data_store.cc
+++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_store.cc
@@ -25,7 +25,7 @@
 LocalSiteCharacteristicsDataStore::LocalSiteCharacteristicsDataStore(
     Profile* profile)
     : history_observer_(this) {
-  DCHECK(base::FeatureList::IsEnabled(features::kProactiveTabDiscarding));
+  DCHECK(base::FeatureList::IsEnabled(features::kProactiveTabFreezeAndDiscard));
 
   database_ = std::make_unique<LevelDBSiteCharacteristicsDatabase>(
       profile->GetPath().AppendASCII(kSiteCharacteristicsDirectoryName));
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_store_factory.cc b/chrome/browser/resource_coordinator/local_site_characteristics_data_store_factory.cc
index 80f74da..453f1bd 100644
--- a/chrome/browser/resource_coordinator/local_site_characteristics_data_store_factory.cc
+++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_store_factory.cc
@@ -19,7 +19,7 @@
 // static
 SiteCharacteristicsDataStore*
 LocalSiteCharacteristicsDataStoreFactory::GetForProfile(Profile* profile) {
-  if (base::FeatureList::IsEnabled(features::kProactiveTabDiscarding)) {
+  if (base::FeatureList::IsEnabled(features::kProactiveTabFreezeAndDiscard)) {
     return static_cast<SiteCharacteristicsDataStore*>(
         GetInstance()->GetServiceForBrowserContext(profile, true));
   }
@@ -91,7 +91,7 @@
 
 bool LocalSiteCharacteristicsDataStoreFactory::
     ServiceIsCreatedWithBrowserContext() const {
-  return base::FeatureList::IsEnabled(features::kProactiveTabDiscarding);
+  return base::FeatureList::IsEnabled(features::kProactiveTabFreezeAndDiscard);
 }
 
 bool LocalSiteCharacteristicsDataStoreFactory::ServiceIsNULLWhileTesting()
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_store_factory_browsertest.cc b/chrome/browser/resource_coordinator/local_site_characteristics_data_store_factory_browsertest.cc
index 0237294..976388b 100644
--- a/chrome/browser/resource_coordinator/local_site_characteristics_data_store_factory_browsertest.cc
+++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_store_factory_browsertest.cc
@@ -41,7 +41,7 @@
 
   void SetUp() override {
     scoped_feature_list_.InitAndEnableFeature(
-        features::kProactiveTabDiscarding);
+        features::kProactiveTabFreezeAndDiscard);
     InProcessBrowserTest::SetUp();
   }
 
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_data_store_unittest.cc b/chrome/browser/resource_coordinator/local_site_characteristics_data_store_unittest.cc
index 8aa3c9f..6312b345 100644
--- a/chrome/browser/resource_coordinator/local_site_characteristics_data_store_unittest.cc
+++ b/chrome/browser/resource_coordinator/local_site_characteristics_data_store_unittest.cc
@@ -46,7 +46,7 @@
   LocalSiteCharacteristicsDataStoreTest()
       : scoped_set_tick_clock_for_testing_(&test_clock_) {
     scoped_feature_list_.InitAndEnableFeature(
-        features::kProactiveTabDiscarding);
+        features::kProactiveTabFreezeAndDiscard);
     data_store_ =
         std::make_unique<LocalSiteCharacteristicsDataStore>(&profile_);
     test_clock_.SetNowTicks(base::TimeTicks::UnixEpoch());
diff --git a/chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store_unittest.cc b/chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store_unittest.cc
index b0afe1a..763e2a9 100644
--- a/chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store_unittest.cc
+++ b/chrome/browser/resource_coordinator/local_site_characteristics_non_recording_data_store_unittest.cc
@@ -18,7 +18,8 @@
 
 TEST_F(LocalSiteCharacteristicsNonRecordingDataStoreTest, EndToEnd) {
   base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndEnableFeature(features::kProactiveTabDiscarding);
+  scoped_feature_list.InitAndEnableFeature(
+      features::kProactiveTabFreezeAndDiscard);
   content::TestBrowserThreadBundle test_browser_thread_bundle;
   TestingProfile profile;
   const char kTestOrigin[] = "http://www.foo.com";
diff --git a/chrome/browser/resource_coordinator/tab_manager.cc b/chrome/browser/resource_coordinator/tab_manager.cc
index 14d0ce67..5aa278a 100644
--- a/chrome/browser/resource_coordinator/tab_manager.cc
+++ b/chrome/browser/resource_coordinator/tab_manager.cc
@@ -180,7 +180,8 @@
         new ResourceCoordinatorSignalObserver());
   }
   stats_collector_.reset(new TabManagerStatsCollector());
-  proactive_discard_params_ = GetStaticProactiveTabDiscardParams();
+  proactive_freeze_discard_params_ =
+      GetStaticProactiveTabFreezeAndDiscardParams();
   TabLoadTracker::Get()->AddObserver(this);
 }
 
@@ -898,28 +899,28 @@
 base::TimeDelta TabManager::GetTimeInBackgroundBeforeProactiveDiscard() const {
   // Exceed high threshold - in excessive state.
   if (num_loaded_lifecycle_units_ >=
-      proactive_discard_params_.high_loaded_tab_count) {
+      proactive_freeze_discard_params_.high_loaded_tab_count) {
     return base::TimeDelta();
   }
 
   // Exceed moderate threshold - in high state.
   if (num_loaded_lifecycle_units_ >=
-      proactive_discard_params_.moderate_loaded_tab_count) {
-    return proactive_discard_params_.high_occluded_timeout;
+      proactive_freeze_discard_params_.moderate_loaded_tab_count) {
+    return proactive_freeze_discard_params_.high_occluded_timeout;
   }
 
   // Exceed low threshold - in moderate state.
   if (num_loaded_lifecycle_units_ >=
-      proactive_discard_params_.low_loaded_tab_count) {
-    return proactive_discard_params_.moderate_occluded_timeout;
+      proactive_freeze_discard_params_.low_loaded_tab_count) {
+    return proactive_freeze_discard_params_.moderate_occluded_timeout;
   }
 
   // Didn't meet any thresholds - in low state.
-  return proactive_discard_params_.low_occluded_timeout;
+  return proactive_freeze_discard_params_.low_occluded_timeout;
 }
 
 void TabManager::PerformStateTransitions() {
-  if (!base::FeatureList::IsEnabled(features::kProactiveTabDiscarding))
+  if (!base::FeatureList::IsEnabled(features::kProactiveTabFreezeAndDiscard))
     return;
 
   base::TimeTicks next_state_transition_time = base::TimeTicks::Max();
@@ -935,7 +936,7 @@
       const base::TimeDelta time_not_visible =
           now - lifecycle_unit->GetLastVisibleTime();
       const base::TimeDelta time_until_freeze =
-          proactive_discard_params_.freeze_timeout - time_not_visible;
+          proactive_freeze_discard_params_.freeze_timeout - time_not_visible;
 
       if (time_until_freeze <= base::TimeDelta()) {
         lifecycle_unit->Freeze();
@@ -968,7 +969,8 @@
   // oldest LifecycleUnit and call PerformStateTransitions() again, rather than
   // discarding all LifecycleUnits that have been non-visible for at least
   // GetTimeInBackgroundBeforeProactiveDiscard().
-  if (oldest_discardable_lifecycle_unit) {
+  if (proactive_freeze_discard_params_.should_proactively_discard &&
+      oldest_discardable_lifecycle_unit) {
     const base::TimeDelta time_not_visible =
         now - oldest_discardable_lifecycle_unit->GetLastVisibleTime();
     const base::TimeDelta time_until_discard =
diff --git a/chrome/browser/resource_coordinator/tab_manager.h b/chrome/browser/resource_coordinator/tab_manager.h
index a2cac62..98fd4448 100644
--- a/chrome/browser/resource_coordinator/tab_manager.h
+++ b/chrome/browser/resource_coordinator/tab_manager.h
@@ -238,6 +238,11 @@
                            IsInBackgroundTabOpeningSession);
   FRIEND_TEST_ALL_PREFIXES(TabManagerWithProactiveDiscardExperimentEnabledTest,
                            GetTimeInBackgroundBeforeProactiveDiscardTest);
+  FRIEND_TEST_ALL_PREFIXES(
+      TabManagerWithProactiveDiscardExperimentEnabledTest,
+      NoProactiveDiscardWhenDiscardingVariationParamDisabled);
+  FRIEND_TEST_ALL_PREFIXES(TabManagerWithProactiveDiscardExperimentEnabledTest,
+                           FreezingWhenDiscardingVariationParamDisabled);
 
   // The time of the first purging after a renderer is backgrounded.
   // The initial value was chosen because most of users activate backgrounded
@@ -420,9 +425,8 @@
   // to determine timeout threshold for proactive discarding.
   int num_loaded_lifecycle_units_ = 0;
 
-  // Parameters for proactive discarding. Used to determine the timeout until a
-  // LifecycleUnit should be discarded based on |num_loaded_lifecycle_units_|.
-  ProactiveTabDiscardParams proactive_discard_params_;
+  // Parameters for proactive freezing and discarding.
+  ProactiveTabFreezeAndDiscardParams proactive_freeze_discard_params_;
 
   // Timer to periodically update the stats of the renderers.
   base::RepeatingTimer update_timer_;
diff --git a/chrome/browser/resource_coordinator/tab_manager_features.cc b/chrome/browser/resource_coordinator/tab_manager_features.cc
index 08b3168..d793c4ac 100644
--- a/chrome/browser/resource_coordinator/tab_manager_features.cc
+++ b/chrome/browser/resource_coordinator/tab_manager_features.cc
@@ -23,9 +23,9 @@
 const base::Feature kCustomizedTabLoadTimeout{
     "CustomizedTabLoadTimeout", base::FEATURE_DISABLED_BY_DEFAULT};
 
-// Enables proactive tab discarding.
-const base::Feature kProactiveTabDiscarding{"ProactiveTabDiscarding",
-                                            base::FEATURE_DISABLED_BY_DEFAULT};
+// Enables proactive tab freezing and discarding.
+const base::Feature kProactiveTabFreezeAndDiscard{
+    "ProactiveTabFreezeAndDiscard", base::FEATURE_DISABLED_BY_DEFAULT};
 
 // Enables delaying the navigation of background tabs in order to improve
 // foreground tab's user experience.
@@ -53,12 +53,12 @@
 // and enforces the constraint that it must be in the interval
 // [low_loaded_tab_count, high_loaded_tab_count].
 int GetModerateThresholdTabCountBasedOnSystemMemory(
-    ProactiveTabDiscardParams* params,
+    ProactiveTabFreezeAndDiscardParams* params,
     int memory_in_gb) {
   int moderate_loaded_tab_count_per_gb = base::GetFieldTrialParamByFeatureAsInt(
-      features::kProactiveTabDiscarding,
-      kProactiveTabDiscard_ModerateLoadedTabsPerGbRamParam,
-      kProactiveTabDiscard_ModerateLoadedTabsPerGbRamDefault);
+      features::kProactiveTabFreezeAndDiscard,
+      kProactiveTabFreezeAndDiscard_ModerateLoadedTabsPerGbRamParam,
+      kProactiveTabFreezeAndDiscard_ModerateLoadedTabsPerGbRamDefault);
 
   int moderate_level = moderate_loaded_tab_count_per_gb * memory_in_gb;
 
@@ -72,82 +72,97 @@
 }  // namespace
 
 // Field-trial parameter names for proactive tab discarding.
-const char kProactiveTabDiscard_LowLoadedTabCountParam[] = "LowLoadedTabCount";
-const char kProactiveTabDiscard_ModerateLoadedTabsPerGbRamParam[] =
+const char kProactiveTabFreezeAndDiscard_ShouldProactivelyDiscard[] =
+    "ShouldProactivelyDiscard";
+const char kProactiveTabFreezeAndDiscard_LowLoadedTabCountParam[] =
+    "LowLoadedTabCount";
+const char kProactiveTabFreezeAndDiscard_ModerateLoadedTabsPerGbRamParam[] =
     "ModerateLoadedTabsPerGbRam";
-const char kProactiveTabDiscard_HighLoadedTabCountParam[] =
+const char kProactiveTabFreezeAndDiscard_HighLoadedTabCountParam[] =
     "HighLoadedTabCount";
-const char kProactiveTabDiscard_LowOccludedTimeoutParam[] =
+const char kProactiveTabFreezeAndDiscard_LowOccludedTimeoutParam[] =
     "LowOccludedTimeoutSeconds";
-const char kProactiveTabDiscard_ModerateOccludedTimeoutParam[] =
+const char kProactiveTabFreezeAndDiscard_ModerateOccludedTimeoutParam[] =
     "ModerateOccludedTimeoutSeconds";
-const char kProactiveTabDiscard_HighOccludedTimeoutParam[] =
+const char kProactiveTabFreezeAndDiscard_HighOccludedTimeoutParam[] =
     "HighOccludedTimeoutSeconds";
-const char kProactiveTabDiscard_FaviconUpdateObservationWindow[] =
+const char kProactiveTabFreezeAndDiscard_FaviconUpdateObservationWindow[] =
     "FaviconUpdateObservationWindow";
-const char kProactiveTabDiscard_TitleUpdateObservationWindow[] =
+const char kProactiveTabFreezeAndDiscard_TitleUpdateObservationWindow[] =
     "TitleUpdateObservationWindow";
-const char kProactiveTabDiscard_AudioUsageObservationWindow[] =
+const char kProactiveTabFreezeAndDiscard_AudioUsageObservationWindow[] =
     "AudioUsageObservationWindow";
-const char kProactiveTabDiscard_NotificationsUsageObservationWindow[] =
+const char kProactiveTabFreezeAndDiscard_NotificationsUsageObservationWindow[] =
     "NotificationsUsageObservationWindow";
-const char kProactiveTabDiscard_FreezeTimeout[] = "FreezeTimeout";
+const char kProactiveTabFreezeAndDiscard_FreezeTimeout[] = "FreezeTimeout";
 
-// Default values for ProactiveTabDiscardParams.
-//
+// Default values for ProactiveTabFreezeAndDiscardParams.
+const bool kProactiveTabFreezeAndDiscard_ShouldProactivelyDiscardDefault =
+    false;
 // 50% of people cap out at 4 tabs, so for them proactive discarding won't even
 // be invoked. See Tabs.MaxTabsInADay.
 // TODO(chrisha): This should eventually be informed by the number of tabs
 // typically used over a given time horizon (metric being developed).
-const uint32_t kProactiveTabDiscard_LowLoadedTabCountDefault = 4;
+const uint32_t kProactiveTabFreezeAndDiscard_LowLoadedTabCountDefault = 4;
 // Testing in the lab shows that 2GB devices suffer beyond 6 tabs, and 4GB
 // devices suffer beyond about 12 tabs. As a very simple first step, we'll aim
 // at allowing 3 tabs per GB of RAM on a system before proactive discarding
 // kicks in. This is a system resource dependent max, which is combined with the
 // DefaultMaxLoadedTabCount to determine the max on a system.
-const uint32_t kProactiveTabDiscard_ModerateLoadedTabsPerGbRamDefault = 3;
+const uint32_t kProactiveTabFreezeAndDiscard_ModerateLoadedTabsPerGbRamDefault =
+    3;
 // 99.9% of people cap out with fewer than this number, so only 0.1% of the
 // population should ever encounter proactive discarding based on this cap.
-const uint32_t kProactiveTabDiscard_HighLoadedTabCountDefault = 100;
+const uint32_t kProactiveTabFreezeAndDiscard_HighLoadedTabCountDefault = 100;
 // Current discarding uses 10 minutes as a minimum cap. This uses exponentially
 // increasing timeouts beyond that.
-const base::TimeDelta kProactiveTabDiscard_LowOccludedTimeoutDefault =
+const base::TimeDelta kProactiveTabFreezeAndDiscard_LowOccludedTimeoutDefault =
     base::TimeDelta::FromHours(6);
-const base::TimeDelta kProactiveTabDiscard_ModerateOccludedTimeoutDefault =
-    base::TimeDelta::FromHours(1);
-const base::TimeDelta kProactiveTabDiscard_HighOccludedTimeoutDefault =
+const base::TimeDelta
+    kProactiveTabFreezeAndDiscard_ModerateOccludedTimeoutDefault =
+        base::TimeDelta::FromHours(1);
+const base::TimeDelta kProactiveTabFreezeAndDiscard_HighOccludedTimeoutDefault =
     base::TimeDelta::FromMinutes(10);
 // Observations windows have a default value of 2 hours, 95% of backgrounded
 // tabs don't use any of these features in this time window.
 const base::TimeDelta
-    kProactiveTabDiscard_FaviconUpdateObservationWindow_Default =
+    kProactiveTabFreezeAndDiscard_FaviconUpdateObservationWindow_Default =
         base::TimeDelta::FromHours(2);
 const base::TimeDelta
-    kProactiveTabDiscard_TitleUpdateObservationWindow_Default =
+    kProactiveTabFreezeAndDiscard_TitleUpdateObservationWindow_Default =
         base::TimeDelta::FromHours(2);
-const base::TimeDelta kProactiveTabDiscard_AudioUsageObservationWindow_Default =
-    base::TimeDelta::FromHours(2);
 const base::TimeDelta
-    kProactiveTabDiscard_NotificationsUsageObservationWindow_Default =
+    kProactiveTabFreezeAndDiscard_AudioUsageObservationWindow_Default =
         base::TimeDelta::FromHours(2);
-const base::TimeDelta kProactiveTabDiscard_FreezeTimeout_Default =
+const base::TimeDelta
+    kProactiveTabFreezeAndDiscard_NotificationsUsageObservationWindow_Default =
+        base::TimeDelta::FromHours(2);
+const base::TimeDelta kProactiveTabFreezeAndDiscard_FreezeTimeout_Default =
     base::TimeDelta::FromMinutes(10);
 
-ProactiveTabDiscardParams::ProactiveTabDiscardParams() = default;
-ProactiveTabDiscardParams::ProactiveTabDiscardParams(
-    const ProactiveTabDiscardParams& rhs) = default;
+ProactiveTabFreezeAndDiscardParams::ProactiveTabFreezeAndDiscardParams() =
+    default;
+ProactiveTabFreezeAndDiscardParams::ProactiveTabFreezeAndDiscardParams(
+    const ProactiveTabFreezeAndDiscardParams& rhs) = default;
 
-ProactiveTabDiscardParams GetProactiveTabDiscardParams(int memory_in_gb) {
-  ProactiveTabDiscardParams params = {};
+ProactiveTabFreezeAndDiscardParams GetProactiveTabFreezeAndDiscardParams(
+    int memory_in_gb) {
+  ProactiveTabFreezeAndDiscardParams params = {};
+
+  params.should_proactively_discard = base::GetFieldTrialParamByFeatureAsBool(
+      features::kProactiveTabFreezeAndDiscard,
+      kProactiveTabFreezeAndDiscard_ShouldProactivelyDiscard,
+      kProactiveTabFreezeAndDiscard_ShouldProactivelyDiscardDefault);
+
   params.low_loaded_tab_count = base::GetFieldTrialParamByFeatureAsInt(
-      features::kProactiveTabDiscarding,
-      kProactiveTabDiscard_LowLoadedTabCountParam,
-      kProactiveTabDiscard_LowLoadedTabCountDefault);
+      features::kProactiveTabFreezeAndDiscard,
+      kProactiveTabFreezeAndDiscard_LowLoadedTabCountParam,
+      kProactiveTabFreezeAndDiscard_LowLoadedTabCountDefault);
 
   params.high_loaded_tab_count = base::GetFieldTrialParamByFeatureAsInt(
-      features::kProactiveTabDiscarding,
-      kProactiveTabDiscard_HighLoadedTabCountParam,
-      kProactiveTabDiscard_HighLoadedTabCountDefault);
+      features::kProactiveTabFreezeAndDiscard,
+      kProactiveTabFreezeAndDiscard_HighLoadedTabCountParam,
+      kProactiveTabFreezeAndDiscard_HighLoadedTabCountDefault);
 
   // |moderate_loaded_tab_count| determined after |high_loaded_tab_count| so it
   // can be enforced that it is lower than |high_loaded_tab_count|.
@@ -156,61 +171,65 @@
 
   params.low_occluded_timeout =
       base::TimeDelta::FromSeconds(base::GetFieldTrialParamByFeatureAsInt(
-          features::kProactiveTabDiscarding,
-          kProactiveTabDiscard_LowOccludedTimeoutParam,
-          kProactiveTabDiscard_LowOccludedTimeoutDefault.InSeconds()));
+          features::kProactiveTabFreezeAndDiscard,
+          kProactiveTabFreezeAndDiscard_LowOccludedTimeoutParam,
+          kProactiveTabFreezeAndDiscard_LowOccludedTimeoutDefault.InSeconds()));
 
   params.moderate_occluded_timeout =
       base::TimeDelta::FromSeconds(base::GetFieldTrialParamByFeatureAsInt(
-          features::kProactiveTabDiscarding,
-          kProactiveTabDiscard_ModerateOccludedTimeoutParam,
-          kProactiveTabDiscard_ModerateOccludedTimeoutDefault.InSeconds()));
+          features::kProactiveTabFreezeAndDiscard,
+          kProactiveTabFreezeAndDiscard_ModerateOccludedTimeoutParam,
+          kProactiveTabFreezeAndDiscard_ModerateOccludedTimeoutDefault
+              .InSeconds()));
 
   params.high_occluded_timeout =
       base::TimeDelta::FromSeconds(base::GetFieldTrialParamByFeatureAsInt(
-          features::kProactiveTabDiscarding,
-          kProactiveTabDiscard_HighOccludedTimeoutParam,
-          kProactiveTabDiscard_HighOccludedTimeoutDefault.InSeconds()));
+          features::kProactiveTabFreezeAndDiscard,
+          kProactiveTabFreezeAndDiscard_HighOccludedTimeoutParam,
+          kProactiveTabFreezeAndDiscard_HighOccludedTimeoutDefault
+              .InSeconds()));
 
   params.favicon_update_observation_window =
       base::TimeDelta::FromSeconds(base::GetFieldTrialParamByFeatureAsInt(
-          features::kProactiveTabDiscarding,
-          kProactiveTabDiscard_FaviconUpdateObservationWindow,
-          kProactiveTabDiscard_FaviconUpdateObservationWindow_Default
+          features::kProactiveTabFreezeAndDiscard,
+          kProactiveTabFreezeAndDiscard_FaviconUpdateObservationWindow,
+          kProactiveTabFreezeAndDiscard_FaviconUpdateObservationWindow_Default
               .InSeconds()));
 
   params.title_update_observation_window =
       base::TimeDelta::FromSeconds(base::GetFieldTrialParamByFeatureAsInt(
-          features::kProactiveTabDiscarding,
-          kProactiveTabDiscard_TitleUpdateObservationWindow,
-          kProactiveTabDiscard_TitleUpdateObservationWindow_Default
+          features::kProactiveTabFreezeAndDiscard,
+          kProactiveTabFreezeAndDiscard_TitleUpdateObservationWindow,
+          kProactiveTabFreezeAndDiscard_TitleUpdateObservationWindow_Default
               .InSeconds()));
 
   params.audio_usage_observation_window =
       base::TimeDelta::FromSeconds(base::GetFieldTrialParamByFeatureAsInt(
-          features::kProactiveTabDiscarding,
-          kProactiveTabDiscard_AudioUsageObservationWindow,
-          kProactiveTabDiscard_AudioUsageObservationWindow_Default
+          features::kProactiveTabFreezeAndDiscard,
+          kProactiveTabFreezeAndDiscard_AudioUsageObservationWindow,
+          kProactiveTabFreezeAndDiscard_AudioUsageObservationWindow_Default
               .InSeconds()));
 
   params.notifications_usage_observation_window =
       base::TimeDelta::FromSeconds(base::GetFieldTrialParamByFeatureAsInt(
-          features::kProactiveTabDiscarding,
-          kProactiveTabDiscard_NotificationsUsageObservationWindow,
-          kProactiveTabDiscard_NotificationsUsageObservationWindow_Default
+          features::kProactiveTabFreezeAndDiscard,
+          kProactiveTabFreezeAndDiscard_NotificationsUsageObservationWindow,
+          kProactiveTabFreezeAndDiscard_NotificationsUsageObservationWindow_Default
               .InSeconds()));
 
   params.freeze_timeout =
       base::TimeDelta::FromSeconds(base::GetFieldTrialParamByFeatureAsInt(
-          features::kProactiveTabDiscarding, kProactiveTabDiscard_FreezeTimeout,
-          kProactiveTabDiscard_FreezeTimeout_Default.InSeconds()));
+          features::kProactiveTabFreezeAndDiscard,
+          kProactiveTabFreezeAndDiscard_FreezeTimeout,
+          kProactiveTabFreezeAndDiscard_FreezeTimeout_Default.InSeconds()));
 
   return params;
 }
 
-const ProactiveTabDiscardParams& GetStaticProactiveTabDiscardParams() {
-  static base::NoDestructor<ProactiveTabDiscardParams> params(
-      GetProactiveTabDiscardParams());
+const ProactiveTabFreezeAndDiscardParams&
+GetStaticProactiveTabFreezeAndDiscardParams() {
+  static base::NoDestructor<ProactiveTabFreezeAndDiscardParams> params(
+      GetProactiveTabFreezeAndDiscardParams());
   return *params;
 }
 
diff --git a/chrome/browser/resource_coordinator/tab_manager_features.h b/chrome/browser/resource_coordinator/tab_manager_features.h
index d3d9c50..402ecbe 100644
--- a/chrome/browser/resource_coordinator/tab_manager_features.h
+++ b/chrome/browser/resource_coordinator/tab_manager_features.h
@@ -13,7 +13,7 @@
 namespace features {
 
 extern const base::Feature kCustomizedTabLoadTimeout;
-extern const base::Feature kProactiveTabDiscarding;
+extern const base::Feature kProactiveTabFreezeAndDiscard;
 extern const base::Feature kStaggeredBackgroundTabOpening;
 extern const base::Feature kStaggeredBackgroundTabOpeningExperiment;
 extern const base::Feature kTabRanker;
@@ -23,39 +23,48 @@
 namespace resource_coordinator {
 
 // Variations parameter names related to proactive discarding.
-// See ProactiveTabDiscardsParams for details.
-extern const char kProactiveTabDiscard_LowLoadedTabCountParam[];
-extern const char kProactiveTabDiscard_ModerateLoadedTabsPerGbRamParam[];
-extern const char kProactiveTabDiscard_HighLoadedTabCountParam[];
-extern const char kProactiveTabDiscard_LowOccludedTimeoutParam[];
-extern const char kProactiveTabDiscard_ModerateOccludedTimeoutParam[];
-extern const char kProactiveTabDiscard_HighOccludedTimeoutParam[];
-extern const char kProactiveTabDiscard_FaviconUpdateObservationWindow[];
-extern const char kProactiveTabDiscard_TitleUpdateObservationWindow[];
-extern const char kProactiveTabDiscard_AudioUsageObservationWindow[];
-extern const char kProactiveTabDiscard_NotificationsUsageObservationWindow[];
-extern const char kProactiveTabDiscard_FreezeTimeout[];
+// See ProactiveTabFreezeAndDiscardsParams for details.
+extern const char kProactiveTabFreezeAndDiscard_ShouldProactivelyDiscard[];
+extern const char kProactiveTabFreezeAndDiscard_LowLoadedTabCountParam[];
+extern const char
+    kProactiveTabFreezeAndDiscard_ModerateLoadedTabsPerGbRamParam[];
+extern const char kProactiveTabFreezeAndDiscard_HighLoadedTabCountParam[];
+extern const char kProactiveTabFreezeAndDiscard_LowOccludedTimeoutParam[];
+extern const char kProactiveTabFreezeAndDiscard_ModerateOccludedTimeoutParam[];
+extern const char kProactiveTabFreezeAndDiscard_HighOccludedTimeoutParam[];
+extern const char
+    kProactiveTabFreezeAndDiscard_FaviconUpdateObservationWindow[];
+extern const char kProactiveTabFreezeAndDiscard_TitleUpdateObservationWindow[];
+extern const char kProactiveTabFreezeAndDiscard_AudioUsageObservationWindow[];
+extern const char
+    kProactiveTabFreezeAndDiscard_NotificationsUsageObservationWindow[];
+extern const char kProactiveTabFreezeAndDiscard_FreezeTimeout[];
 
 // Default values of parameters related to proactive discarding.
-// See ProactiveTabDiscardsParams for details.
-extern const uint32_t kProactiveTabDiscard_LowLoadedTabCountDefault;
-extern const uint32_t kProactiveTabDiscard_ModerateLoadedTabsPerGbRamDefault;
-extern const uint32_t kProactiveTabDiscard_HighLoadedTabCountDefault;
-extern const base::TimeDelta kProactiveTabDiscard_LowOccludedTimeoutDefault;
+// See ProactiveTabFreezeAndDiscardsParams for details.
+extern const bool kProactiveTabFreezeAndDiscard_ShouldProactivelyDiscardDefault;
+extern const uint32_t kProactiveTabFreezeAndDiscard_LowLoadedTabCountDefault;
+extern const uint32_t
+    kProactiveTabFreezeAndDiscard_ModerateLoadedTabsPerGbRamDefault;
+extern const uint32_t kProactiveTabFreezeAndDiscard_HighLoadedTabCountDefault;
 extern const base::TimeDelta
-    kProactiveTabDiscard_ModerateOccludedTimeoutDefault;
-extern const base::TimeDelta kProactiveTabDiscard_HighOccludedTimeoutDefault;
+    kProactiveTabFreezeAndDiscard_LowOccludedTimeoutDefault;
 extern const base::TimeDelta
-    kProactiveTabDiscard_FaviconUpdateObservationWindow_Default;
+    kProactiveTabFreezeAndDiscard_ModerateOccludedTimeoutDefault;
 extern const base::TimeDelta
-    kProactiveTabDiscard_TitleUpdateObservationWindow_Default;
+    kProactiveTabFreezeAndDiscard_HighOccludedTimeoutDefault;
 extern const base::TimeDelta
-    kProactiveTabDiscard_AudioUsageObservationWindow_Default;
+    kProactiveTabFreezeAndDiscard_FaviconUpdateObservationWindow_Default;
 extern const base::TimeDelta
-    kProactiveTabDiscard_NotificationsUsageObservationWindow_Default;
-extern const base::TimeDelta kProactiveTabDiscard_FreezeTimeout_Default;
+    kProactiveTabFreezeAndDiscard_TitleUpdateObservationWindow_Default;
+extern const base::TimeDelta
+    kProactiveTabFreezeAndDiscard_AudioUsageObservationWindow_Default;
+extern const base::TimeDelta
+    kProactiveTabFreezeAndDiscard_NotificationsUsageObservationWindow_Default;
+extern const base::TimeDelta
+    kProactiveTabFreezeAndDiscard_FreezeTimeout_Default;
 
-// Parameters used by the proactive tab discarding feature.
+// Parameters used by the proactive tab freezing and discarding feature.
 //
 // Proactive discarding has 5 key parameters:
 //
@@ -100,10 +109,15 @@
 // NOTE: This is extremely simplistic, and by design. We will be using this to
 // do a very simple "lightspeed" experiment to determine how much possible
 // savings proactive discarding can hope to achieve.
-struct ProactiveTabDiscardParams {
-  ProactiveTabDiscardParams();
-  ProactiveTabDiscardParams(const ProactiveTabDiscardParams& rhs);
+struct ProactiveTabFreezeAndDiscardParams {
+  ProactiveTabFreezeAndDiscardParams();
+  ProactiveTabFreezeAndDiscardParams(
+      const ProactiveTabFreezeAndDiscardParams& rhs);
 
+  // Whether tabs should be proactively discarded. When the
+  // |kProactiveTabFreezeAndDiscard| feature is enabled and this is false, only
+  // proactive tab freezing happens.
+  bool should_proactively_discard;
   // Tab count (inclusive) beyond which the state transitions to MODERATE.
   // Intended to cover the majority of simple workflows and be small enough that
   // it is very unlikely that memory pressure will be encountered with this many
@@ -145,13 +159,14 @@
 // Gets parameters for the proactive tab discarding feature. This does no
 // parameter validation, and sets the default values if the feature is not
 // enabled.
-ProactiveTabDiscardParams GetProactiveTabDiscardParams(
+ProactiveTabFreezeAndDiscardParams GetProactiveTabFreezeAndDiscardParams(
     int memory_in_gb = base::SysInfo::AmountOfPhysicalMemory() /
                        (1024 * 1024 * 1024));
 
-// Return a static ProactiveTabDiscardParams object that can be used by all the
-// classes that need one.
-const ProactiveTabDiscardParams& GetStaticProactiveTabDiscardParams();
+// Return a static ProactiveTabFreezeAndDiscardParams object that can be used by
+// all the classes that need one.
+const ProactiveTabFreezeAndDiscardParams&
+GetStaticProactiveTabFreezeAndDiscardParams();
 
 base::TimeDelta GetTabLoadTimeout(const base::TimeDelta& default_timeout);
 
diff --git a/chrome/browser/resource_coordinator/tab_manager_features_unittest.cc b/chrome/browser/resource_coordinator/tab_manager_features_unittest.cc
index 3931b21..7599836 100644
--- a/chrome/browser/resource_coordinator/tab_manager_features_unittest.cc
+++ b/chrome/browser/resource_coordinator/tab_manager_features_unittest.cc
@@ -20,7 +20,7 @@
   // variations parameter values.
   void EnableProactiveTabDiscarding() {
     std::set<std::string> features;
-    features.insert(features::kProactiveTabDiscarding.name);
+    features.insert(features::kProactiveTabFreezeAndDiscard.name);
     variations_manager_.SetVariationParamsWithFeatureAssociations(
         "DummyTrial", params_, features);
   }
@@ -41,8 +41,8 @@
       base::TimeDelta title_update_observation_window,
       base::TimeDelta audio_usage_observation_window,
       base::TimeDelta notifications_usage_observation_window) {
-    ProactiveTabDiscardParams params =
-        GetProactiveTabDiscardParams(memory_in_gb);
+    ProactiveTabFreezeAndDiscardParams params =
+        GetProactiveTabFreezeAndDiscardParams(memory_in_gb);
 
     EXPECT_EQ(low_loaded_tab_count, params.low_loaded_tab_count);
     EXPECT_EQ(moderate_loaded_tab_count, params.moderate_loaded_tab_count);
@@ -67,19 +67,20 @@
               params.notifications_usage_observation_window);
   }
 
-  void ExpectDefaultProactiveTabDiscardParams() {
+  void ExpectDefaultProactiveTabFreezeAndDiscardParams() {
     int memory_in_gb = 4;
     ExpectProactiveTabDiscardingParams(
-        kProactiveTabDiscard_LowLoadedTabCountDefault,
-        kProactiveTabDiscard_ModerateLoadedTabsPerGbRamDefault * memory_in_gb,
-        kProactiveTabDiscard_HighLoadedTabCountDefault, memory_in_gb,
-        kProactiveTabDiscard_LowOccludedTimeoutDefault,
-        kProactiveTabDiscard_ModerateOccludedTimeoutDefault,
-        kProactiveTabDiscard_HighOccludedTimeoutDefault,
-        kProactiveTabDiscard_FaviconUpdateObservationWindow_Default,
-        kProactiveTabDiscard_TitleUpdateObservationWindow_Default,
-        kProactiveTabDiscard_AudioUsageObservationWindow_Default,
-        kProactiveTabDiscard_NotificationsUsageObservationWindow_Default);
+        kProactiveTabFreezeAndDiscard_LowLoadedTabCountDefault,
+        kProactiveTabFreezeAndDiscard_ModerateLoadedTabsPerGbRamDefault *
+            memory_in_gb,
+        kProactiveTabFreezeAndDiscard_HighLoadedTabCountDefault, memory_in_gb,
+        kProactiveTabFreezeAndDiscard_LowOccludedTimeoutDefault,
+        kProactiveTabFreezeAndDiscard_ModerateOccludedTimeoutDefault,
+        kProactiveTabFreezeAndDiscard_HighOccludedTimeoutDefault,
+        kProactiveTabFreezeAndDiscard_FaviconUpdateObservationWindow_Default,
+        kProactiveTabFreezeAndDiscard_TitleUpdateObservationWindow_Default,
+        kProactiveTabFreezeAndDiscard_AudioUsageObservationWindow_Default,
+        kProactiveTabFreezeAndDiscard_NotificationsUsageObservationWindow_Default);
   }
 
  private:
@@ -90,44 +91,50 @@
 }  // namespace
 
 TEST_F(TabManagerFeaturesTest,
-       GetProactiveTabDiscardParamsDisabledFeatureGoesToDefault) {
+       GetProactiveTabFreezeAndDiscardParamsDisabledFeatureGoesToDefault) {
   // Do not enable the proactive tab discarding feature.
-  ExpectDefaultProactiveTabDiscardParams();
-}
-
-TEST_F(TabManagerFeaturesTest, GetProactiveTabDiscardParamsNoneGoesToDefault) {
-  EnableProactiveTabDiscarding();
-  ExpectDefaultProactiveTabDiscardParams();
+  ExpectDefaultProactiveTabFreezeAndDiscardParams();
 }
 
 TEST_F(TabManagerFeaturesTest,
-       GetProactiveTabDiscardParamsInvalidGoesToDefault) {
-  SetParam(kProactiveTabDiscard_LowLoadedTabCountParam, "ab");
-  SetParam(kProactiveTabDiscard_ModerateLoadedTabsPerGbRamParam, "27.8");
-  SetParam(kProactiveTabDiscard_HighLoadedTabCountParam, "4e8");
-  SetParam(kProactiveTabDiscard_LowOccludedTimeoutParam, "---");
-  SetParam(kProactiveTabDiscard_ModerateOccludedTimeoutParam, " ");
-  SetParam(kProactiveTabDiscard_HighOccludedTimeoutParam, "");
-  SetParam(kProactiveTabDiscard_FaviconUpdateObservationWindow, "    ");
-  SetParam(kProactiveTabDiscard_TitleUpdateObservationWindow, "foo");
-  SetParam(kProactiveTabDiscard_AudioUsageObservationWindow, ".");
-  SetParam(kProactiveTabDiscard_NotificationsUsageObservationWindow, "abc");
+       GetProactiveTabFreezeAndDiscardParamsNoneGoesToDefault) {
   EnableProactiveTabDiscarding();
-  ExpectDefaultProactiveTabDiscardParams();
+  ExpectDefaultProactiveTabFreezeAndDiscardParams();
 }
 
-TEST_F(TabManagerFeaturesTest, GetProactiveTabDiscardParams) {
-  SetParam(kProactiveTabDiscard_LowLoadedTabCountParam, "7");
-  SetParam(kProactiveTabDiscard_ModerateLoadedTabsPerGbRamParam, "4");
-  SetParam(kProactiveTabDiscard_HighLoadedTabCountParam, "42");
+TEST_F(TabManagerFeaturesTest,
+       GetProactiveTabFreezeAndDiscardParamsInvalidGoesToDefault) {
+  SetParam(kProactiveTabFreezeAndDiscard_LowLoadedTabCountParam, "ab");
+  SetParam(kProactiveTabFreezeAndDiscard_ModerateLoadedTabsPerGbRamParam,
+           "27.8");
+  SetParam(kProactiveTabFreezeAndDiscard_HighLoadedTabCountParam, "4e8");
+  SetParam(kProactiveTabFreezeAndDiscard_LowOccludedTimeoutParam, "---");
+  SetParam(kProactiveTabFreezeAndDiscard_ModerateOccludedTimeoutParam, " ");
+  SetParam(kProactiveTabFreezeAndDiscard_HighOccludedTimeoutParam, "");
+  SetParam(kProactiveTabFreezeAndDiscard_FaviconUpdateObservationWindow,
+           "    ");
+  SetParam(kProactiveTabFreezeAndDiscard_TitleUpdateObservationWindow, "foo");
+  SetParam(kProactiveTabFreezeAndDiscard_AudioUsageObservationWindow, ".");
+  SetParam(kProactiveTabFreezeAndDiscard_NotificationsUsageObservationWindow,
+           "abc");
+  EnableProactiveTabDiscarding();
+  ExpectDefaultProactiveTabFreezeAndDiscardParams();
+}
+
+TEST_F(TabManagerFeaturesTest, GetProactiveTabFreezeAndDiscardParams) {
+  SetParam(kProactiveTabFreezeAndDiscard_LowLoadedTabCountParam, "7");
+  SetParam(kProactiveTabFreezeAndDiscard_ModerateLoadedTabsPerGbRamParam, "4");
+  SetParam(kProactiveTabFreezeAndDiscard_HighLoadedTabCountParam, "42");
   // These are expressed in seconds.
-  SetParam(kProactiveTabDiscard_LowOccludedTimeoutParam, "60");
-  SetParam(kProactiveTabDiscard_ModerateOccludedTimeoutParam, "120");
-  SetParam(kProactiveTabDiscard_HighOccludedTimeoutParam, "247");
-  SetParam(kProactiveTabDiscard_FaviconUpdateObservationWindow, "3600");
-  SetParam(kProactiveTabDiscard_TitleUpdateObservationWindow, "36000");
-  SetParam(kProactiveTabDiscard_AudioUsageObservationWindow, "360000");
-  SetParam(kProactiveTabDiscard_NotificationsUsageObservationWindow, "3600000");
+  SetParam(kProactiveTabFreezeAndDiscard_LowOccludedTimeoutParam, "60");
+  SetParam(kProactiveTabFreezeAndDiscard_ModerateOccludedTimeoutParam, "120");
+  SetParam(kProactiveTabFreezeAndDiscard_HighOccludedTimeoutParam, "247");
+  SetParam(kProactiveTabFreezeAndDiscard_FaviconUpdateObservationWindow,
+           "3600");
+  SetParam(kProactiveTabFreezeAndDiscard_TitleUpdateObservationWindow, "36000");
+  SetParam(kProactiveTabFreezeAndDiscard_AudioUsageObservationWindow, "360000");
+  SetParam(kProactiveTabFreezeAndDiscard_NotificationsUsageObservationWindow,
+           "3600000");
   EnableProactiveTabDiscarding();
 
   // Should snap |moderate_loaded_tab_count| to |low_loaded_tab_count|, when the
diff --git a/chrome/browser/resource_coordinator/tab_manager_unittest.cc b/chrome/browser/resource_coordinator/tab_manager_unittest.cc
index 1ec8a384..149f74cc 100644
--- a/chrome/browser/resource_coordinator/tab_manager_unittest.cc
+++ b/chrome/browser/resource_coordinator/tab_manager_unittest.cc
@@ -285,18 +285,20 @@
  public:
   void SetUp() override {
     scoped_feature_list_.InitAndEnableFeature(
-        features::kProactiveTabDiscarding);
+        features::kProactiveTabFreezeAndDiscard);
 
     TabManagerTest::SetUp();
 
     // Use test constants for proactive discarding parameters.
-    tab_manager_->proactive_discard_params_ = GetTestProactiveDiscardParams();
+    tab_manager_->proactive_freeze_discard_params_ =
+        GetTestProactiveDiscardParams();
   }
 
-  ProactiveTabDiscardParams GetTestProactiveDiscardParams() {
-    // Return a ProactiveTabDiscardParams struct with default test
+  ProactiveTabFreezeAndDiscardParams GetTestProactiveDiscardParams() {
+    // Return a ProactiveTabFreezeAndDiscardParams struct with default test
     // parameters.
-    ProactiveTabDiscardParams params;
+    ProactiveTabFreezeAndDiscardParams params = {};
+    params.should_proactively_discard = true;
     params.low_occluded_timeout = kLowOccludedTimeout;
     params.moderate_occluded_timeout = kModerateOccludedTimeout;
     params.high_occluded_timeout = kHighOccludedTimeout;
@@ -1492,7 +1494,11 @@
   tab_strip->CloseAllTabs();
 }
 
-TEST_F(TabManagerTest, ProactiveDiscardDoesNotOccurWhenDisabled) {
+TEST_F(TabManagerWithProactiveDiscardExperimentEnabledTest,
+       NoProactiveDiscardWhenDiscardingVariationParamDisabled) {
+  tab_manager_->proactive_freeze_discard_params_.should_proactively_discard =
+      false;
+
   auto window = std::make_unique<TestBrowserWindow>();
   Browser::CreateParams params(profile(), true);
   params.type = Browser::TYPE_TABBED;
@@ -1501,19 +1507,22 @@
   TabStripModel* tab_strip = browser->tab_strip_model();
 
   tab_strip->AppendWebContents(CreateWebContents(), /*foreground=*/true);
-  tab_strip->GetWebContentsAt(0)->WasShown();
-  tab_strip->GetWebContentsAt(0)->WasHidden();
+  tab_strip->AppendWebContents(CreateWebContents(), /*foreground=*/false);
+  tab_strip->GetWebContentsAt(1)->WasShown();
+  tab_strip->GetWebContentsAt(1)->WasHidden();
 
   task_runner_->FastForwardBy(kLowOccludedTimeout);
 
-  EXPECT_FALSE(
-      TabLifecycleUnitExternal::FromWebContents(tab_strip->GetWebContentsAt(0))
-          ->IsDiscarded());
+  EXPECT_FALSE(IsTabDiscarded(tab_strip->GetWebContentsAt(1)));
 
   tab_strip->CloseAllTabs();
 }
 
-TEST_F(TabManagerTest, FreezingDoesNotOccurWhenDisabled) {
+TEST_F(TabManagerWithProactiveDiscardExperimentEnabledTest,
+       FreezingWhenDiscardingVariationParamDisabled) {
+  tab_manager_->proactive_freeze_discard_params_.should_proactively_discard =
+      false;
+
   auto window = std::make_unique<TestBrowserWindow>();
   Browser::CreateParams params(profile(), true);
   params.type = Browser::TYPE_TABBED;
@@ -1522,12 +1531,57 @@
   TabStripModel* tab_strip = browser->tab_strip_model();
 
   tab_strip->AppendWebContents(CreateWebContents(), /*foreground=*/true);
-  tab_strip->GetWebContentsAt(0)->WasShown();
-  tab_strip->GetWebContentsAt(0)->WasHidden();
+  tab_strip->AppendWebContents(CreateWebContents(), /*foreground=*/false);
+  TabLoadTracker::Get()->TransitionStateForTesting(
+      tab_strip->GetWebContentsAt(1), TabLoadTracker::LoadingState::LOADED);
+  tab_strip->GetWebContentsAt(1)->WasShown();
+  tab_strip->GetWebContentsAt(1)->WasHidden();
 
   task_runner_->FastForwardBy(kFreezeTimeout);
 
-  EXPECT_FALSE(IsTabFrozen(tab_strip->GetWebContentsAt(0)));
+  EXPECT_TRUE(IsTabFrozen(tab_strip->GetWebContentsAt(1)));
+
+  tab_strip->CloseAllTabs();
+}
+
+TEST_F(TabManagerTest, NoProactiveDiscardWhenFeatureDisabled) {
+  auto window = std::make_unique<TestBrowserWindow>();
+  Browser::CreateParams params(profile(), true);
+  params.type = Browser::TYPE_TABBED;
+  params.window = window.get();
+  auto browser = std::make_unique<Browser>(params);
+  TabStripModel* tab_strip = browser->tab_strip_model();
+
+  tab_strip->AppendWebContents(CreateWebContents(), /*foreground=*/true);
+  tab_strip->AppendWebContents(CreateWebContents(), /*foreground=*/false);
+  tab_strip->GetWebContentsAt(1)->WasShown();
+  tab_strip->GetWebContentsAt(1)->WasHidden();
+
+  task_runner_->FastForwardBy(kLowOccludedTimeout);
+
+  EXPECT_FALSE(IsTabDiscarded(tab_strip->GetWebContentsAt(1)));
+
+  tab_strip->CloseAllTabs();
+}
+
+TEST_F(TabManagerTest, NoFreezingWhenFeatureDisabled) {
+  auto window = std::make_unique<TestBrowserWindow>();
+  Browser::CreateParams params(profile(), true);
+  params.type = Browser::TYPE_TABBED;
+  params.window = window.get();
+  auto browser = std::make_unique<Browser>(params);
+  TabStripModel* tab_strip = browser->tab_strip_model();
+
+  tab_strip->AppendWebContents(CreateWebContents(), /*foreground=*/true);
+  tab_strip->AppendWebContents(CreateWebContents(), /*foreground=*/false);
+  TabLoadTracker::Get()->TransitionStateForTesting(
+      tab_strip->GetWebContentsAt(1), TabLoadTracker::LoadingState::LOADED);
+  tab_strip->GetWebContentsAt(1)->WasShown();
+  tab_strip->GetWebContentsAt(1)->WasHidden();
+
+  task_runner_->FastForwardBy(kFreezeTimeout);
+
+  EXPECT_FALSE(IsTabFrozen(tab_strip->GetWebContentsAt(1)));
 
   tab_strip->CloseAllTabs();
 }
diff --git a/chrome/browser/resources/md_bookmarks/edit_dialog.html b/chrome/browser/resources/md_bookmarks/edit_dialog.html
index f5eb3ac..1fc0ecd 100644
--- a/chrome/browser/resources/md_bookmarks/edit_dialog.html
+++ b/chrome/browser/resources/md_bookmarks/edit_dialog.html
@@ -15,7 +15,7 @@
       <div slot="title">
         [[getDialogTitle_(isFolder_, isEdit_)]]
       </div>
-      <div slot="body" style="height: [[getHeightOfBody_(isFolder_)]]px">
+      <div slot="body">
         <paper-input always-float-label id="name"
             label="$i18n{editDialogNameInput}"
             value="{{titleValue_}}"
diff --git a/chrome/browser/resources/md_bookmarks/edit_dialog.js b/chrome/browser/resources/md_bookmarks/edit_dialog.js
index c9da7aa..d46092be 100644
--- a/chrome/browser/resources/md_bookmarks/edit_dialog.js
+++ b/chrome/browser/resources/md_bookmarks/edit_dialog.js
@@ -138,11 +138,4 @@
   onCancelButtonTap_: function() {
     this.$.dialog.cancel();
   },
-
-  /** @private */
-  getHeightOfBody_: function() {
-    const heightTwoInputs = 136;
-    const heightOneInput = 62;
-    return this.isFolder_ ? heightOneInput : heightTwoInputs;
-  },
 });
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/BUILD.gn b/chrome/browser/resources/settings/passwords_and_forms_page/BUILD.gn
index 4f4ba6a6..a25ebda 100644
--- a/chrome/browser/resources/settings/passwords_and_forms_page/BUILD.gn
+++ b/chrome/browser/resources/settings/passwords_and_forms_page/BUILD.gn
@@ -82,8 +82,6 @@
     ":password_list_item",
     ":password_manager_proxy",
     "..:global_scroll_target_behavior",
-    "//third_party/polymer/v1_0/components-chromium/iron-a11y-announcer:iron-a11y-announcer-extracted",
-    "//third_party/polymer/v1_0/components-chromium/iron-a11y-keys-behavior:iron-a11y-keys-behavior-extracted",
     "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu",
     "//ui/webui/resources/cr_elements/cr_toast:cr_toast",
     "//ui/webui/resources/js:assert",
@@ -97,7 +95,7 @@
 js_library("password_edit_dialog") {
   deps = [
     ":show_password_behavior",
-    "//ui/webui/resources/cr_elements/cr_input:cr_input",
+    "//third_party/polymer/v1_0/components-chromium/paper-input:paper-input-extracted",
   ]
 }
 
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.html b/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.html
index ef7c9c6..7466d9c 100644
--- a/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.html
+++ b/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.html
@@ -1,10 +1,10 @@
 <link rel="import" href="chrome://resources/html/polymer.html">
 
 <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.html">
 <link rel="import" href="chrome://resources/cr_elements/cr_icons_css.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
 <link rel="import" href="../icons.html">
 <link rel="import" href="../settings_shared_css.html">
 <link rel="import" href="../settings_vars_css.html">
@@ -13,43 +13,52 @@
 <dom-module id="password-edit-dialog">
   <template>
     <style include="settings-shared">
+      paper-input[readonly] {
+        /* Lighter than label to appear uneditable. */
+        color: var(--paper-grey-500);
+
+        /* For readonly inputs we don't want to show focus styles. */
+        --paper-input-container-underline-focus: {
+          display: none;
+        };
+
+        --paper-input-container-label-focus: {
+          color: var(--secondary-text-color);
+        };
+      }
+
       #passwordGroup {
         align-items: center;
         display: flex;
-        /* Offset contained cr-input margin to have consistent spacing with
-           other inputs. */
-        margin-top: -8px;
       }
 
-      cr-input {
+      paper-input {
         width: var(--settings-input-max-width);
-        --cr-input-error-display: none;
       }
 
       paper-icon-button-light {
         -webkit-margin-start: 2px;
         background-size: 24px;  /* Other buttons are sized by --cr-icon-size. */
-        margin-top: 16px;  /* Line up with cr-input. */
       }
     </style>
     <cr-dialog id="dialog" close-text="$i18n{close}">
       <div slot="title">$i18n{passwordDetailsTitle}</div>
       <div slot="body">
-        <cr-input id="websiteInput" label="$i18n{editPasswordWebsiteLabel}"
+        <paper-input id="websiteInput" label="$i18n{editPasswordWebsiteLabel}"
             value="[[item.entry.loginPair.urls.link]]" readonly
-            on-focus="onInputFocus_">
-        </cr-input>
-        <cr-input id="usernameInput" label="$i18n{editPasswordUsernameLabel}"
+            always-float-label on-focus="onInputFocus_">
+        </paper-input>
+        <paper-input id="usernameInput" label="$i18n{editPasswordUsernameLabel}"
             value="[[item.entry.loginPair.username]]" readonly
-            on-focus="onInputFocus_">
-        </cr-input>
+            always-float-label on-focus="onInputFocus_">
+        </paper-input>
         <div id="passwordGroup">
-          <cr-input id="passwordInput" readonly
+          <paper-input id="passwordInput" always-float-label
               label="$i18n{editPasswordPasswordLabel}"
               type="[[getPasswordInputType_(item.password)]]"
-              value="[[getPassword_(item.password)]]"
+              value="[[getPassword_(item.password)]]" readonly
               on-focus="onInputFocus_">
-          </cr-input>
+          </paper-input>
           <paper-icon-button-light id="showPasswordButtonContainer"
               class$="[[getIconClass_(item.password)]]"
               hidden$="[[item.entry.federationText]]">
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.js b/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.js
index de24af2..8ea5c3f 100644
--- a/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.js
+++ b/chrome/browser/resources/settings/passwords_and_forms_page/password_edit_dialog.js
@@ -39,7 +39,7 @@
    */
   onInputFocus_: function(event) {
     const inputElement =
-        /** @type {!CrInputElement} */ (Polymer.dom(event).localTarget)
+        /** @type {!PaperInputElement} */ (Polymer.dom(event).localTarget)
             .inputElement;
     inputElement.setSelectionRange(0, 0);
     inputElement.focus();
diff --git a/chrome/browser/resources/settings/people_page/sync_page.html b/chrome/browser/resources/settings/people_page/sync_page.html
index 2d63321..1c5cf73 100644
--- a/chrome/browser/resources/settings/people_page/sync_page.html
+++ b/chrome/browser/resources/settings/people_page/sync_page.html
@@ -4,13 +4,13 @@
 <link rel="import" href="chrome://resources/html/util.html">
 <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html">
 <link rel="import" href="chrome://resources/cr_elements/cr_expand_button/cr_expand_button.html">
-<link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.html">
 <link rel="import" href="chrome://resources/cr_elements/cr_toggle/cr_toggle.html">
 <link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-collapse/iron-collapse.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-group/paper-radio-group.html">
 <link rel="import" href="sync_browser_proxy.html">
 <link rel="import" href="../privacy_page/personalization_options.html">
@@ -31,8 +31,16 @@
         -webkit-margin-start: var(--settings-indent-width);
       }
 
-      cr-input {
+      paper-input {
         width: var(--settings-input-max-width);
+        --paper-input-container-focus-color: var(--google-blue-500);
+        --paper-input-container-input: {
+          font-size: inherit;
+        };
+      }
+
+      #saveNewPassphrase {
+        margin-top: 20px;
       }
 
       #existingPassphrase {
@@ -41,24 +49,20 @@
         border-bottom: var(--settings-separator-line);
       }
 
-      #existingPassphraseContainer {
-        /* The contained cr-input has different spacing on top and bottom due
-           to space allocated for error message, so it's easier to line up with
-           "start" alignment. */
-        align-items: start;
+      #existingPassphraseContainer,
+      #passphraseRecoverHint {
+        align-items: center;
       }
 
       #existingPassphraseInput {
         /* The submit button for the existing passphrase is on the same line. */
         -webkit-margin-end: 16px;
-      }
-
-      #submitExistingPassphrase {
-        margin-top: 8px;  /* Aligns with cr-input on the same line. */
-      }
-
-      #passphraseRecoverHint {
-        align-items: center;
+        display: inline-block;
+        --paper-input-container: {
+          padding: 0;
+          /* TODO(scottchen): remove margin once large font properly padded. */
+          margin-bottom: 1rem;
+        };
       }
 
       #sync-data-types .list-item:not([hidden]) ~ .list-item:not([hidden]) {
@@ -147,12 +151,12 @@
               </span>
             </div>
             <div id="existingPassphraseContainer" class="list-item">
-              <cr-input id="existingPassphraseInput" type="password"
+              <paper-input id="existingPassphraseInput" type="password"
                   value="{{existingPassphrase_}}"
                   placeholder="$i18n{passphrasePlaceholder}"
                   error-message="$i18n{incorrectPassphraseError}"
                   on-keypress="onSubmitExistingPassphraseTap_">
-              </cr-input>
+              </paper-input>
               <paper-button id="submitExistingPassphrase"
                   on-click="onSubmitExistingPassphraseTap_"
                   class="action-button" disabled="[[!existingPassphrase_]]">
@@ -392,16 +396,16 @@
                 <div class="list-item">
                   <span>$i18nRaw{passphraseExplanationText}</span>
                 </div>
-                <cr-input id="passphraseInput" type="password"
+                <paper-input id="passphraseInput" type="password"
                     value="{{passphrase_}}"
                     placeholder="$i18n{passphrasePlaceholder}"
                     error-message="$i18n{emptyPassphraseError}">
-                </cr-input>
-                <cr-input id="passphraseConfirmationInput" type="password"
+                </paper-input>
+                <paper-input id="passphraseConfirmationInput" type="password"
                     value="{{confirmation_}}"
                     placeholder="$i18n{passphraseConfirmationPlaceholder}"
                     error-message="$i18n{mismatchedPassphraseError}">
-                </cr-input>
+                </paper-input>
                 <paper-button id="saveNewPassphrase"
                     on-click="onSaveNewPassphraseTap_" class="action-button"
                     disabled="[[!isSaveNewPassphraseEnabled_(passphrase_,
diff --git a/chrome/browser/resources/settings/people_page/sync_page.js b/chrome/browser/resources/settings/people_page/sync_page.js
index 5ad605f..5076295e 100644
--- a/chrome/browser/resources/settings/people_page/sync_page.js
+++ b/chrome/browser/resources/settings/people_page/sync_page.js
@@ -367,7 +367,7 @@
     assert(this.creatingNewPassphrase_);
 
     // Ignore events on irrelevant elements or with irrelevant keys.
-    if (e.target.tagName != 'PAPER-BUTTON' && e.target.tagName != 'CR-INPUT')
+    if (e.target.tagName != 'PAPER-BUTTON' && e.target.tagName != 'PAPER-INPUT')
       return;
     if (e.type == 'keypress' && e.key != 'Enter')
       return;
diff --git a/chrome/browser/subresource_filter/chrome_subresource_filter_client.cc b/chrome/browser/subresource_filter/chrome_subresource_filter_client.cc
index 0592a8b..1898d29 100644
--- a/chrome/browser/subresource_filter/chrome_subresource_filter_client.cc
+++ b/chrome/browser/subresource_filter/chrome_subresource_filter_client.cc
@@ -90,17 +90,7 @@
 
 void ChromeSubresourceFilterClient::OnReloadRequested() {
   UMA_HISTOGRAM_BOOLEAN("SubresourceFilter.Prompt.NumReloads", true);
-  const GURL& whitelist_url = web_contents()->GetLastCommittedURL();
-
-  // Only whitelist via content settings when using the experimental UI,
-  // otherwise could get into a situation where content settings cannot be
-  // adjusted.
-  if (base::FeatureList::IsEnabled(
-          subresource_filter::kSafeBrowsingSubresourceFilterExperimentalUI)) {
-    WhitelistByContentSettings(whitelist_url);
-  } else {
-    WhitelistInCurrentWebContents(whitelist_url);
-  }
+  WhitelistByContentSettings(web_contents()->GetLastCommittedURL());
   web_contents()->GetController().Reload(content::ReloadType::NORMAL, true);
 }
 
@@ -137,8 +127,7 @@
                  subresource_filter::ActivationLevel::ENABLED);
   }
 
-  if (whitelisted_hosts_.count(url.host()) ||
-      settings_manager_->GetSitePermission(url) == CONTENT_SETTING_ALLOW) {
+  if (settings_manager_->GetSitePermission(url) == CONTENT_SETTING_ALLOW) {
     if (effective_activation_level ==
         subresource_filter::ActivationLevel::ENABLED) {
       *decision = subresource_filter::ActivationDecision::URL_WHITELISTED;
@@ -148,12 +137,6 @@
   return effective_activation_level;
 }
 
-void ChromeSubresourceFilterClient::WhitelistInCurrentWebContents(
-    const GURL& url) {
-  if (url.SchemeIsHTTPOrHTTPS())
-    whitelisted_hosts_.insert(url.host());
-}
-
 void ChromeSubresourceFilterClient::WhitelistByContentSettings(
     const GURL& top_level_url) {
   settings_manager_->WhitelistSite(top_level_url);
diff --git a/chrome/browser/subresource_filter/chrome_subresource_filter_client.h b/chrome/browser/subresource_filter/chrome_subresource_filter_client.h
index 9725123..ad4e25a 100644
--- a/chrome/browser/subresource_filter/chrome_subresource_filter_client.h
+++ b/chrome/browser/subresource_filter/chrome_subresource_filter_client.h
@@ -6,8 +6,6 @@
 #define CHROME_BROWSER_SUBRESOURCE_FILTER_CHROME_SUBRESOURCE_FILTER_CLIENT_H_
 
 #include <memory>
-#include <set>
-#include <string>
 #include <vector>
 
 #include "base/macros.h"
@@ -136,15 +134,9 @@
   static void LogAction(SubresourceFilterAction action);
 
  private:
-  // TODO(csharrison): Remove this once the experimental UI flag is either
-  // removed or merged with the top-level subresource filter flag.
-  void WhitelistInCurrentWebContents(const GURL& url);
-
   void WhitelistByContentSettings(const GURL& url);
   void ShowUI(const GURL& url);
 
-  std::set<std::string> whitelisted_hosts_;
-
   std::unique_ptr<subresource_filter::ContentSubresourceFilterThrottleManager>
       throttle_manager_;
 
diff --git a/chrome/browser/subresource_filter/subresource_filter_content_settings_manager.cc b/chrome/browser/subresource_filter/subresource_filter_content_settings_manager.cc
index 85aab3f..f9d9f587 100644
--- a/chrome/browser/subresource_filter/subresource_filter_content_settings_manager.cc
+++ b/chrome/browser/subresource_filter/subresource_filter_content_settings_manager.cc
@@ -6,7 +6,6 @@
 
 #include "base/auto_reset.h"
 #include "base/bind.h"
-#include "base/feature_list.h"
 #include "base/logging.h"
 #include "base/time/default_clock.h"
 #include "base/values.h"
@@ -20,7 +19,6 @@
 #include "components/content_settings/core/common/content_settings_pattern.h"
 #include "components/history/core/browser/history_service.h"
 #include "components/keyed_service/core/service_access_type.h"
-#include "components/subresource_filter/core/browser/subresource_filter_features.h"
 #include "url/gurl.h"
 
 namespace {
@@ -30,8 +28,7 @@
 
 bool ShouldUseSmartUI() {
 #if defined(OS_ANDROID)
-  return base::FeatureList::IsEnabled(
-      subresource_filter::kSafeBrowsingSubresourceFilterExperimentalUI);
+  return true;
 #endif
   return false;
 }
@@ -75,8 +72,6 @@
 }
 
 void SubresourceFilterContentSettingsManager::WhitelistSite(const GURL& url) {
-  DCHECK(base::FeatureList::IsEnabled(
-      subresource_filter::kSafeBrowsingSubresourceFilterExperimentalUI));
   base::AutoReset<bool> resetter(&ignore_settings_changes_, true);
   settings_map_->SetContentSettingDefaultScope(
       url, GURL(), ContentSettingsType::CONTENT_SETTINGS_TYPE_ADS,
@@ -128,9 +123,6 @@
 void SubresourceFilterContentSettingsManager::SetSiteMetadata(
     const GURL& url,
     std::unique_ptr<base::DictionaryValue> dict) {
-  if (!base::FeatureList::IsEnabled(
-          subresource_filter::kSafeBrowsingSubresourceFilterExperimentalUI))
-    return;
   settings_map_->SetWebsiteSettingDefaultScope(
       url, GURL(), ContentSettingsType::CONTENT_SETTINGS_TYPE_ADS_DATA,
       std::string(), std::move(dict));
diff --git a/chrome/browser/subresource_filter/subresource_filter_content_settings_manager_unittest.cc b/chrome/browser/subresource_filter/subresource_filter_content_settings_manager_unittest.cc
index 9f44bdc..a9f9ba2 100644
--- a/chrome/browser/subresource_filter/subresource_filter_content_settings_manager_unittest.cc
+++ b/chrome/browser/subresource_filter/subresource_filter_content_settings_manager_unittest.cc
@@ -24,15 +24,12 @@
 #include "components/content_settings/core/common/content_settings.h"
 #include "components/history/core/browser/history_service.h"
 #include "components/history/core/test/history_service_test_util.h"
-#include "components/subresource_filter/core/browser/subresource_filter_features.h"
-#include "components/subresource_filter/core/browser/subresource_filter_features_test_support.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
 namespace {
 
-using subresource_filter::testing::ScopedSubresourceFilterFeatureToggle;
 const char kActionsHistogram[] = "SubresourceFilter.Actions";
 
 class SubresourceFilterContentSettingsManagerTest : public testing::Test {
@@ -40,9 +37,6 @@
   SubresourceFilterContentSettingsManagerTest() {}
 
   void SetUp() override {
-    scoped_feature_toggle().ResetSubresourceFilterState(
-        base::FeatureList::OVERRIDE_ENABLE_FEATURE,
-        "SubresourceFilterExperimentalUI" /* additional_features */);
     settings_manager_ =
         SubresourceFilterProfileContextFactory::GetForProfile(&testing_profile_)
             ->settings_manager();
@@ -63,10 +57,6 @@
     return settings_manager_;
   }
 
-  ScopedSubresourceFilterFeatureToggle& scoped_feature_toggle() {
-    return scoped_feature_toggle_;
-  }
-
   TestingProfile* profile() { return &testing_profile_; }
 
   ContentSetting GetContentSettingMatchingUrlWithEmptyPath(const GURL& url) {
@@ -89,7 +79,6 @@
   base::ScopedTempDir scoped_dir_;
 
   content::TestBrowserThreadBundle thread_bundle_;
-  ScopedSubresourceFilterFeatureToggle scoped_feature_toggle_;
   base::HistogramTester histogram_tester_;
   TestingProfile testing_profile_;
 
@@ -292,25 +281,6 @@
 }
 
 TEST_F(SubresourceFilterContentSettingsManagerTest,
-       NoExperimentalUI_NoWebsiteSetting) {
-  GURL url("https://example.test/");
-  {
-    base::test::ScopedFeatureList scoped_disabled;
-    scoped_disabled.InitAndDisableFeature(
-        subresource_filter::kSafeBrowsingSubresourceFilterExperimentalUI);
-    settings_manager()->OnDidShowUI(url);
-    EXPECT_FALSE(settings_manager()->GetSiteMetadata(url));
-  }
-  {
-    base::test::ScopedFeatureList scoped_enable;
-    scoped_enable.InitAndEnableFeature(
-        subresource_filter::kSafeBrowsingSubresourceFilterExperimentalUI);
-    settings_manager()->OnDidShowUI(url);
-    EXPECT_TRUE(settings_manager()->GetSiteMetadata(url));
-  }
-}
-
-TEST_F(SubresourceFilterContentSettingsManagerTest,
        DefaultSettingsChange_NoWebsiteMetadata) {
   GURL url("https://example.test/");
   EXPECT_FALSE(settings_manager()->GetSiteMetadata(url));
diff --git a/chrome/browser/subresource_filter/subresource_filter_test_harness.cc b/chrome/browser/subresource_filter/subresource_filter_test_harness.cc
index 9064c71..ddfe1f7 100644
--- a/chrome/browser/subresource_filter/subresource_filter_test_harness.cc
+++ b/chrome/browser/subresource_filter/subresource_filter_test_harness.cc
@@ -45,9 +45,6 @@
   ChromeRenderViewHostTestHarness::SetUp();
 
   // Ensure correct features.
-  scoped_feature_toggle_.ResetSubresourceFilterState(
-      base::FeatureList::OVERRIDE_ENABLE_FEATURE,
-      "SafeBrowsingV4OnlyEnabled,SubresourceFilterExperimentalUI");
   scoped_configuration_.ResetConfiguration(subresource_filter::Configuration(
       subresource_filter::ActivationLevel::ENABLED,
       subresource_filter::ActivationScope::ACTIVATION_LIST,
diff --git a/chrome/browser/subresource_filter/subresource_filter_test_harness.h b/chrome/browser/subresource_filter/subresource_filter_test_harness.h
index 61d39b33..c6c8f5c3 100644
--- a/chrome/browser/subresource_filter/subresource_filter_test_harness.h
+++ b/chrome/browser/subresource_filter/subresource_filter_test_harness.h
@@ -66,8 +66,6 @@
  private:
   base::ScopedTempDir ruleset_service_dir_;
   TestingPrefServiceSimple pref_service_;
-  subresource_filter::testing::ScopedSubresourceFilterFeatureToggle
-      scoped_feature_toggle_;
   subresource_filter::testing::ScopedSubresourceFilterConfigurator
       scoped_configuration_;
 
diff --git a/chrome/browser/sync/profile_sync_service_factory_unittest.cc b/chrome/browser/sync/profile_sync_service_factory_unittest.cc
index 8e4772e..633efb1 100644
--- a/chrome/browser/sync/profile_sync_service_factory_unittest.cc
+++ b/chrome/browser/sync/profile_sync_service_factory_unittest.cc
@@ -43,6 +43,10 @@
 
   // Returns the collection of default datatypes.
   std::vector<syncer::ModelType> DefaultDatatypes() {
+    static_assert(41 == syncer::MODEL_TYPE_COUNT,
+                  "When adding a new type, you probably want to add it here as "
+                  "well (assuming it is already enabled).");
+
     std::vector<syncer::ModelType> datatypes;
 
     // Desktop types.
diff --git a/chrome/browser/ui/android/content_settings/ads_blocked_infobar_delegate.cc b/chrome/browser/ui/android/content_settings/ads_blocked_infobar_delegate.cc
index 0a425558..d253026 100644
--- a/chrome/browser/ui/android/content_settings/ads_blocked_infobar_delegate.cc
+++ b/chrome/browser/ui/android/content_settings/ads_blocked_infobar_delegate.cc
@@ -16,7 +16,6 @@
 #include "components/infobars/core/infobar.h"
 #include "components/strings/grit/components_strings.h"
 #include "components/subresource_filter/core/browser/subresource_filter_constants.h"
-#include "components/subresource_filter/core/browser/subresource_filter_features.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -35,13 +34,8 @@
   return l10n_util::GetStringUTF16(IDS_BLOCKED_ADS_PROMPT_EXPLANATION);
 }
 
-// The experimental UI includes the permission and its associated UI. Without it
-// we can't say "Always". Allowing ads will only be scoped to the tab.
 base::string16 AdsBlockedInfobarDelegate::GetToggleText() const {
-  return base::FeatureList::IsEnabled(
-             subresource_filter::kSafeBrowsingSubresourceFilterExperimentalUI)
-             ? l10n_util::GetStringUTF16(IDS_ALWAYS_ALLOW_ADS)
-             : l10n_util::GetStringUTF16(IDS_ALLOW_ADS);
+  return l10n_util::GetStringUTF16(IDS_ALWAYS_ALLOW_ADS);
 }
 
 infobars::InfoBarDelegate::InfoBarIdentifier
diff --git a/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa_browsertest.mm b/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa_browsertest.mm
index 6e142f4..279dabe 100644
--- a/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa_browsertest.mm
+++ b/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa_browsertest.mm
@@ -28,7 +28,6 @@
 #include "chrome/test/base/in_process_browser_test.h"
 #include "components/strings/grit/components_strings.h"
 #include "components/subresource_filter/core/browser/subresource_filter_constants.h"
-#include "components/subresource_filter/core/browser/subresource_filter_features.h"
 #include "content/public/common/media_stream_request.h"
 #include "content/public/test/test_navigation_observer.h"
 #include "testing/gtest_mac.h"
@@ -153,9 +152,6 @@
 
 IN_PROC_BROWSER_TEST_F(ContentSettingBubbleControllerTest,
                        InitSubresourceFilter) {
-  base::test::ScopedFeatureList feature_list;
-  feature_list.InitAndEnableFeature(
-      subresource_filter::kSafeBrowsingSubresourceFilterExperimentalUI);
   ContentSettingBubbleController* controller =
       CreateBubbleController(new ContentSettingSubresourceFilterBubbleModel(
           nullptr, web_contents(), profile()));
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
index c6a5bdc..2abcb4d6 100644
--- a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
+++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
@@ -1431,15 +1431,7 @@
 }
 
 void ContentSettingSubresourceFilterBubbleModel::SetManageText() {
-  // The experimental UI includes the permission UI, which allows us to
-  // guarantee that we will "Always" show ads on the site. For users without the
-  // permission UI, avoid saying "Always" since the user action will be scoped
-  // to the tab only.
-  set_manage_text(l10n_util::GetStringUTF16(
-      base::FeatureList::IsEnabled(
-          subresource_filter::kSafeBrowsingSubresourceFilterExperimentalUI)
-          ? IDS_ALWAYS_ALLOW_ADS
-          : IDS_ALLOW_ADS));
+  set_manage_text(l10n_util::GetStringUTF16(IDS_ALWAYS_ALLOW_ADS));
   set_manage_text_style(ContentSettingBubbleModel::ManageTextStyle::kCheckbox);
 }
 
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_browsertest.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller_browsertest.cc
index 6d5e7cd..1ecac54 100644
--- a/chrome/browser/ui/exclusive_access/fullscreen_controller_browsertest.cc
+++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_browsertest.cc
@@ -47,7 +47,7 @@
 //
 IN_PROC_BROWSER_TEST_F(FullscreenControllerTest, KeyboardLockWithEscLocked) {
   EnterActiveTabFullscreen();
-  RequestKeyboardLock(/*esc_key_locked=*/true);
+  ASSERT_TRUE(RequestKeyboardLock(/*esc_key_locked=*/true));
   ASSERT_TRUE(GetExclusiveAccessManager()
                   ->keyboard_lock_controller()
                   ->IsKeyboardLockActive());
@@ -57,7 +57,7 @@
 
 IN_PROC_BROWSER_TEST_F(FullscreenControllerTest, KeyboardLockWithEscUnlocked) {
   EnterActiveTabFullscreen();
-  RequestKeyboardLock(/*esc_key_locked=*/false);
+  ASSERT_TRUE(RequestKeyboardLock(/*esc_key_locked=*/false));
   ASSERT_TRUE(GetExclusiveAccessManager()
                   ->keyboard_lock_controller()
                   ->IsKeyboardLockActive());
@@ -74,7 +74,7 @@
       base::FilePath(kEmptyFile)));
   AddTabAtIndex(0, file_url, PAGE_TRANSITION_TYPED);
   EnterActiveTabFullscreen();
-  RequestKeyboardLock(/*esc_key_locked=*/true);
+  ASSERT_TRUE(RequestKeyboardLock(/*esc_key_locked=*/true));
   ASSERT_TRUE(GetExclusiveAccessManager()
                   ->keyboard_lock_controller()
                   ->IsKeyboardLockActive());
@@ -91,7 +91,7 @@
       base::FilePath(kEmptyFile)));
   AddTabAtIndex(0, file_url, PAGE_TRANSITION_TYPED);
   EnterActiveTabFullscreen();
-  RequestKeyboardLock(/*esc_key_locked=*/false);
+  ASSERT_TRUE(RequestKeyboardLock(/*esc_key_locked=*/false));
   ASSERT_TRUE(GetExclusiveAccessManager()
                   ->keyboard_lock_controller()
                   ->IsKeyboardLockActive());
@@ -101,7 +101,7 @@
 
 IN_PROC_BROWSER_TEST_F(FullscreenControllerTest,
                        KeyboardLockNotLockedInWindowMode) {
-  RequestKeyboardLock(/*esc_key_locked=*/true);
+  ASSERT_TRUE(RequestKeyboardLock(/*esc_key_locked=*/true));
   ASSERT_FALSE(GetExclusiveAccessManager()
                    ->keyboard_lock_controller()
                    ->IsKeyboardLockActive());
@@ -112,7 +112,7 @@
 IN_PROC_BROWSER_TEST_F(FullscreenControllerTest,
                        KeyboardLockExitsOnEscPressWhenEscNotLocked) {
   EnterActiveTabFullscreen();
-  RequestKeyboardLock(/*esc_key_locked=*/false);
+  ASSERT_TRUE(RequestKeyboardLock(/*esc_key_locked=*/false));
   ASSERT_TRUE(GetExclusiveAccessManager()
                   ->keyboard_lock_controller()
                   ->IsKeyboardLockActive());
@@ -125,7 +125,7 @@
 IN_PROC_BROWSER_TEST_F(FullscreenControllerTest,
                        KeyboardLockDoesNotExitOnEscPressWhenEscIsLocked) {
   EnterActiveTabFullscreen();
-  RequestKeyboardLock(/*esc_key_locked=*/true);
+  ASSERT_TRUE(RequestKeyboardLock(/*esc_key_locked=*/true));
   ASSERT_TRUE(GetExclusiveAccessManager()
                   ->keyboard_lock_controller()
                   ->IsKeyboardLockActive());
@@ -138,7 +138,7 @@
 IN_PROC_BROWSER_TEST_F(FullscreenControllerTest,
                        KeyboardLockNotLockedInExtensionFullscreenMode) {
   EnterExtensionInitiatedFullscreen();
-  RequestKeyboardLock(/*esc_key_locked=*/true);
+  ASSERT_TRUE(RequestKeyboardLock(/*esc_key_locked=*/true));
   ASSERT_FALSE(GetExclusiveAccessManager()
                    ->keyboard_lock_controller()
                    ->IsKeyboardLockActive());
@@ -149,7 +149,7 @@
 
 IN_PROC_BROWSER_TEST_F(FullscreenControllerTest,
                        KeyboardLockNotLockedAfterFullscreenTransition) {
-  RequestKeyboardLock(/*esc_key_locked=*/true);
+  ASSERT_TRUE(RequestKeyboardLock(/*esc_key_locked=*/true));
   EnterActiveTabFullscreen();
   ASSERT_FALSE(GetExclusiveAccessManager()
                    ->keyboard_lock_controller()
@@ -163,7 +163,7 @@
                        KeyboardLockBubbleHideCallbackUnlock) {
   EnterActiveTabFullscreen();
   keyboard_lock_bubble_hide_reason_recorder_.clear();
-  RequestKeyboardLock(/*esc_key_locked=*/true);
+  ASSERT_TRUE(RequestKeyboardLock(/*esc_key_locked=*/true));
   ASSERT_EQ(0ul, keyboard_lock_bubble_hide_reason_recorder_.size());
 
   CancelKeyboardLock();
@@ -178,12 +178,12 @@
   auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
   base::TestMockTimeTaskRunner::ScopedContext scoped_context(task_runner.get());
 
-  RequestKeyboardLock(/*esc_key_locked=*/true);
+  ASSERT_TRUE(RequestKeyboardLock(/*esc_key_locked=*/true));
   // Shorter than |ExclusiveAccessBubble::kInitialDelayMs|.
   task_runner->FastForwardBy(
       base::TimeDelta::FromMilliseconds(InitialBubbleDelayMs() / 2));
   CancelKeyboardLock();
-  RequestKeyboardLock(/*esc_key_locked=*/true);
+  ASSERT_TRUE(RequestKeyboardLock(/*esc_key_locked=*/true));
   ASSERT_TRUE(GetExclusiveAccessManager()
                   ->keyboard_lock_controller()
                   ->IsKeyboardLockActive());
@@ -197,12 +197,12 @@
   auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
   base::TestMockTimeTaskRunner::ScopedContext scoped_context(task_runner.get());
 
-  RequestKeyboardLock(/*esc_key_locked=*/true);
+  ASSERT_TRUE(RequestKeyboardLock(/*esc_key_locked=*/true));
   // Longer than |ExclusiveAccessBubble::kInitialDelayMs|.
   task_runner->FastForwardBy(
       base::TimeDelta::FromMilliseconds(InitialBubbleDelayMs() + 20));
   CancelKeyboardLock();
-  RequestKeyboardLock(/*esc_key_locked=*/true);
+  ASSERT_TRUE(RequestKeyboardLock(/*esc_key_locked=*/true));
   ASSERT_TRUE(GetExclusiveAccessManager()
                   ->keyboard_lock_controller()
                   ->IsKeyboardLockActive());
@@ -224,7 +224,7 @@
   // Set the window to a known value for testing.
   SetEscRepeatWindowLength(base::TimeDelta::FromSeconds(1));
 
-  RequestKeyboardLock(/*esc_key_locked=*/true);
+  ASSERT_TRUE(RequestKeyboardLock(/*esc_key_locked=*/true));
   ASSERT_TRUE(GetExclusiveAccessManager()
                   ->keyboard_lock_controller()
                   ->IsKeyboardLockActive());
@@ -272,7 +272,7 @@
   // Set the window to a known value for testing.
   SetEscRepeatWindowLength(base::TimeDelta::FromSeconds(1));
 
-  RequestKeyboardLock(/*esc_key_locked=*/true);
+  ASSERT_TRUE(RequestKeyboardLock(/*esc_key_locked=*/true));
   ASSERT_TRUE(GetExclusiveAccessManager()
                   ->keyboard_lock_controller()
                   ->IsKeyboardLockActive());
@@ -313,7 +313,7 @@
   ASSERT_TRUE(
       GetExclusiveAccessManager()->mouse_lock_controller()->IsMouseLocked());
 
-  RequestKeyboardLock(/*esc_key_locked=*/false);
+  ASSERT_TRUE(RequestKeyboardLock(/*esc_key_locked=*/false));
   ASSERT_TRUE(GetExclusiveAccessManager()
                   ->keyboard_lock_controller()
                   ->IsKeyboardLockActive());
@@ -331,7 +331,7 @@
   ASSERT_TRUE(IsFullscreenBubbleDisplayed());
   ASSERT_TRUE(
       GetExclusiveAccessManager()->mouse_lock_controller()->IsMouseLocked());
-  RequestKeyboardLock(/*esc_key_locked=*/true);
+  ASSERT_TRUE(RequestKeyboardLock(/*esc_key_locked=*/true));
   ASSERT_TRUE(GetExclusiveAccessManager()
                   ->keyboard_lock_controller()
                   ->IsKeyboardLockActive());
@@ -344,7 +344,7 @@
   EnterActiveTabFullscreen();
   keyboard_lock_bubble_hide_reason_recorder_.clear();
 
-  RequestKeyboardLock(/*esc_key_locked=*/true);
+  ASSERT_TRUE(RequestKeyboardLock(/*esc_key_locked=*/true));
   ASSERT_TRUE(GetExclusiveAccessManager()
                   ->keyboard_lock_controller()
                   ->IsKeyboardLockActive());
@@ -352,7 +352,7 @@
             GetExclusiveAccessBubbleType());
   ASSERT_EQ(0ul, keyboard_lock_bubble_hide_reason_recorder_.size());
 
-  RequestKeyboardLock(/*esc_key_locked=*/false);
+  ASSERT_TRUE(RequestKeyboardLock(/*esc_key_locked=*/false));
   ASSERT_TRUE(GetExclusiveAccessManager()
                   ->keyboard_lock_controller()
                   ->IsKeyboardLockActive());
@@ -363,7 +363,7 @@
             keyboard_lock_bubble_hide_reason_recorder_[0]);
   keyboard_lock_bubble_hide_reason_recorder_.clear();
 
-  RequestKeyboardLock(/*esc_key_locked=*/false);
+  ASSERT_TRUE(RequestKeyboardLock(/*esc_key_locked=*/false));
   ASSERT_TRUE(GetExclusiveAccessManager()
                   ->keyboard_lock_controller()
                   ->IsKeyboardLockActive());
@@ -371,7 +371,7 @@
             GetExclusiveAccessBubbleType());
   ASSERT_EQ(0ul, keyboard_lock_bubble_hide_reason_recorder_.size());
 
-  RequestKeyboardLock(/*esc_key_locked=*/true);
+  ASSERT_TRUE(RequestKeyboardLock(/*esc_key_locked=*/true));
   ASSERT_TRUE(GetExclusiveAccessManager()
                   ->keyboard_lock_controller()
                   ->IsKeyboardLockActive());
@@ -382,7 +382,7 @@
             keyboard_lock_bubble_hide_reason_recorder_[0]);
   keyboard_lock_bubble_hide_reason_recorder_.clear();
 
-  RequestKeyboardLock(/*esc_key_locked=*/true);
+  ASSERT_TRUE(RequestKeyboardLock(/*esc_key_locked=*/true));
   ASSERT_TRUE(GetExclusiveAccessManager()
                   ->keyboard_lock_controller()
                   ->IsKeyboardLockActive());
@@ -511,7 +511,7 @@
 
 IN_PROC_BROWSER_TEST_F(FullscreenControllerTest, MouseLockAfterKeyboardLock) {
   EnterActiveTabFullscreen();
-  RequestKeyboardLock(/*esc_key_locked=*/false);
+  ASSERT_TRUE(RequestKeyboardLock(/*esc_key_locked=*/false));
   ASSERT_TRUE(GetExclusiveAccessManager()
                   ->keyboard_lock_controller()
                   ->IsKeyboardLockActive());
@@ -529,7 +529,7 @@
 IN_PROC_BROWSER_TEST_F(FullscreenControllerTest,
                        MouseLockAfterKeyboardLockWithEscLocked) {
   EnterActiveTabFullscreen();
-  RequestKeyboardLock(/*esc_key_locked=*/true);
+  ASSERT_TRUE(RequestKeyboardLock(/*esc_key_locked=*/true));
   ASSERT_TRUE(GetExclusiveAccessManager()
                   ->keyboard_lock_controller()
                   ->IsKeyboardLockActive());
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_test.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller_test.cc
index fe96743..5fc16db 100644
--- a/chrome/browser/ui/exclusive_access/fullscreen_controller_test.cc
+++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_test.cc
@@ -9,6 +9,8 @@
 
 #include "base/callback.h"
 #include "base/command_line.h"
+#include "base/containers/flat_set.h"
+#include "base/optional.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_window.h"
@@ -21,8 +23,11 @@
 #include "content/public/browser/native_web_keyboard_event.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/content_features.h"
+#include "content/public/test/browser_test_utils.h"
 #include "content/public/test/test_navigation_observer.h"
+#include "ui/base/ui_base_features.h"
 #include "ui/events/base_event_utils.h"
+#include "ui/events/keycodes/dom/dom_code.h"
 #include "ui/events/keycodes/keyboard_codes.h"
 
 using content::WebContents;
@@ -34,7 +39,12 @@
     "/fullscreen_mouselock/fullscreen_mouselock.html";
 
 FullscreenControllerTest::FullscreenControllerTest() : weak_ptr_factory_(this) {
-  scoped_feature_list_.InitAndEnableFeature(features::kKeyboardLockAPI);
+  // Ensure the KeyboardLockAPI is enabled and system keyboard lock is disabled.
+  // It is important to disable system keyboard lock as low-level test utilities
+  // may install a keyboard hook to listen for keyboard events and having an
+  // active system hook may cause issues with that mechanism.
+  scoped_feature_list_.InitWithFeatures({features::kKeyboardLockAPI},
+                                        {features::kSystemKeyboardLock});
 }
 
 FullscreenControllerTest::~FullscreenControllerTest() = default;
@@ -64,13 +74,22 @@
       base::RepeatingCallback<void(ExclusiveAccessBubbleHideReason)>();
 }
 
-void FullscreenControllerTest::RequestKeyboardLock(bool esc_key_locked) {
+bool FullscreenControllerTest::RequestKeyboardLock(bool esc_key_locked) {
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
-  KeyboardLockController* keyboard_lock_controller =
-      GetExclusiveAccessManager()->keyboard_lock_controller();
-  keyboard_lock_controller->fake_keyboard_lock_for_test_ = true;
-  browser()->RequestKeyboardLock(tab, esc_key_locked);
-  keyboard_lock_controller->fake_keyboard_lock_for_test_ = false;
+
+  // If the caller defines |esc_key_locked| as true then we create a set of
+  // locked keys which includes the escape key, this will require the user/test
+  // to press and hold escape to exit fullscreen.  If |esc_key_locked| is false,
+  // then we create a set of keys that does not include escape (we arbitrarily
+  // chose the 'a' key) which means the user/test can just press escape to exit
+  // fullscreen.
+  base::Optional<base::flat_set<ui::DomCode>> codes;
+  if (esc_key_locked)
+    codes = base::flat_set<ui::DomCode>({ui::DomCode::ESCAPE});
+  else
+    codes = base::flat_set<ui::DomCode>({ui::DomCode::US_A});
+
+  return content::RequestKeyboardLock(tab, std::move(codes));
 }
 
 void FullscreenControllerTest::RequestToLockMouse(
@@ -103,7 +122,7 @@
 
 void FullscreenControllerTest::CancelKeyboardLock() {
   WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
-  browser()->CancelKeyboardLockRequest(tab);
+  content::CancelKeyboardLock(tab);
 }
 
 void FullscreenControllerTest::LostMouseLock() {
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_test.h b/chrome/browser/ui/exclusive_access/fullscreen_controller_test.h
index b6b48c0..70f0ed4 100644
--- a/chrome/browser/ui/exclusive_access/fullscreen_controller_test.h
+++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_test.h
@@ -60,7 +60,7 @@
   void SetUpOnMainThread() override;
   void TearDownOnMainThread() override;
 
-  void RequestKeyboardLock(bool esc_key_locked);
+  bool RequestKeyboardLock(bool esc_key_locked);
   void RequestToLockMouse(bool user_gesture,
                           bool last_unlocked_by_target);
   void SetWebContentsGrantedSilentMouseLockPermission();
diff --git a/chrome/browser/ui/exclusive_access/keyboard_lock_controller.cc b/chrome/browser/ui/exclusive_access/keyboard_lock_controller.cc
index 1a26894..13a13fc 100644
--- a/chrome/browser/ui/exclusive_access/keyboard_lock_controller.cc
+++ b/chrome/browser/ui/exclusive_access/keyboard_lock_controller.cc
@@ -155,8 +155,7 @@
 
 void KeyboardLockController::LockKeyboard(content::WebContents* web_contents,
                                           bool esc_key_locked) {
-  if (fake_keyboard_lock_for_test_ ||
-      web_contents->GotResponseToKeyboardLockRequest(true)) {
+  if (web_contents->GotResponseToKeyboardLockRequest(true)) {
     KeyboardLockState new_lock_state =
         esc_key_locked ? KeyboardLockState::kLockedWithEsc
                        : KeyboardLockState::kLockedWithoutEsc;
@@ -185,10 +184,7 @@
   RecordForcedBubbleReshowsHistogram();
   keyboard_lock_state_ = KeyboardLockState::kUnlocked;
 
-  if (!fake_keyboard_lock_for_test_) {
-    exclusive_access_tab()->GotResponseToKeyboardLockRequest(false);
-  }
-
+  exclusive_access_tab()->GotResponseToKeyboardLockRequest(false);
   SetTabWithExclusiveAccess(nullptr);
   exclusive_access_manager()->UpdateExclusiveAccessExitBubbleContent(
       ExclusiveAccessBubbleHideCallback());
diff --git a/chrome/browser/ui/exclusive_access/keyboard_lock_controller.h b/chrome/browser/ui/exclusive_access/keyboard_lock_controller.h
index 58cc540..0e8cd8b 100644
--- a/chrome/browser/ui/exclusive_access/keyboard_lock_controller.h
+++ b/chrome/browser/ui/exclusive_access/keyboard_lock_controller.h
@@ -85,12 +85,6 @@
   // repeated ESC keypresses.
   void RecordForcedBubbleReshowsHistogram();
 
-  // TODO(joedow): Remove this bool and initiate keyboard lock from javascript
-  // once all platforms have been implemented.
-  // If true, does not call into the WebContents to lock the keyboard.
-  // Used for testing to abstract away platform differences for keyboard lock.
-  bool fake_keyboard_lock_for_test_ = false;
-
   // Called after the bubble is hidden in tests, if set.
   ExclusiveAccessBubbleHideCallbackForTest bubble_hide_callback_for_test_;
 
diff --git a/chrome/browser/ui/extensions/blocked_action_bubble_browsertest.cc b/chrome/browser/ui/extensions/blocked_action_bubble_browsertest.cc
index cc823a0..ec6ac58 100644
--- a/chrome/browser/ui/extensions/blocked_action_bubble_browsertest.cc
+++ b/chrome/browser/ui/extensions/blocked_action_bubble_browsertest.cc
@@ -80,7 +80,7 @@
   ASSERT_TRUE(extension);
   extensions::ScriptingPermissionsModifier(profile(),
                                            base::WrapRefCounted(extension))
-      .SetAllowedOnAllUrls(false);
+      .SetWithholdAllUrls(true);
 
   content::WebContents* tab =
       browser()->tab_strip_model()->GetActiveWebContents();
diff --git a/chrome/browser/ui/keyboard_lock_interactive_browsertest.cc b/chrome/browser/ui/keyboard_lock_interactive_browsertest.cc
index 333f790..e114037 100644
--- a/chrome/browser/ui/keyboard_lock_interactive_browsertest.cc
+++ b/chrome/browser/ui/keyboard_lock_interactive_browsertest.cc
@@ -322,8 +322,16 @@
   ASSERT_FALSE(IsKeyboardLockActive());
 }
 
+#if defined(OS_MACOSX)
+// TODO(crbug.com/837438): Enable once browser fullscreen is reliable in tests.
+#define MAYBE_RequestedButNotActiveInBrowserFullscreen \
+  DISABLED_RequestedButNotActiveInBrowserFullscreen
+#else
+#define MAYBE_RequestedButNotActiveInBrowserFullscreen \
+  RequestedButNotActiveInBrowserFullscreen
+#endif
 IN_PROC_BROWSER_TEST_F(KeyboardLockInteractiveBrowserTest,
-                       RequestedButNotActiveInBrowserFullscreen) {
+                       MAYBE_RequestedButNotActiveInBrowserFullscreen) {
   ASSERT_NO_FATAL_FAILURE(StartFullscreenLockPage());
   ASSERT_TRUE(DisablePreventDefaultOnTestPage());
   ASSERT_TRUE(KeyboardLockApiExists());
diff --git a/chrome/browser/ui/page_info/page_info.cc b/chrome/browser/ui/page_info/page_info.cc
index f1f7210..cfec84c3 100644
--- a/chrome/browser/ui/page_info/page_info.cc
+++ b/chrome/browser/ui/page_info/page_info.cc
@@ -151,7 +151,7 @@
   // value when it has been activated on the current origin.
   if (info.type == CONTENT_SETTINGS_TYPE_ADS) {
     if (!base::FeatureList::IsEnabled(
-            subresource_filter::kSafeBrowsingSubresourceFilterExperimentalUI)) {
+            subresource_filter::kSafeBrowsingSubresourceFilter)) {
       return false;
     }
 
diff --git a/chrome/browser/ui/page_info/page_info_unittest.cc b/chrome/browser/ui/page_info/page_info_unittest.cc
index 7c0743b..0784718 100644
--- a/chrome/browser/ui/page_info/page_info_unittest.cc
+++ b/chrome/browser/ui/page_info/page_info_unittest.cc
@@ -14,7 +14,6 @@
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/metrics/histogram_tester.h"
-#include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
 #include "chrome/browser/infobars/mock_infobar_service.h"
@@ -29,7 +28,6 @@
 #include "components/content_settings/core/common/content_settings_types.h"
 #include "components/infobars/core/infobar.h"
 #include "components/strings/grit/components_strings.h"
-#include "components/subresource_filter/core/browser/subresource_filter_features.h"
 #include "content/public/browser/ssl_host_state_delegate.h"
 #include "content/public/browser/ssl_status.h"
 #include "content/public/common/content_switches.h"
@@ -974,9 +972,6 @@
 
 // Tests that the SubresourceFilter setting is omitted correctly.
 TEST_F(PageInfoTest, SubresourceFilterSetting_MatchesActivation) {
-  base::test::ScopedFeatureList feature_list;
-  feature_list.InitAndEnableFeature(
-      subresource_filter::kSafeBrowsingSubresourceFilterExperimentalUI);
   auto showing_setting = [](const PermissionInfoList& permissions) {
     return PermissionInfoListContainsPermission(permissions,
                                                 CONTENT_SETTINGS_TYPE_ADS);
diff --git a/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc b/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc
index c7e6f22..f08262b 100644
--- a/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc
+++ b/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc
@@ -746,7 +746,7 @@
     extension_ = LoadExtension(extension_dir_.UnpackedPath());
     ASSERT_TRUE(extension_);
     extensions::ScriptingPermissionsModifier(profile(), extension_)
-        .SetAllowedOnAllUrls(false);
+        .SetWithholdAllUrls(true);
   }
 
   base::test::ScopedFeatureList scoped_feature_list_;
diff --git a/chrome/browser/ui/toolbar/toolbar_actions_bar_unittest.cc b/chrome/browser/ui/toolbar/toolbar_actions_bar_unittest.cc
index 9d9f412..e08d2f99 100644
--- a/chrome/browser/ui/toolbar/toolbar_actions_bar_unittest.cc
+++ b/chrome/browser/ui/toolbar/toolbar_actions_bar_unittest.cc
@@ -494,6 +494,8 @@
 
 TEST_P(ToolbarActionsBarUnitTest, TestStartAndEndIndexes) {
   const int icon_width = toolbar_actions_bar()->GetViewSize().width();
+  const int resize_handle_size =
+      toolbar_actions_bar()->platform_settings().item_spacing;
 
   for (int i = 0; i < 3; ++i) {
     CreateAndAddExtension(base::StringPrintf("extension %d", i),
@@ -509,7 +511,7 @@
   EXPECT_FALSE(toolbar_actions_bar()->NeedsOverflow());
 
   // Shrink the width of the view to be a little over enough for one icon.
-  browser_action_test_util()->SetWidth(icon_width + 2);
+  browser_action_test_util()->SetWidth(icon_width + 2 + resize_handle_size);
   // Tricky: GetIconCount() is what we use to determine our preferred size,
   // stored pref size, etc, and should not be affected by a minimum size that is
   // too small to show everything. It should remain constant.
@@ -532,9 +534,12 @@
   EXPECT_EQ(3u, overflow_bar()->GetEndIndexInBounds());
   EXPECT_TRUE(toolbar_actions_bar()->NeedsOverflow());
 
-  // Set the width back to the preferred width. All should be back to normal.
+  // Set the width back to the preferred width (with resize handle). All should
+  // be back to normal.
+  // TODO(pbos): Set the full width in a less contrived way when
+  // ToolbarActionsBar and BrowserActionsContainer merge.
   browser_action_test_util()->SetWidth(
-      toolbar_actions_bar()->GetFullSize().width());
+      toolbar_actions_bar()->GetFullSize().width() + resize_handle_size);
   EXPECT_EQ(3u, toolbar_actions_bar()->GetIconCount());
   EXPECT_EQ(0u, toolbar_actions_bar()->GetStartIndexInBounds());
   EXPECT_EQ(3u, toolbar_actions_bar()->GetEndIndexInBounds());
diff --git a/chrome/browser/ui/views/fullscreen_control/fullscreen_control_view_interactive_uitest.cc b/chrome/browser/ui/views/fullscreen_control/fullscreen_control_view_interactive_uitest.cc
index 4ed0858..d0c965f 100644
--- a/chrome/browser/ui/views/fullscreen_control/fullscreen_control_view_interactive_uitest.cc
+++ b/chrome/browser/ui/views/fullscreen_control/fullscreen_control_view_interactive_uitest.cc
@@ -2,8 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <memory>
+#include <utility>
+
 #include "base/callback.h"
+#include "base/containers/flat_set.h"
 #include "base/macros.h"
+#include "base/optional.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
@@ -20,11 +25,13 @@
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/content_features.h"
+#include "content/public/test/browser_test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/web/web_fullscreen_options.h"
 #include "ui/base/ui_base_features.h"
 #include "ui/events/base_event_utils.h"
 #include "ui/events/event.h"
+#include "ui/events/keycodes/dom/dom_code.h"
 #include "ui/views/controls/button/button.h"
 #include "ui/views/view.h"
 #include "url/gurl.h"
@@ -58,8 +65,13 @@
   FullscreenControlViewTest() = default;
 
   void SetUp() override {
+    // Ensure the KeyboardLockAPI is enabled and system keyboard lock is
+    // disabled. It is important to disable system keyboard lock as low-level
+    // test utilities may install a keyboard hook to listen for keyboard events
+    // and having an active system hook may cause issues with that mechanism.
     scoped_feature_list_.InitWithFeatures(
-        {features::kFullscreenExitUI, features::kKeyboardLockAPI}, {});
+        {features::kFullscreenExitUI, features::kKeyboardLockAPI},
+        {features::kSystemKeyboardLock});
     InProcessBrowserTest::SetUp();
   }
 
@@ -122,12 +134,10 @@
     ASSERT_TRUE(delegate->IsFullscreenForTabOrPending(GetActiveWebContents()));
   }
 
-  void EnableKeyboardLock() {
-    KeyboardLockController* controller = GetKeyboardLockController();
-    controller->fake_keyboard_lock_for_test_ = true;
-    controller->RequestKeyboardLock(GetActiveWebContents(),
-                                    /*require_esc_to_exit=*/true);
-    controller->fake_keyboard_lock_for_test_ = false;
+  bool EnableKeyboardLock() {
+    base::Optional<base::flat_set<ui::DomCode>> codes({ui::DomCode::ESCAPE});
+    return content::RequestKeyboardLock(GetActiveWebContents(),
+                                        std::move(codes));
   }
 
   void SetPopupVisibilityChangedCallback(base::OnceClosure callback) {
@@ -450,7 +460,7 @@
   ASSERT_FALSE(host->IsVisible());
 
   // Lock the keyboard and ensure it is active.
-  EnableKeyboardLock();
+  ASSERT_TRUE(EnableKeyboardLock());
   ASSERT_TRUE(GetKeyboardLockController()->IsKeyboardLockActive());
 
   // Verify a bubble message is now displayed, then dismiss it.
diff --git a/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc b/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc
index f22d517..8110aebf 100644
--- a/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc
+++ b/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc
@@ -12,7 +12,9 @@
 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/profiles/profiles_state.h"
+#include "chrome/browser/signin/account_consistency_mode_manager.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/browser/sync/sync_ui_util.h"
 #include "chrome/browser/themes/theme_properties.h"
 #include "chrome/browser/ui/layout_constants.h"
 #include "chrome/browser/ui/view_ids.h"
@@ -22,6 +24,7 @@
 #include "ui/base/material_design/material_design_controller.h"
 #include "ui/base/models/menu_model.h"
 #include "ui/base/theme_provider.h"
+#include "ui/gfx/color_palette.h"
 #include "ui/gfx/image/image.h"
 #include "ui/gfx/paint_vector_icon.h"
 #include "ui/views/controls/button/label_button_border.h"
@@ -120,7 +123,7 @@
          !SigninManagerFactory::GetForProfile(profile_)->IsAuthenticated();
 }
 
-gfx::ImageSkia AvatarToolbarButton::GetAvatarIcon() const {
+gfx::ImageSkia AvatarToolbarButton::GetAvatarIcon() {
   const int icon_size =
       ui::MaterialDesignController::IsTouchOptimizedUiEnabled() ? 24 : 20;
 
@@ -134,8 +137,20 @@
     return gfx::CreateVectorIcon(kUserMenuGuestIcon, icon_size, icon_color);
 
   gfx::Image avatar_icon;
-  if (!ShouldShowGenericIcon())
-    avatar_icon = GetIconImageFromProfile();
+  if (!ShouldShowGenericIcon()) {
+    switch (GetSyncState()) {
+      case SyncState::kNormal:
+        avatar_icon = GetIconImageFromProfile();
+        break;
+      case SyncState::kPaused:
+        return gfx::CreateVectorIcon(kSyncPausedIcon, icon_size,
+                                     gfx::kGoogleBlue500);
+      case SyncState::kError:
+        return gfx::CreateVectorIcon(kSyncProblemIcon, icon_size,
+                                     gfx::kGoogleRed700);
+    }
+  }
+
   if (!avatar_icon.IsEmpty()) {
     return profiles::GetSizedAvatarIcon(avatar_icon, true, icon_size, icon_size,
                                         profiles::SHAPE_CIRCLE)
@@ -169,3 +184,18 @@
 
   return entry->GetAvatarIcon();
 }
+
+AvatarToolbarButton::SyncState AvatarToolbarButton::GetSyncState() {
+  if (profile_->IsSyncAllowed() && error_controller_.HasAvatarError()) {
+    // When DICE is enabled and the error is an auth error, the sync-paused
+    // icon is shown.
+    int unused;
+    const bool should_show_sync_paused_ui =
+        AccountConsistencyModeManager::IsDiceEnabledForProfile(profile_) &&
+        sync_ui_util::GetMessagesForAvatarSyncError(
+            profile_, *SigninManagerFactory::GetForProfile(profile_), &unused,
+            &unused) == sync_ui_util::AUTH_ERROR;
+    return should_show_sync_paused_ui ? SyncState::kPaused : SyncState::kError;
+  }
+  return SyncState::kNormal;
+}
diff --git a/chrome/browser/ui/views/profiles/avatar_toolbar_button.h b/chrome/browser/ui/views/profiles/avatar_toolbar_button.h
index 3a6e4bf..4692f03 100644
--- a/chrome/browser/ui/views/profiles/avatar_toolbar_button.h
+++ b/chrome/browser/ui/views/profiles/avatar_toolbar_button.h
@@ -23,6 +23,8 @@
   void UpdateTooltipText();
 
  private:
+  enum class SyncState { kNormal, kPaused, kError };
+
   // AvatarButtonErrorControllerDelegate:
   void OnAvatarErrorChanged() override;
 
@@ -38,8 +40,9 @@
 
   bool IsIncognito() const;
   bool ShouldShowGenericIcon() const;
-  gfx::ImageSkia GetAvatarIcon() const;
+  gfx::ImageSkia GetAvatarIcon();
   gfx::Image GetIconImageFromProfile() const;
+  SyncState GetSyncState();
 
   Profile* const profile_;
 
diff --git a/chrome/browser/ui/views/toolbar/browser_actions_container.cc b/chrome/browser/ui/views/toolbar/browser_actions_container.cc
index 4117747..d0e2c36 100644
--- a/chrome/browser/ui/views/toolbar/browser_actions_container.cc
+++ b/chrome/browser/ui/views/toolbar/browser_actions_container.cc
@@ -223,6 +223,7 @@
   // GetWidthForIconCount.
   if (toolbar_actions_bar_->WidthToIconCount(target_width) > 0)
     target_width += GetSeparatorAreaWidth();
+  target_width += GetResizeAreaWidth();
 
   if (resize_animation_ && !toolbar_actions_bar_->suppress_animation()) {
     if (!ShownInsideMenu()) {
@@ -253,14 +254,14 @@
       get_width_time == GET_WIDTH_AFTER_ANIMATION && animating()
           ? animation_target_size_
           : width();
-  const int width_without_separator = target_width - GetSeparatorAreaWidth();
+  const int icon_area_width =
+      target_width - GetSeparatorAreaWidth() - GetResizeAreaWidth();
   // This needs to be clamped to non-zero as ToolbarActionsBar::ResizeDelegate
   // uses this value to distinguish between an empty bar without items and a bar
   // that is showing no items.
   // TODO(pbos): This is landed to fix to https://crbug.com/836182. Remove the
   // need for this when ToolbarActionsBar and BrowserActionsContainer merges.
-  return std::max(toolbar_actions_bar_->GetMinimumWidth(),
-                  width_without_separator);
+  return std::max(toolbar_actions_bar_->GetMinimumWidth(), icon_area_width);
 }
 
 bool BrowserActionsContainer::IsAnimating() const {
@@ -347,7 +348,8 @@
     preferred_width = *resize_starting_width_ - resize_amount_;
   } else {
     // Otherwise, use the normal preferred width.
-    preferred_width = toolbar_actions_bar_->GetFullSize().width();
+    preferred_width =
+        GetResizeAreaWidth() + toolbar_actions_bar_->GetFullSize().width();
     if (toolbar_actions_bar_->GetIconCount() > 0)
       preferred_width += GetSeparatorAreaWidth();
   }
@@ -384,7 +386,7 @@
 
   SetVisible(true);
   if (resize_area_)
-    resize_area_->SetBounds(0, 0, platform_settings().item_spacing, height());
+    resize_area_->SetBounds(0, 0, GetResizeAreaWidth(), height());
 
   // The range of visible icons, from start_index (inclusive) to end_index
   // (exclusive).
@@ -399,7 +401,13 @@
     if (i < start_index || i >= end_index) {
       view->SetVisible(false);
     } else {
-      view->SetBoundsRect(toolbar_actions_bar()->GetFrameForIndex(i));
+      gfx::Rect bounds = toolbar_actions_bar()->GetFrameForIndex(i);
+      // Offset all icons by GetResizeAreaWidth() so that they start on the
+      // resize area's right edge. ToolbarActionsBar is not aware of the
+      // separate resize area.
+      // TODO(pbos): Remove this workaround when the files merge.
+      bounds.set_x(bounds.x() + GetResizeAreaWidth());
+      view->SetBoundsRect(bounds);
       view->SetVisible(true);
       if (!ShownInsideMenu()) {
         view->AnimateInkDrop(toolbar_actions_bar()->is_highlighting()
@@ -604,13 +612,14 @@
   // Up until now we've only been modifying the resize_amount, but now it is
   // time to set the container size to the size we have resized to, and then
   // animate to the nearest icon count size if necessary (which may be 0).
-  int width_without_separator =
-      std::max(GetResizeAreaWidth(),
-               CalculatePreferredSize().width() - GetSeparatorAreaWidth());
+  int icon_area_width =
+      std::max(toolbar_actions_bar_->GetMinimumWidth(),
+               CalculatePreferredSize().width() - GetSeparatorAreaWidth() -
+                   GetResizeAreaWidth());
   // As we're done resizing, reset the starting width to reflect this after
   // calculating the final size based on it.
   resize_starting_width_.reset();
-  toolbar_actions_bar_->OnResizeComplete(width_without_separator);
+  toolbar_actions_bar_->OnResizeComplete(icon_area_width);
 }
 
 void BrowserActionsContainer::AnimationProgressed(
@@ -719,7 +728,7 @@
 int BrowserActionsContainer::GetWidthForIconCount(size_t num_icons) const {
   if (num_icons == 0)
     return 0;
-  return GetSeparatorAreaWidth() +
+  return GetResizeAreaWidth() + GetSeparatorAreaWidth() +
          num_icons * toolbar_actions_bar_->GetViewSize().width();
 }
 
@@ -731,7 +740,7 @@
 int BrowserActionsContainer::GetResizeAreaWidth() const {
   if (!resize_area_)
     return 0;
-  return resize_area_->width();
+  return platform_settings().item_spacing;
 }
 
 int BrowserActionsContainer::GetSeparatorAreaWidth() const {
diff --git a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc
index 442b4f9..d165fdc 100644
--- a/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/enrollment_screen_handler.cc
@@ -272,9 +272,6 @@
     case authpolicy::ERROR_OU_DOES_NOT_EXIST:
       ShowError(IDS_AD_OU_DOES_NOT_EXIST, true);
       return;
-    case authpolicy::ERROR_INVALID_OU:
-      ShowError(IDS_AD_OU_INVALID, true);
-      return;
     case authpolicy::ERROR_OU_ACCESS_DENIED:
       ShowError(IDS_AD_OU_ACCESS_DENIED, true);
       return;
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
index 68573f9..6eee230 100644
--- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -2349,7 +2349,7 @@
   html_source->AddBoolean(
       "enableSafeBrowsingSubresourceFilter",
       base::FeatureList::IsEnabled(
-          subresource_filter::kSafeBrowsingSubresourceFilterExperimentalUI));
+          subresource_filter::kSafeBrowsingSubresourceFilter));
 
   html_source->AddBoolean(
       "enableSoundContentSetting",
diff --git a/chrome/browser/ui/webui/site_settings_helper.cc b/chrome/browser/ui/webui/site_settings_helper.cc
index de6fa11..f7cfefa 100644
--- a/chrome/browser/ui/webui/site_settings_helper.cc
+++ b/chrome/browser/ui/webui/site_settings_helper.cc
@@ -161,7 +161,7 @@
 
   if (content_type == CONTENT_SETTINGS_TYPE_ADS &&
       base::FeatureList::IsEnabled(
-          subresource_filter::kSafeBrowsingSubresourceFilterExperimentalUI)) {
+          subresource_filter::kSafeBrowsingSubresourceFilter)) {
     HostContentSettingsMap* map =
         HostContentSettingsMapFactory::GetForProfile(profile);
     if (map->GetWebsiteSetting(origin, GURL(), CONTENT_SETTINGS_TYPE_ADS_DATA,
diff --git a/chrome/common/extensions/api/OWNERS b/chrome/common/extensions/api/OWNERS
index 503d523e..57235704 100644
--- a/chrome/common/extensions/api/OWNERS
+++ b/chrome/common/extensions/api/OWNERS
@@ -14,7 +14,6 @@
 per-file automation*.idl=dmazzoni@chromium.org
 per-file automation*.idl=dtseng@chromium.org
 per-file automation*.idl=nektar@chromium.org
-per-file file_manager_private*.idl=fukino@chromium.org
-per-file file_manager_private*.idl=yamaguchi@chromium.org
+per-file file_manager_private*.idl=file://ui/file_manager/OWNERS
 
 # COMPONENT: Platform>Extensions>API
diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json
index 1c97ddd..dc15489 100644
--- a/chrome/common/extensions/api/_permission_features.json
+++ b/chrome/common/extensions/api/_permission_features.json
@@ -688,11 +688,12 @@
       "312745D9BF916161191143F6490085EEA0434997"   // Google Talk debug
     ]
   },
-  "safeBrowingPrivate": {
-    "channel": "dev",
+  "safeBrowsingPrivate": {
+    "channel": "stable",
     "extension_types": ["extension"],
     "whitelist": [
-      "FD15C63ABA854733FDCBC1D4D34A71E963A12ABD"  // Chrome Reporting Extension
+      "FD15C63ABA854733FDCBC1D4D34A71E963A12ABD",  // Chrome Reporting Extension
+      "08455FA7CB8734168378F731B00B354CEEE0088F"   // Chrome Reporting Ext. Beta
     ]
   },
   "screenlockPrivate": {
diff --git a/chrome/common/extensions/permissions/chrome_api_permissions.cc b/chrome/common/extensions/permissions/chrome_api_permissions.cc
index b91c9ad..bd278e9 100644
--- a/chrome/common/extensions/permissions/chrome_api_permissions.cc
+++ b/chrome/common/extensions/permissions/chrome_api_permissions.cc
@@ -187,6 +187,7 @@
        APIPermissionInfo::kFlagCannotBeOptional},
       {APIPermission::kResourcesPrivate, "resourcesPrivate",
        APIPermissionInfo::kFlagCannotBeOptional},
+      {APIPermission::kSafeBrowsingPrivate, "safeBrowsingPrivate"},
 
       // Full url access permissions.
       {APIPermission::kDebugger, "debugger",
diff --git a/chrome/common/extensions/permissions/permission_set_unittest.cc b/chrome/common/extensions/permissions/permission_set_unittest.cc
index f6fd473..d8bd516 100644
--- a/chrome/common/extensions/permissions/permission_set_unittest.cc
+++ b/chrome/common/extensions/permissions/permission_set_unittest.cc
@@ -854,6 +854,7 @@
   skip.insert(APIPermission::kImageWriterPrivate);
   skip.insert(APIPermission::kResourcesPrivate);
   skip.insert(APIPermission::kRtcPrivate);
+  skip.insert(APIPermission::kSafeBrowsingPrivate);
   skip.insert(APIPermission::kStreamsPrivate);
   skip.insert(APIPermission::kSystemPrivate);
   skip.insert(APIPermission::kTabCaptureForTab);
diff --git a/chrome/test/data/webui/cr_elements/cr_input_test.js b/chrome/test/data/webui/cr_elements/cr_input_test.js
index c0634e3b..7cce810 100644
--- a/chrome/test/data/webui/cr_elements/cr_input_test.js
+++ b/chrome/test/data/webui/cr_elements/cr_input_test.js
@@ -15,31 +15,24 @@
   });
 
   test('AttributesCorrectlySupported', function() {
-    assertFalse(input.autofocus);
-    crInput.setAttribute('autofocus', 'autofocus');
-    assertTrue(input.autofocus);
-
-    assertFalse(input.disabled);
-    crInput.setAttribute('disabled', 'disabled');
-    assertTrue(input.disabled);
-
+    assertFalse(input.hasAttribute('autofocus'));
+    assertFalse(input.hasAttribute('disabled'));
     assertFalse(input.hasAttribute('tabindex'));
+
+    crInput.setAttribute('autofocus', 'autofocus');
+    assertTrue(input.hasAttribute('autofocus'));
+
+    crInput.setAttribute('disabled', 'disabled');
+    assertTrue(input.hasAttribute('disabled'));
+
     crInput.tabIndex = '-1';
-    assertEquals(-1, input.tabIndex);
+    assertEquals('-1', input.getAttribute('tabindex'));
     crInput.tabIndex = '0';
-    assertEquals(0, input.tabIndex);
+    assertEquals('0', input.getAttribute('tabindex'));
 
     assertEquals('none', getComputedStyle(crInput.$.label).display);
     crInput.label = 'label';
     assertEquals('block', getComputedStyle(crInput.$.label).display);
-
-    assertFalse(input.readOnly);
-    crInput.setAttribute('readonly', 'readonly');
-    assertTrue(input.readOnly);
-
-    assertEquals('text', input.type);
-    crInput.setAttribute('type', 'password');
-    assertEquals('password', input.type);
   });
 
   test('placeholderCorrectlyBound', function() {
diff --git a/chrome/test/data/webui/settings/people_page_sync_page_interactive_test.js b/chrome/test/data/webui/settings/people_page_sync_page_interactive_test.js
index 5e4205a..7f7c4f5 100644
--- a/chrome/test/data/webui/settings/people_page_sync_page_interactive_test.js
+++ b/chrome/test/data/webui/settings/people_page_sync_page_interactive_test.js
@@ -16,11 +16,16 @@
     cr.webUIListenerCallback('sync-prefs-changed', {passphraseRequired: true});
     Polymer.dom.flush();
 
+    const input = testElement.$$('#existingPassphraseInput');
+
+    let focused = false;
+    input.addEventListener('focus', function() {
+      focused = true;
+    });
+
     // Simulate event normally fired by main_page_behavior after subpage
     // animation ends.
     testElement.fire('show-container');
-    assertEquals(
-        testElement.$$('#existingPassphraseInput').inputElement,
-        testElement.$$('#existingPassphraseInput').shadowRoot.activeElement);
+    assertTrue(focused);
   });
 });
diff --git a/chrome/test/mini_installer/BUILD.gn b/chrome/test/mini_installer/BUILD.gn
index ac88753..2e14e5df 100644
--- a/chrome/test/mini_installer/BUILD.gn
+++ b/chrome/test/mini_installer/BUILD.gn
@@ -3,6 +3,59 @@
 # found in the LICENSE file.
 
 if (is_win) {
+  files = get_path_info([
+                          "chrome_helper.py",
+                          "create_zip.py",
+                          "config/chrome_beta_installed.prop",
+                          "config/chrome_beta_no_pv.prop",
+                          "config/chrome_beta_not_installed.prop",
+                          "config/chrome_beta_not_inuse.prop",
+                          "config/chrome_canary_installed.prop",
+                          "config/chrome_canary_inuse.prop",
+                          "config/chrome_canary_no_pv.prop",
+                          "config/chrome_canary_not_installed.prop",
+                          "config/chrome_canary_not_inuse.prop",
+                          "config/chrome_dev_installed.prop",
+                          "config/chrome_dev_no_pv.prop",
+                          "config/chrome_dev_not_installed.prop",
+                          "config/chrome_dev_not_inuse.prop",
+                          "config/chrome_multi_system_installed.prop",
+                          "config/chrome_multi_user_installed.prop",
+                          "config/chrome_system_installed.prop",
+                          "config/chrome_system_inuse.prop",
+                          "config/chrome_system_no_pv.prop",
+                          "config/chrome_system_not_installed.prop",
+                          "config/chrome_system_not_inuse.prop",
+                          "config/chrome_user_binaries_killed.prop",
+                          "config/chrome_user_installed.prop",
+                          "config/chrome_user_inuse.prop",
+                          "config/chrome_user_killed.prop",
+                          "config/chrome_user_no_pv.prop",
+                          "config/chrome_user_not_installed.prop",
+                          "config/chrome_user_not_inuse.prop",
+                          "config/config.config",
+                          "config/previous_chrome_canary_installed.prop",
+                          "config/previous_chrome_system_installed.prop",
+                          "config/previous_chrome_user_installed.prop",
+                          "file_verifier.py",
+                          "launch_chrome.py",
+                          "make_chrome_multi.py",
+                          "process_verifier.py",
+                          "quit_chrome.py",
+                          "registry_verifier.py",
+                          "test_chrome_with_chromedriver.py",
+                          "test_installer.py",
+                          "test_page.html",
+                          "uninstall_chrome.py",
+                          "update_lastrun.py",
+                          "variable_expander.py",
+                          "verifier.py",
+                          "verifier_runner.py",
+                          "ZIP_README.txt",
+                          "zip_test_runner.bat",
+                        ],
+                        "abspath")
+
   group("mini_installer_tests") {
     testonly = true
 
@@ -17,55 +70,25 @@
              "//testing/xvfb.py",
              "//third_party/depot_tools/download_from_google_storage.py",
              "//third_party/depot_tools/gsutil.py",
-           ] +
-           get_path_info([
-                           "chrome_helper.py",
-                           "config/chrome_beta_installed.prop",
-                           "config/chrome_beta_no_pv.prop",
-                           "config/chrome_beta_not_installed.prop",
-                           "config/chrome_beta_not_inuse.prop",
-                           "config/chrome_canary_installed.prop",
-                           "config/chrome_canary_inuse.prop",
-                           "config/chrome_canary_no_pv.prop",
-                           "config/chrome_canary_not_installed.prop",
-                           "config/chrome_canary_not_inuse.prop",
-                           "config/chrome_dev_installed.prop",
-                           "config/chrome_dev_no_pv.prop",
-                           "config/chrome_dev_not_installed.prop",
-                           "config/chrome_dev_not_inuse.prop",
-                           "config/chrome_multi_system_installed.prop",
-                           "config/chrome_multi_user_installed.prop",
-                           "config/chrome_system_installed.prop",
-                           "config/chrome_system_inuse.prop",
-                           "config/chrome_system_no_pv.prop",
-                           "config/chrome_system_not_installed.prop",
-                           "config/chrome_system_not_inuse.prop",
-                           "config/chrome_user_binaries_killed.prop",
-                           "config/chrome_user_installed.prop",
-                           "config/chrome_user_inuse.prop",
-                           "config/chrome_user_killed.prop",
-                           "config/chrome_user_no_pv.prop",
-                           "config/chrome_user_not_installed.prop",
-                           "config/chrome_user_not_inuse.prop",
-                           "config/config.config",
-                           "config/previous_chrome_canary_installed.prop",
-                           "config/previous_chrome_system_installed.prop",
-                           "config/previous_chrome_user_installed.prop",
-                           "file_verifier.py",
-                           "launch_chrome.py",
-                           "make_chrome_multi.py",
-                           "process_verifier.py",
-                           "quit_chrome.py",
-                           "registry_verifier.py",
-                           "test_chrome_with_chromedriver.py",
-                           "test_installer.py",
-                           "test_page.html",
-                           "uninstall_chrome.py",
-                           "update_lastrun.py",
-                           "variable_expander.py",
-                           "verifier.py",
-                           "verifier_runner.py",
-                         ],
-                         "abspath")
+           ] + files
+  }
+
+  action("zip_mini_installer_tests") {
+    testonly = true
+    output_zip_file = "$root_out_dir/mini_installer_tests.zip"
+    script = "create_zip.py"
+    outputs = [
+      output_zip_file,
+    ]
+    data = files
+    args = [
+      "--o",
+      rebase_path(output_zip_file, root_build_dir),
+      "--chromedriver-path",
+      rebase_path("$root_out_dir/chromedriver.exe", root_build_dir),
+    ]
+    deps = [
+      "//chrome/test/chromedriver:chromedriver",
+    ]
   }
 }
diff --git a/chrome/test/mini_installer/ZIP_README.txt b/chrome/test/mini_installer/ZIP_README.txt
new file mode 100644
index 0000000..759ac869
--- /dev/null
+++ b/chrome/test/mini_installer/ZIP_README.txt
@@ -0,0 +1,52 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.

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

+# found in the LICENSE file.

+

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

+1) Download from cloud storage

+2) Build zip_mini_installer_tests

+3) Create one from an existing zip file

+

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

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

+set the paths.

+

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

+  --output-path <ZIP_FILE_OUTPUT_PATH> ^

+  --installer-path <CURRENT_INSTALLER_PATH> ^

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

+  --chromedriver-path <CHROMEDRIVER_PATH>

+

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

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

+and chromedriver may be out of date.

+

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

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

+Automatically adding 2 installers on build could cause confusion.

+

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

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

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

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

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

+since the default may be wrong.

+

+To run:

+

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

+2) Unzip zip file

+3) Open a command window in administrator mode

+4) Navigate to the unzip folder

+5) Run test_runner.bat file

+

+Info:

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

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

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

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

+if desired.

+

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

+to reduce the amount of setup time is needed.

+

diff --git a/chrome/test/mini_installer/create_zip.py b/chrome/test/mini_installer/create_zip.py
new file mode 100644
index 0000000..993d8c9
--- /dev/null
+++ b/chrome/test/mini_installer/create_zip.py
@@ -0,0 +1,146 @@
+# 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.
+
+"""Creates a zip file that can be used by manual testers.
+
+python chrome/test/mini_installer/create_zip.py
+
+This will drop <OUTPUT_DIR>\mini_installer_tests.zip onto the disk.
+To generate an easy-to-distribute package for manual testers add the current
+and previous installers as mini_installer.exe and
+previous_version_mini_installer.exe, as well as chromedriver.exe.
+
+This can be passed out and extracted into c:\mini_installer_tests and go through
+the README.
+
+chromedriver.exe can be obtained one of two ways. Either download it from
+http://chromedriver.chromium.org/downloads. It can also be built locally, but
+if you do this make sure you are not building as components else you will
+have to copy some dlls to the chromedriver.exe dir.
+
+Note: This does not zip the executables by default. However paths to the
+current, previous, and chromedriver binaries can be passed to be zipped.
+
+The easiest way to package everything is to run:
+  python chrome\test\mini_installer\create_zip.py ^
+    -o <ZIP_FILE_OUTPUT_PATH> ^
+    -i <CURRENT_INSTALLER_PATH> ^
+    -p <PREVIOUS_INSTALLER_PATH> ^
+    -c <CHROMEDRIVER_PATH>
+
+This will drop a zip file making the distribution of the test needs simple.
+When the runner batch script is run it will install the python packages
+required by the tests to further reduce the overhead of running the tests.
+The directory structure is also preserved, so running the tests from
+run_tests.bat all of the import paths are correct. __init__.py files
+are dropped in any empty folders to make them importable.
+"""
+
+import argparse
+import logging
+import os
+import re
+import sys
+import zipfile
+
+THIS_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__)))
+SRC_DIR = os.path.join(THIS_DIR, '..', '..', '..')
+SELENIUM_PATH = os.path.abspath(os.path.join(
+    SRC_DIR, r'third_party', 'webdriver', 'pylib'))
+BLACKLIST = ['', '.pyc', '.gn', '.gni', '.txt', '.bat']
+
+
+def ArchiveDirectory(path, zipf):
+  """Archive an entire directory and subdirectories.
+
+  This will skip files that have an extension in BLACKLIST.
+
+  Args:
+    path: The path to the current directory.
+    zipf: A handle to a ZipFile instance.
+  """
+  logging.debug('Archiving %s', path)
+  for c_path in [os.path.join(path, name) for name in os.listdir(path)]:
+    if os.path.isfile(c_path):
+      if os.path.splitext(c_path)[-1] in BLACKLIST:
+        continue
+      logging.debug('Adding %s', os.path.relpath(c_path, SRC_DIR))
+      zipf.write(c_path, os.path.relpath(c_path, SRC_DIR))
+    elif os.path.isdir(c_path):
+      ArchiveDirectory(c_path, zipf)
+
+def main():
+  logging.basicConfig(
+    format='[%(asctime)s:%(filename)s(%(lineno)d)] %(message)s',
+    datefmt='%m%d/%H%M%S', level=logging.INFO)
+
+  parser = argparse.ArgumentParser(
+    description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
+  parser.add_argument('--output-path', default='installer_tests.zip',
+                      help='The path to write the zip file to')
+  parser.add_argument('--installer-path', default='',
+                      help='The path to the current installer. This is '
+                      'optional. If passed it will be zipped as '
+                      'mini_installer.exe')
+  parser.add_argument('--previous-version-installer-path', default='',
+                      help='The path to the previous installer. This is '
+                      'optional. If passed it will be zipped as '
+                      'previous_version_mini_installer.exe')
+  parser.add_argument('--chromedriver-path', default='',
+                      help='The path to chromedriver.exe. This is '
+                      'optional.')
+  args = parser.parse_args()
+
+  with zipfile.ZipFile(args.output_path, 'w') as zipf:
+
+    # Setup chrome\test\mini_installer as importable in Python
+    zipf.writestr(os.path.join('chrome', '__init__.py'), '')
+    zipf.writestr(os.path.join('chrome', 'test', '__init__.py'), '')
+    zipf.writestr(
+      os.path.join('chrome', 'test', 'mini_installer', '__init__.py'), '')
+
+    run_args = []
+    # Add any of the executables
+    if args.installer_path:
+      installer_name = os.path.split(args.installer_path)[-1]
+      run_args.append('--installer-path=' + installer_name)
+      logging.info('Archiving: %s', installer_name)
+      zipf.write(args.installer_path, installer_name)
+
+    if args.previous_version_installer_path:
+      previous_version_installer_name = os.path.split(
+        args.previous_version_installer_path)[-1]
+      run_args.append(
+        '--previous-version-installer-path=' + previous_version_installer_name)
+      logging.info('Archiving: %s', previous_version_installer_name)
+      zipf.write(
+        args.previous_version_installer_path, previous_version_installer_name)
+
+    if args.chromedriver_path:
+      chromedriver_name = os.path.split(args.chromedriver_path)[-1]
+      run_args.append('--chromedriver-path=' + chromedriver_name)
+      logging.info('Archiving: %s', chromedriver_name)
+      zipf.write(
+        args.chromedriver_path, chromedriver_name)
+
+    # Add the top level files
+    with open(os.path.join(THIS_DIR, 'zip_test_runner.bat')) as rh:
+      text = rh.read().format(run_args=' '.join(run_args))
+      text = re.sub("\r(?!\n)|(?<!\r)\n", "\r\n", text)
+      zipf.writestr('zip_test_runner.bat', text)
+    zipf.write(os.path.join(THIS_DIR, 'ZIP_README.txt'),
+               os.path.split('README.txt')[-1])
+
+    # Archive this and the chromedriver code directories
+    logging.info('Zipping chrome/test/mini_installer')
+    ArchiveDirectory(THIS_DIR, zipf)
+    logging.info('Zipping third_party/webdriver/pylib')
+    ArchiveDirectory(SELENIUM_PATH, zipf)
+  logging.info('Wrote zip to %s', args.output_path)
+
+  return 0
+
+
+if __name__ == '__main__':
+  sys.exit(main())
diff --git a/chrome/test/mini_installer/zip_test_runner.bat b/chrome/test/mini_installer/zip_test_runner.bat
new file mode 100755
index 0000000..5514028
--- /dev/null
+++ b/chrome/test/mini_installer/zip_test_runner.bat
@@ -0,0 +1,13 @@
+@echo off

+

+rem This batch file installs all Python packages needed for the test

+rem and automatically runs the test. All args passed into this batch file

+rem will be passed to test_installer.py. See

+rem chrome\test\mini_installer\test_installer.py for the args that can be

+rem passed.

+

+c:\Python27\python -m pip install --upgrade pip

+c:\Python27\Scripts\pip install psutil

+c:\Python27\Scripts\pip install pywin32

+c:\Python27\python chrome\test\mini_installer\test_installer.py {run_args} %*

+pause
\ No newline at end of file
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index 8784758..7cdf886 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-10734.0.0
\ No newline at end of file
+10741.0.0
\ No newline at end of file
diff --git a/chromeos/components/tether/asynchronous_shutdown_object_container_impl.cc b/chromeos/components/tether/asynchronous_shutdown_object_container_impl.cc
index 481fb51..ecf11e7c 100644
--- a/chromeos/components/tether/asynchronous_shutdown_object_container_impl.cc
+++ b/chromeos/components/tether/asynchronous_shutdown_object_container_impl.cc
@@ -106,7 +106,6 @@
           remote_beacon_seed_fetcher_.get(),
           ble_synchronizer_.get())),
       ble_connection_manager_(std::make_unique<BleConnectionManager>(
-          cryptauth_service,
           adapter,
           ble_advertisement_device_queue_.get(),
           ble_advertiser_.get(),
diff --git a/chromeos/components/tether/ble_connection_manager.cc b/chromeos/components/tether/ble_connection_manager.cc
index 91acde8b..48b6b3e 100644
--- a/chromeos/components/tether/ble_connection_manager.cc
+++ b/chromeos/components/tether/ble_connection_manager.cc
@@ -11,7 +11,6 @@
 #include "chromeos/components/tether/ble_constants.h"
 #include "chromeos/components/tether/timer_factory.h"
 #include "components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.h"
-#include "components/cryptauth/cryptauth_service.h"
 #include "components/cryptauth/remote_device_ref.h"
 #include "device/bluetooth/bluetooth_uuid.h"
 
@@ -215,14 +214,12 @@
 }
 
 BleConnectionManager::BleConnectionManager(
-    cryptauth::CryptAuthService* cryptauth_service,
     scoped_refptr<device::BluetoothAdapter> adapter,
     BleAdvertisementDeviceQueue* ble_advertisement_device_queue,
     BleAdvertiser* ble_advertiser,
     BleScanner* ble_scanner,
     AdHocBleAdvertiser* ad_hoc_ble_advertisement)
-    : cryptauth_service_(cryptauth_service),
-      adapter_(adapter),
+    : adapter_(adapter),
       ble_advertisement_device_queue_(ble_advertisement_device_queue),
       ble_advertiser_(ble_advertiser),
       ble_scanner_(ble_scanner),
@@ -391,8 +388,7 @@
           remote_device, adapter_, device::BluetoothUUID(kGattServerUuid),
           bluetooth_device, false /* should_set_low_connection_latency */);
   std::unique_ptr<cryptauth::SecureChannel> secure_channel =
-      cryptauth::SecureChannel::Factory::NewInstance(std::move(connection),
-                                                     cryptauth_service_);
+      cryptauth::SecureChannel::Factory::NewInstance(std::move(connection));
   connection_metadata->SetSecureChannel(std::move(secure_channel));
 
   UpdateConnectionAttempts();
diff --git a/chromeos/components/tether/ble_connection_manager.h b/chromeos/components/tether/ble_connection_manager.h
index ff91608..39323343 100644
--- a/chromeos/components/tether/ble_connection_manager.h
+++ b/chromeos/components/tether/ble_connection_manager.h
@@ -22,10 +22,6 @@
 #include "chromeos/components/tether/proto/tether.pb.h"
 #include "components/cryptauth/secure_channel.h"
 
-namespace cryptauth {
-class CryptAuthService;
-}  // namespace cryptauth
-
 namespace device {
 class BluetoothAdapter;
 class BluetoothDevice;
@@ -105,7 +101,6 @@
   };
 
   BleConnectionManager(
-      cryptauth::CryptAuthService* cryptauth_service,
       scoped_refptr<device::BluetoothAdapter> adapter,
       BleAdvertisementDeviceQueue* ble_advertisement_device_queue,
       BleAdvertiser* ble_advertiser,
@@ -252,7 +247,6 @@
   void RecordStartScanToConnectionDuration(const std::string device_id);
   void RecordConnectionToAuthenticationDuration(const std::string device_id);
 
-  cryptauth::CryptAuthService* cryptauth_service_;
   scoped_refptr<device::BluetoothAdapter> adapter_;
   BleAdvertisementDeviceQueue* ble_advertisement_device_queue_;
   BleAdvertiser* ble_advertiser_;
diff --git a/chromeos/components/tether/ble_connection_manager_unittest.cc b/chromeos/components/tether/ble_connection_manager_unittest.cc
index 813bf6b0..1e324a8 100644
--- a/chromeos/components/tether/ble_connection_manager_unittest.cc
+++ b/chromeos/components/tether/ble_connection_manager_unittest.cc
@@ -16,7 +16,6 @@
 #include "components/cryptauth/ble/bluetooth_low_energy_weave_client_connection.h"
 #include "components/cryptauth/connection.h"
 #include "components/cryptauth/fake_connection.h"
-#include "components/cryptauth/fake_cryptauth_service.h"
 #include "components/cryptauth/fake_secure_channel.h"
 #include "components/cryptauth/fake_secure_message_delegate.h"
 #include "components/cryptauth/remote_device_test_util.h"
@@ -294,10 +293,8 @@
  protected:
   class FakeSecureChannel : public cryptauth::FakeSecureChannel {
    public:
-    FakeSecureChannel(std::unique_ptr<cryptauth::Connection> connection,
-                      cryptauth::CryptAuthService* cryptauth_service)
-        : cryptauth::FakeSecureChannel(std::move(connection),
-                                       cryptauth_service) {}
+    FakeSecureChannel(std::unique_ptr<cryptauth::Connection> connection)
+        : cryptauth::FakeSecureChannel(std::move(connection)) {}
     ~FakeSecureChannel() override = default;
 
     void AddObserver(Observer* observer) override {
@@ -326,13 +323,11 @@
     }
 
     std::unique_ptr<cryptauth::SecureChannel> BuildInstance(
-        std::unique_ptr<cryptauth::Connection> connection,
-        cryptauth::CryptAuthService* cryptauth_service) override {
+        std::unique_ptr<cryptauth::Connection> connection) override {
       FakeConnectionWithAddress* fake_connection =
           static_cast<FakeConnectionWithAddress*>(connection.get());
       EXPECT_EQ(expected_device_address_, fake_connection->GetDeviceAddress());
-      FakeSecureChannel* channel =
-          new FakeSecureChannel(std::move(connection), cryptauth_service);
+      FakeSecureChannel* channel = new FakeSecureChannel(std::move(connection));
       created_channels_.push_back(channel);
       return base::WrapUnique(channel);
     }
@@ -352,8 +347,6 @@
     verified_status_changes_.clear();
     verified_received_messages_.clear();
 
-    fake_cryptauth_service_ =
-        std::make_unique<cryptauth::FakeCryptAuthService>();
     mock_adapter_ =
         base::MakeRefCounted<NiceMock<device::MockBluetoothAdapter>>();
 
@@ -378,9 +371,8 @@
         fake_secure_channel_factory_.get());
 
     manager_ = base::WrapUnique(new BleConnectionManager(
-        fake_cryptauth_service_.get(), mock_adapter_, device_queue_.get(),
-        fake_ble_advertiser_.get(), fake_ble_scanner_.get(),
-        fake_ad_hoc_ble_advertiser_.get()));
+        mock_adapter_, device_queue_.get(), fake_ble_advertiser_.get(),
+        fake_ble_scanner_.get(), fake_ad_hoc_ble_advertiser_.get()));
     test_observer_ = base::WrapUnique(new TestObserver());
     manager_->AddObserver(test_observer_.get());
     test_metrics_observer_ = base::WrapUnique(new TestMetricsObserver());
@@ -637,7 +629,6 @@
 
   const cryptauth::RemoteDeviceRefList test_devices_;
 
-  std::unique_ptr<cryptauth::FakeCryptAuthService> fake_cryptauth_service_;
   scoped_refptr<NiceMock<device::MockBluetoothAdapter>> mock_adapter_;
   std::unique_ptr<FakeBleAdvertiser> fake_ble_advertiser_;
   std::unique_ptr<FakeBleScanner> fake_ble_scanner_;
diff --git a/chromeos/components/tether/fake_ble_connection_manager.cc b/chromeos/components/tether/fake_ble_connection_manager.cc
index 9f5847e..749688db 100644
--- a/chromeos/components/tether/fake_ble_connection_manager.cc
+++ b/chromeos/components/tether/fake_ble_connection_manager.cc
@@ -27,7 +27,6 @@
                            nullptr,
                            nullptr,
                            nullptr,
-                           nullptr,
                            nullptr) {}
 
 FakeBleConnectionManager::~FakeBleConnectionManager() = default;
diff --git a/chromeos/services/secure_channel/authenticated_channel_impl_unittest.cc b/chromeos/services/secure_channel/authenticated_channel_impl_unittest.cc
index c2077572..5febed0 100644
--- a/chromeos/services/secure_channel/authenticated_channel_impl_unittest.cc
+++ b/chromeos/services/secure_channel/authenticated_channel_impl_unittest.cc
@@ -38,8 +38,7 @@
 
   void SetUp() override {
     auto fake_secure_channel = std::make_unique<cryptauth::FakeSecureChannel>(
-        std::make_unique<cryptauth::FakeConnection>(test_device_),
-        nullptr /* cryptauth_service */);
+        std::make_unique<cryptauth::FakeConnection>(test_device_));
     fake_secure_channel->ChangeStatus(
         cryptauth::SecureChannel::Status::AUTHENTICATED);
     fake_secure_channel_ = fake_secure_channel.get();
diff --git a/components/arc/common/notifications.mojom b/components/arc/common/notifications.mojom
index ffcbcc5b..1887e4a 100644
--- a/components/arc/common/notifications.mojom
+++ b/components/arc/common/notifications.mojom
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
-// Next MinVersion: 17
+// Next MinVersion: 18
 
 module arc.mojom;
 
@@ -72,6 +72,19 @@
   CONTENTS_SHOWN = 0,
   // The notification settings view is shown.
   SETTINGS_SHOWN = 1,
+  // The notification snooze settings view is shown.
+  [MinVersion=17]
+  SNOOZE_SHOWN = 2,
+};
+
+// Flag for various feature of ARC notifications.
+[Extensible, MinVersion=17]
+struct ArcNotificationFlags {
+  // Bits for features.
+  const uint32 SUPPORT_SNOOZE = 1;  // 1 << 0
+
+  // Bit-masked value.
+  uint32 value;
 };
 
 struct ArcNotificationData {
@@ -139,6 +152,8 @@
   Rect? swipe_input_rect;
   [MinVersion=15]
   string? package_name;
+  [MinVersion=17]
+  ArcNotificationFlags? flags;
 };
 
 // Next Method ID: 7
@@ -162,7 +177,7 @@
   OpenMessageCenter@6();
 };
 
-// Next Method ID: 6
+// Next Method ID: 7
 // TODO(lhchavez): Migrate all request/response messages to Mojo.
 interface NotificationsInstance {
   // DEPRECATED: Please use Init@5 instead.
@@ -192,4 +207,10 @@
   // side.
   [MinVersion=9]
   OpenNotificationSettings@4(string key);
+
+  // Requests to Android side to open snooze settings.
+  // |key| is the identifier of the notification which is generated by Android
+  // side.
+  [MinVersion=17]
+  OpenNotificationSnoozeSettings@6(string key);
 };
diff --git a/components/arc/test/fake_notifications_instance.cc b/components/arc/test/fake_notifications_instance.cc
index 09c5150..b25c4554 100644
--- a/components/arc/test/fake_notifications_instance.cc
+++ b/components/arc/test/fake_notifications_instance.cc
@@ -27,6 +27,9 @@
 void FakeNotificationsInstance::OpenNotificationSettings(
     const std::string& key) {}
 
+void FakeNotificationsInstance::OpenNotificationSnoozeSettings(
+    const std::string& key) {}
+
 void FakeNotificationsInstance::InitDeprecated(
     mojom::NotificationsHostPtr host_ptr) {
   Init(std::move(host_ptr), base::DoNothing());
diff --git a/components/arc/test/fake_notifications_instance.h b/components/arc/test/fake_notifications_instance.h
index ef68f6d..b8b5256 100644
--- a/components/arc/test/fake_notifications_instance.h
+++ b/components/arc/test/fake_notifications_instance.h
@@ -29,6 +29,7 @@
   void CreateNotificationWindow(const std::string& key) override;
   void CloseNotificationWindow(const std::string& key) override;
   void OpenNotificationSettings(const std::string& key) override;
+  void OpenNotificationSnoozeSettings(const std::string& key) override;
 
   const std::vector<std::pair<std::string, mojom::ArcNotificationEvent>>&
   events() const;
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc
index 63f5064..ab9a42c 100644
--- a/components/autofill/content/renderer/password_autofill_agent.cc
+++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -1631,15 +1631,18 @@
 }
 
 void PasswordAutofillAgent::FrameClosing() {
-  for (auto const& iter : web_input_to_password_info_) {
-    password_to_username_.erase(iter.second.password_field);
-  }
   web_input_to_password_info_.clear();
+  password_to_username_.clear();
+  last_supplied_password_info_iter_ = web_input_to_password_info_.end();
   provisionally_saved_form_.Reset();
   field_value_and_properties_map_.clear();
-  username_detector_cache_.clear();
+  was_username_autofilled_ = false;
+  was_password_autofilled_ = false;
   sent_request_to_store_ = false;
   checked_safe_browsing_reputation_ = false;
+  username_query_prefix_.clear();
+  form_predictions_.clear();
+  username_detector_cache_.clear();
   blacklisted_form_found_ = false;
 #if !defined(OS_ANDROID) && !defined(OS_IOS)
   page_passwords_analyser_.Reset();
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn
index 5edadd8..f75afe34 100644
--- a/components/autofill/core/browser/BUILD.gn
+++ b/components/autofill/core/browser/BUILD.gn
@@ -111,8 +111,12 @@
     "legal_message_line.h",
     "name_field.cc",
     "name_field.h",
+    "password_generator.cc",
+    "password_generator.h",
     "password_generator_fips181.cc",
     "password_generator_fips181.h",
+    "password_requirements_spec_fetcher.cc",
+    "password_requirements_spec_fetcher.h",
     "payments/full_card_request.cc",
     "payments/full_card_request.h",
     "payments/payments_client.cc",
@@ -245,6 +249,8 @@
     "//services/identity/public/cpp",
     "//services/metrics/public/cpp:metrics_cpp",
     "//services/metrics/public/cpp:ukm_builders",
+    "//services/network/public/cpp",
+    "//services/network/public/mojom",
     "//sql",
     "//third_party/fips181",
     "//third_party/icu",
@@ -399,6 +405,8 @@
     "legal_message_line_unittest.cc",
     "name_field_unittest.cc",
     "password_generator_fips181_unittest.cc",
+    "password_generator_unittest.cc",
+    "password_requirements_spec_fetcher_unittest.cc",
     "payments/full_card_request_unittest.cc",
     "payments/payments_client_unittest.cc",
     "payments/payments_service_url_unittest.cc",
@@ -457,6 +465,7 @@
     "//net:test_support",
     "//services/identity/public/cpp:test_support",
     "//services/metrics/public/cpp:ukm_builders",
+    "//services/network:test_support",
     "//sql",
     "//testing/gmock",
     "//testing/gtest",
diff --git a/components/autofill/core/browser/DEPS b/components/autofill/core/browser/DEPS
index fa356fa..71a374d 100644
--- a/components/autofill/core/browser/DEPS
+++ b/components/autofill/core/browser/DEPS
@@ -23,6 +23,7 @@
   "+net",
   "+services/identity/public",
   "+services/metrics/public",
+  "+services/network/public",
   "+sql",
   "+third_party/fips181",
   "+third_party/libaddressinput", # For address i18n.
@@ -45,4 +46,7 @@
   "test_autofill_client\.h": [
     "+components/ukm",
   ],
+  "password_requirements_spec_fetcher_unittest\.cc": [
+    "+services/network/test",
+  ]
 }
diff --git a/components/autofill/core/browser/password_generator.cc b/components/autofill/core/browser/password_generator.cc
new file mode 100644
index 0000000..a475905
--- /dev/null
+++ b/components/autofill/core/browser/password_generator.cc
@@ -0,0 +1,196 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/password_generator.h"
+
+#include <algorithm>
+#include <limits>
+#include <map>
+#include <vector>
+
+#include "base/logging.h"
+#include "base/rand_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/browser/proto/password_requirements.pb.h"
+
+namespace autofill {
+
+const uint32_t kDefaultPasswordLength = 15;
+
+namespace {
+
+// Default character sets used if the spec does not override the character set.
+constexpr char kLowerCaseChars[] = "abcdefghijklmnopqrstuvwxyz";
+constexpr char kUpperCaseChars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+constexpr char kAlphabeticChars[] =
+    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+constexpr char kDigits[] = "0123456789";
+constexpr char kSymbols[] = "-_.";
+
+// Returns a default password requirements specification that requires:
+// - at least one lower case letter
+// - at least one upper case letter
+// - at least one number
+// - no symbols
+PasswordRequirementsSpec BuildDefaultSpec() {
+  // Note the the fields below should be initialized in the order of their
+  // proto field numbers to reduce the risk of forgetting a field.
+  PasswordRequirementsSpec spec;
+  spec.set_priority(0);
+  spec.set_spec_version(1);
+  // spec.min_length and spec.max_length remain unset to fall back to
+  // PasswordGenerator::kDefaultPasswordLength.
+
+  spec.mutable_lower_case()->set_character_set(kLowerCaseChars);
+  spec.mutable_lower_case()->set_min(1);
+  spec.mutable_lower_case()->set_max(std::numeric_limits<int32_t>::max());
+
+  spec.mutable_upper_case()->set_character_set(kUpperCaseChars);
+  spec.mutable_upper_case()->set_min(1);
+  spec.mutable_upper_case()->set_max(std::numeric_limits<int32_t>::max());
+
+  spec.mutable_alphabetic()->set_character_set(kAlphabeticChars);
+  spec.mutable_alphabetic()->set_min(0);
+  spec.mutable_alphabetic()->set_max(0);
+
+  spec.mutable_numeric()->set_character_set(kDigits);
+  spec.mutable_numeric()->set_min(1);
+  spec.mutable_numeric()->set_max(std::numeric_limits<int32_t>::max());
+
+  spec.mutable_symbols()->set_character_set(kSymbols);
+  spec.mutable_symbols()->set_min(0);
+  spec.mutable_symbols()->set_max(0);
+  return spec;
+}
+
+// Generates a password according to |spec| and tries to maximze the entropy
+// while not caring for pronounceable passwords.
+//
+// |spec| must contain values for at least all fields that are defined
+// in the spec of BuildDefaultSpec().
+base::string16 GenerateMaxEntropyPassword(PasswordRequirementsSpec spec) {
+  using CharacterClass = PasswordRequirementsSpec_CharacterClass;
+
+  // Determine target length.
+  uint32_t target_length = kDefaultPasswordLength;
+  if (spec.has_min_length())
+    target_length = std::max(target_length, spec.min_length());
+  if (spec.has_max_length())
+    target_length = std::min(target_length, spec.max_length());
+  // Avoid excessively long passwords.
+  target_length = std::min(target_length, 200u);
+
+  // The password that is being generated in this function.
+  base::string16 password;
+  password.reserve(target_length);
+
+  // A list of CharacterClasses that have not been fully used.
+  std::vector<CharacterClass*> classes;
+  // The list of allowed characters in a specific class. This map exists
+  // to calculate the string16 conversion only once.
+  std::map<CharacterClass*, base::string16> characters_of_class;
+
+  // These are guaranteed to exist because |spec| is an overlay of the default
+  // spec.
+  DCHECK(spec.has_lower_case());
+  DCHECK(spec.has_upper_case());
+  DCHECK(spec.has_alphabetic());
+  DCHECK(spec.has_numeric());
+  DCHECK(spec.has_symbols());
+
+  // Initialize |classes| and |characters_of_class| and sanitize |spec|
+  // if necessary.
+  for (CharacterClass* character_class :
+       {spec.mutable_lower_case(), spec.mutable_upper_case(),
+        spec.mutable_alphabetic(), spec.mutable_numeric(),
+        spec.mutable_symbols()}) {
+    DCHECK(character_class->has_character_set());
+    DCHECK(character_class->has_min());
+    DCHECK(character_class->has_max());
+
+    // If the character set is empty, we cannot generate characters from it.
+    if (character_class->character_set().empty())
+      character_class->set_max(0);
+
+    // The the maximum is smaller than the minimum, limit the minimum.
+    if (character_class->max() < character_class->min())
+      character_class->set_min(character_class->max());
+
+    if (character_class->max() > 0) {
+      classes.push_back(character_class);
+      characters_of_class[character_class] =
+          base::UTF8ToUTF16(character_class->character_set());
+    }
+  }
+
+  // Generate a password that contains the minimum number of characters of the
+  // various character classes as per requirements. This stops when the target
+  // length is achieved. Note that this is just a graceful handling of a buggy
+  // spec. It should not happen that more characters are needed than can
+  // accommodated.
+  for (CharacterClass* character_class : classes) {
+    while (character_class->min() > 0 && password.length() < target_length) {
+      const base::string16& possible_chars =
+          characters_of_class[character_class];
+      password += possible_chars[base::RandGenerator(possible_chars.length())];
+      character_class->set_min(character_class->min() - 1);
+      character_class->set_max(character_class->max() - 1);
+    }
+  }
+
+  // Now fill the rest of the password with random characters.
+  while (password.length() < target_length) {
+    // Determine how many different characters are in all remaining character
+    // classes.
+    size_t number_of_possible_chars = 0;
+    for (CharacterClass* character_class : classes) {
+      if (character_class->max() > 0) {
+        number_of_possible_chars +=
+            characters_of_class[character_class].length();
+      }
+    }
+    if (number_of_possible_chars == 0)
+      break;
+    uint64_t choice = base::RandGenerator(number_of_possible_chars);
+    // Now figure out which character was chosen and append it.
+    for (CharacterClass* character_class : classes) {
+      if (character_class->max() > 0) {
+        size_t size_of_class = characters_of_class[character_class].length();
+        if (choice < size_of_class) {
+          password += characters_of_class[character_class][choice];
+          character_class->set_max(character_class->max() - 1);
+          break;
+        } else {
+          choice -= size_of_class;
+        }
+      }
+    }
+  }
+
+  // So far the password contains the minimally required characters at the
+  // the beginning. Therefore, we create a random permutation.
+  base::RandomShuffle(password.begin(), password.end());
+
+  return password;
+}
+
+}  // namespace
+
+base::string16 GeneratePassword(const PasswordRequirementsSpec& spec) {
+  PasswordRequirementsSpec actual_spec = BuildDefaultSpec();
+
+  // Override all fields that are set in |spec|. Character classes are merged
+  // recursively.
+  actual_spec.MergeFrom(spec);
+
+  base::string16 password = GenerateMaxEntropyPassword(std::move(actual_spec));
+
+  // Catch cases where supplied spec is infeasible.
+  if (password.empty())
+    password = GenerateMaxEntropyPassword(BuildDefaultSpec());
+
+  return password;
+}
+
+}  // namespace autofill
diff --git a/components/autofill/core/browser/password_generator.h b/components/autofill/core/browser/password_generator.h
new file mode 100644
index 0000000..4ff870f
--- /dev/null
+++ b/components/autofill/core/browser/password_generator.h
@@ -0,0 +1,30 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PASSWORD_GENERATOR_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PASSWORD_GENERATOR_H_
+
+#include "base/strings/string16.h"
+
+namespace autofill {
+
+class PasswordRequirementsSpec;
+
+extern const uint32_t kDefaultPasswordLength;
+
+// Returns a password that follows the |spec| as well as possible. If this is
+// impossible, a password that nearly meets the requirements can be returned.
+// In this case the user is asked to fix the password themselves.
+//
+// If |spec| is empty, a password of length |kDefaultPasswordLength| is
+// generated that contains
+// - at least 1 lower case latin character
+// - at least 1 upper case latin character
+// - at least 1 number (digit)
+// - no symbols
+base::string16 GeneratePassword(const PasswordRequirementsSpec& spec);
+
+}  // namespace autofill
+
+#endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_PASSWORD_GENERATOR_H_
diff --git a/components/autofill/core/browser/password_generator_unittest.cc b/components/autofill/core/browser/password_generator_unittest.cc
new file mode 100644
index 0000000..853438871
--- /dev/null
+++ b/components/autofill/core/browser/password_generator_unittest.cc
@@ -0,0 +1,273 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/password_generator.h"
+
+#include "base/logging.h"
+#include "components/autofill/core/browser/proto/password_requirements.pb.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace autofill {
+
+namespace {
+
+// These are strings instead of enums to have an easy way of logging them.
+constexpr char kLowerCase[] = "lower_case";
+constexpr char kUpperCase[] = "upper_case";
+constexpr char kAlphabetic[] = "alphabetic";
+constexpr char kNumeric[] = "numeric";
+constexpr char kSymbol[] = "symbol";
+
+constexpr const char* kAllClassesButSymbols[] = {kLowerCase, kUpperCase,
+                                                 kAlphabetic, kNumeric};
+constexpr const char* kAllClassesButSymbolsAndAlphabetic[] = {
+    kLowerCase, kUpperCase, kNumeric};
+
+bool IsCharInClass(base::char16 c, const std::string& class_name) {
+  if (class_name == kLowerCase) {
+    return 'a' <= c && c <= 'z';
+  } else if (class_name == kUpperCase) {
+    return 'A' <= c && c <= 'Z';
+  } else if (class_name == kAlphabetic) {
+    return IsCharInClass(c, kLowerCase) || IsCharInClass(c, kUpperCase);
+  } else if (class_name == kNumeric) {
+    return '0' <= c && c <= '9';
+  }
+  // Symbols are not covered because there is not fixed definition and because
+  // symbols are treated like other character classes, so the importance of
+  // dealing with them here is limited.
+  NOTREACHED() << "Don't call IsCharInClass for symbols";
+  return false;
+}
+
+size_t CountCharsInClass(const base::string16& password,
+                         const std::string& class_name) {
+  size_t num = 0;
+  for (base::char16 c : password) {
+    if (IsCharInClass(c, class_name))
+      ++num;
+  }
+  return num;
+}
+
+PasswordRequirementsSpec_CharacterClass* GetMutableCharClass(
+    PasswordRequirementsSpec* spec,
+    const std::string& class_name) {
+  if (class_name == kLowerCase) {
+    return spec->mutable_lower_case();
+  } else if (class_name == kUpperCase) {
+    return spec->mutable_upper_case();
+  } else if (class_name == kAlphabetic) {
+    return spec->mutable_alphabetic();
+  } else if (class_name == kNumeric) {
+    return spec->mutable_numeric();
+  } else if (class_name == kSymbol) {
+    return spec->mutable_symbols();
+  }
+  NOTREACHED();
+  return nullptr;
+}
+
+class PasswordGeneratorTest : public testing::Test {
+ public:
+  PasswordGeneratorTest() { spec_.set_spec_version(1); }
+  ~PasswordGeneratorTest() override = default;
+
+  PasswordRequirementsSpec spec_;
+};
+
+TEST_F(PasswordGeneratorTest, PasswordLengthDefault) {
+  EXPECT_EQ(kDefaultPasswordLength, GeneratePassword(spec_).length());
+}
+
+TEST_F(PasswordGeneratorTest, PasswordLengthMaxLength) {
+  // Limit length according to requirement.
+  spec_.set_max_length(kDefaultPasswordLength - 5u);
+  EXPECT_EQ(kDefaultPasswordLength - 5u, GeneratePassword(spec_).length());
+
+  // If max is higher than default, it does not matter.
+  spec_.set_max_length(kDefaultPasswordLength + 5);
+  EXPECT_EQ(kDefaultPasswordLength, GeneratePassword(spec_).length());
+}
+
+TEST_F(PasswordGeneratorTest, PasswordLengthMinLength) {
+  // If min is smaller than default, it does not matter.
+  spec_.set_min_length(kDefaultPasswordLength - 5u);
+  EXPECT_EQ(kDefaultPasswordLength, GeneratePassword(spec_).length());
+
+  // If a higher minimum length is explicitly set, use it.
+  spec_.set_min_length(kDefaultPasswordLength + 5u);
+  EXPECT_EQ(kDefaultPasswordLength + 5u, GeneratePassword(spec_).length());
+}
+
+TEST_F(PasswordGeneratorTest, PasswordLengthMinAndMax) {
+  // Configure a contradicting min and max length. The max length wins.
+  spec_.set_min_length(kDefaultPasswordLength + 5u);
+  spec_.set_max_length(kDefaultPasswordLength - 5u);
+  EXPECT_EQ(kDefaultPasswordLength - 5u, GeneratePassword(spec_).length());
+}
+
+TEST_F(PasswordGeneratorTest, MinCharFrequenciesRespected) {
+  for (std::string char_class : kAllClassesButSymbols) {
+    SCOPED_TRACE(char_class);
+    spec_ = PasswordRequirementsSpec();
+    spec_.set_spec_version(1);
+    auto* char_class_config = GetMutableCharClass(&spec_, char_class);
+    char_class_config->set_min(10);
+    char_class_config->set_max(1000);
+
+    base::string16 password = GeneratePassword(spec_);
+    EXPECT_GE(CountCharsInClass(password, char_class), 10u);
+  }
+}
+
+TEST_F(PasswordGeneratorTest, MinCharFrequenciesInsane) {
+  // Nothing breaks if the min frequencies are way beyond what's possible
+  // with the password length. In this case the generated passwor may contain
+  // just characters of one class but its target length does not increase.
+  for (std::string char_class : kAllClassesButSymbols) {
+    SCOPED_TRACE(char_class);
+    spec_ = PasswordRequirementsSpec();
+    spec_.set_spec_version(1);
+    auto* char_class_config = GetMutableCharClass(&spec_, char_class);
+    char_class_config->set_min(1000);
+    char_class_config->set_max(1000);
+
+    base::string16 password = GeneratePassword(spec_);
+    // At least some of the characters should be there.
+    EXPECT_GE(CountCharsInClass(password, char_class), 1u);
+    // But the password length does not change by minimum length requirements.
+    EXPECT_EQ(kDefaultPasswordLength, GeneratePassword(spec_).length());
+  }
+}
+
+TEST_F(PasswordGeneratorTest, MinCharFrequenciesBiggerThanMax) {
+  spec_.set_min_length(15);
+  spec_.set_max_length(15);
+  for (std::string char_class : kAllClassesButSymbolsAndAlphabetic) {
+    auto* char_class_config = GetMutableCharClass(&spec_, char_class);
+    // Min is reduced to max --> each class should have 5 representatives.
+    char_class_config->set_min(10);
+    char_class_config->set_max(5);
+  }
+
+  base::string16 password = GeneratePassword(spec_);
+
+  for (std::string char_class : kAllClassesButSymbolsAndAlphabetic) {
+    SCOPED_TRACE(char_class);
+    // Check that each character class is represented by 5 characters.
+    EXPECT_EQ(5u, CountCharsInClass(password, char_class));
+  }
+  EXPECT_EQ(15u, password.length());
+}
+
+TEST_F(PasswordGeneratorTest, MaxFrequenciesRespected) {
+  // Limit the maximum occurrences of characters of some classes to 2 and
+  // validate that this is respected.
+  for (std::string char_class : kAllClassesButSymbolsAndAlphabetic) {
+    SCOPED_TRACE(char_class);
+    spec_ = PasswordRequirementsSpec();
+    spec_.set_spec_version(1);
+    auto* char_class_config = GetMutableCharClass(&spec_, char_class);
+    char_class_config->set_max(2);
+
+    base::string16 password = GeneratePassword(spec_);
+    EXPECT_LE(CountCharsInClass(password, char_class), 2u);
+    // Ensure that the other character classes that are not limited fill up the
+    // password to the desired length.
+    EXPECT_EQ(kDefaultPasswordLength, GeneratePassword(spec_).length());
+  }
+}
+
+TEST_F(PasswordGeneratorTest, MaxFrequenciesInsufficient) {
+  spec_.set_min_length(15);
+  spec_.set_max_length(15);
+  // Limit the maximum occurrences of characters of all classes to 2 which
+  // sums up to less than 15.
+  for (std::string char_class : kAllClassesButSymbolsAndAlphabetic) {
+    auto* char_class_config = GetMutableCharClass(&spec_, char_class);
+    char_class_config->set_max(2);
+  }
+  // The resulting password can contain only 6 characters.
+  EXPECT_EQ(6u, GeneratePassword(spec_).length());
+}
+
+TEST_F(PasswordGeneratorTest, CharacterSetCanBeOverridden) {
+  // Limit lower case chars to 'a' and 'b' and require exacty 5 of those.
+  spec_.mutable_lower_case()->set_character_set("ab");
+  spec_.mutable_lower_case()->set_min(5);
+  spec_.mutable_lower_case()->set_max(5);
+  base::string16 password = GeneratePassword(spec_);
+  // Then ensure that 'a's and 'b's are generated at the expected frequencies
+  // as an indicator that the override was respected.
+  size_t num_as_and_bs = 0;
+  for (base::char16 c : password) {
+    if (c == 'a' || c == 'b')
+      ++num_as_and_bs;
+  }
+  EXPECT_EQ(5u, num_as_and_bs);
+}
+
+TEST_F(PasswordGeneratorTest, AllCharactersAreGenerated) {
+  // Limit lower case chars to 'a' and 'b' and require exacty 5 of those.
+  spec_.mutable_lower_case()->set_character_set("ab");
+  spec_.mutable_lower_case()->set_min(5);
+  spec_.mutable_lower_case()->set_max(5);
+  bool success = false;
+  // The chance of not seing both an 'a' and a 'b' in one run are only 2/32 per
+  // run. Ultimately we should see success. If none of the 100 generated
+  // passwords contained an 'a' (or 'b'), then this would indicate that the
+  // generator does not fully use the character set (probably due to an
+  // off-by-one error).
+  for (size_t attempt = 0; attempt < 100; ++attempt) {
+    base::string16 password = GeneratePassword(spec_);
+    size_t num_as = 0;
+    size_t num_bs = 0;
+    for (base::char16 c : password) {
+      if (c == 'a')
+        ++num_as;
+      if (c == 'b')
+        ++num_bs;
+    }
+    if (num_as > 0u && num_bs > 0u) {
+      success = true;
+      break;
+    }
+  }
+  EXPECT_TRUE(success);
+}
+
+TEST_F(PasswordGeneratorTest, PasswordCanBeGeneratedWithEmptyCharSet) {
+  // If the character set is empty, min and max should be ignored.
+  spec_.mutable_lower_case()->set_character_set("");
+  spec_.mutable_lower_case()->set_min(5);
+  spec_.mutable_lower_case()->set_max(5);
+  base::string16 password = GeneratePassword(spec_);
+  EXPECT_EQ(0u, CountCharsInClass(password, kLowerCase));
+  EXPECT_EQ(kDefaultPasswordLength, GeneratePassword(spec_).length());
+}
+
+TEST_F(PasswordGeneratorTest, AllCharactersForbidden) {
+  spec_.set_min_length(kDefaultPasswordLength + 2);
+  spec_.set_max_length(kDefaultPasswordLength + 2);
+  for (std::string char_class : kAllClassesButSymbolsAndAlphabetic) {
+    auto* char_class_config = GetMutableCharClass(&spec_, char_class);
+    char_class_config->set_max(0);
+  }
+  // If it is impossible to generate a password (due to max = 0), the generator
+  // delivers a password as per default spec and ignores everything else.
+  EXPECT_EQ(kDefaultPasswordLength, GeneratePassword(spec_).length());
+}
+
+TEST_F(PasswordGeneratorTest, ZeroLength) {
+  spec_.set_min_length(0);
+  spec_.set_max_length(0);
+  // If the generated password following the spec is empty, a default spec is
+  // applied.
+  EXPECT_EQ(kDefaultPasswordLength, GeneratePassword(spec_).length());
+}
+
+}  // namespace
+
+}  // namespace autofill
diff --git a/components/autofill/core/browser/password_requirements_spec_fetcher.cc b/components/autofill/core/browser/password_requirements_spec_fetcher.cc
new file mode 100644
index 0000000..7059b63
--- /dev/null
+++ b/components/autofill/core/browser/password_requirements_spec_fetcher.cc
@@ -0,0 +1,156 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/password_requirements_spec_fetcher.h"
+
+#include "base/logging.h"
+#include "base/md5.h"
+#include "base/strings/stringprintf.h"
+#include "base/time/time.h"
+#include "components/autofill/core/browser/proto/password_requirements.pb.h"
+#include "net/base/load_flags.h"
+#include "net/base/net_errors.h"
+#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
+#include "services/network/public/cpp/resource_request.h"
+#include "services/network/public/cpp/simple_url_loader.h"
+
+namespace autofill {
+
+PasswordRequirementsSpecFetcher::PasswordRequirementsSpecFetcher(
+    int version,
+    size_t prefix_length,
+    int timeout)
+    : version_(version), prefix_length_(prefix_length), timeout_(timeout) {
+  DCHECK_GE(version_, 0);
+  DCHECK_LE(prefix_length_, 32u);
+  DCHECK_GE(timeout_, 0);
+}
+
+PasswordRequirementsSpecFetcher::~PasswordRequirementsSpecFetcher() = default;
+
+namespace {
+
+// Hashes the eTLD+1 of |origin| via MD5 and returns a filename with the first
+// |prefix_length| bits populated. The returned value corresponds to the first
+// 4 bytes of the truncated MD5 prefix in hex notation.
+// For example:
+//   "https://www.example.com" has a eTLD+1 of "example.com".
+//   The MD5SUM of that is 5ababd603b22780302dd8d83498e5172.
+//   Stripping this to the first 8 bits (prefix_length = 8) gives
+//   500000000000000000000000000000000. The file name is always cut to the first
+//   four bytes, i.e. 5000 in this example.
+std::string GetHashPrefix(const GURL& origin, size_t prefix_length) {
+  DCHECK_LE(prefix_length, 32u);
+  std::string domain_and_registry =
+      net::registry_controlled_domains::GetDomainAndRegistry(
+          origin, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
+
+  base::MD5Digest digest;
+  base::MD5Sum(domain_and_registry.data(), domain_and_registry.size(), &digest);
+
+  for (size_t i = 0; i < base::size(digest.a); ++i) {
+    if (prefix_length >= 8) {
+      prefix_length -= 8;
+      continue;
+    } else {
+      // Determine the |prefix_length| most significant bits by calculating
+      // the 8 - |prefix_length| least significant bits and inverting the
+      // result.
+      digest.a[i] &= ~((1 << (8 - prefix_length)) - 1);
+      prefix_length = 0;
+    }
+  }
+
+  return base::MD5DigestToBase16(digest).substr(0, 4);
+}
+
+// Returns the URL on gstatic.com where the passwords spec file can be found
+// that contains data for |origin|.
+GURL GetUrlForRequirementsSpec(const GURL& origin,
+                               int version,
+                               size_t prefix_length) {
+  std::string hash_prefix = GetHashPrefix(origin, prefix_length);
+  return GURL(base::StringPrintf(
+      "https://www.gstatic.com/chrome/password_requirements/%d/%s", version,
+      hash_prefix.c_str()));
+}
+
+}  // namespace
+
+void PasswordRequirementsSpecFetcher::Fetch(
+    network::mojom::URLLoaderFactory* loader_factory,
+    const GURL& origin,
+    FetchCallback callback) {
+  DCHECK(origin.is_valid());
+  DCHECK(origin_.is_empty());
+  DCHECK(callback_.is_null());
+  origin_ = origin;
+  callback_ = std::move(callback);
+
+  net::NetworkTrafficAnnotationTag traffic_annotation =
+      net::DefineNetworkTrafficAnnotation("password_requirements_spec_fetch",
+                                          R"(
+      semantics {
+        sender: "Password requirements specification fetcher"
+        description:
+          "Fetches the password requirements for a set of domains whose origin "
+          "hash starts with a certain prefix."
+        trigger:
+          "When the user triggers a password generation (this can happen by "
+          "just focussing a password field)."
+        data:
+          "The URL encodes a hash prefix from which it is not possible to "
+          "derive the original origin. No user information is sent."
+        destination: WEBSITE
+      }
+      policy {
+        cookies_allowed: NO
+        setting: "Unconditionally enabled."
+        policy_exception_justification:
+          "Not implemented, considered not useful."
+      })");
+  auto resource_request = std::make_unique<network::ResourceRequest>();
+  resource_request->url =
+      GetUrlForRequirementsSpec(origin, version_, prefix_length_);
+  resource_request->load_flags = net::LOAD_DO_NOT_SAVE_COOKIES |
+                                 net::LOAD_DO_NOT_SEND_COOKIES |
+                                 net::LOAD_DO_NOT_SEND_AUTH_DATA;
+  url_loader_ = network::SimpleURLLoader::Create(std::move(resource_request),
+                                                 traffic_annotation);
+  url_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
+      loader_factory,
+      base::BindOnce(&PasswordRequirementsSpecFetcher::OnFetchComplete,
+                     base::Unretained(this)));
+
+  download_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(timeout_),
+                        this, &PasswordRequirementsSpecFetcher::OnFetchTimeout);
+}
+
+void PasswordRequirementsSpecFetcher::OnFetchComplete(
+    std::unique_ptr<std::string> response_body) {
+  download_timer_.Stop();
+
+  // Destroy the fetcher when this method returns.
+  std::unique_ptr<network::SimpleURLLoader> loader(std::move(url_loader_));
+
+  if (!response_body || loader->NetError() != net::Error::OK) {
+    // TODO(crbug.com/846694): log error in UKM / UMA.
+    std::move(callback_).Run(PasswordRequirementsSpec());
+    return;
+  }
+
+  // TODO(crbug.com/846694): log statistics, process data.
+  // For now this is just some dummy data for testing.
+  PasswordRequirementsSpec spec;
+  spec.set_min_length(17);
+  std::move(callback_).Run(spec);
+}
+
+void PasswordRequirementsSpecFetcher::OnFetchTimeout() {
+  url_loader_.reset();
+  // TODO(crbug.com/846694): log error (abort)
+  std::move(callback_).Run(PasswordRequirementsSpec());
+}
+
+}  // namespace autofill
diff --git a/components/autofill/core/browser/password_requirements_spec_fetcher.h b/components/autofill/core/browser/password_requirements_spec_fetcher.h
new file mode 100644
index 0000000..64b1b124
--- /dev/null
+++ b/components/autofill/core/browser/password_requirements_spec_fetcher.h
@@ -0,0 +1,93 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PASSWORD_REQUIREMENTS_SPEC_FETCHER_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_PASSWORD_REQUIREMENTS_SPEC_FETCHER_H_
+
+#include <memory>
+#include <string>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/timer/timer.h"
+#include "url/gurl.h"
+
+namespace network {
+class SimpleURLLoader;
+namespace mojom {
+class URLLoaderFactory;
+}  // namespace mojom
+}  // namespace network
+
+namespace autofill {
+
+class PasswordRequirementsSpec;
+
+// Fetches PasswordRequirementsSpec for a specific origin.
+class PasswordRequirementsSpecFetcher {
+ public:
+  using FetchCallback =
+      base::OnceCallback<void(const PasswordRequirementsSpec&)>;
+
+  // See the member variables for explanations of these parameters.
+  PasswordRequirementsSpecFetcher(int version,
+                                  size_t prefix_length,
+                                  int timeout);
+  ~PasswordRequirementsSpecFetcher();
+
+  // Fetches a configuration for |origin|.
+  //
+  // |origin| references the origin in the PasswordForm for which rules need to
+  // be fetched.
+  //
+  // The |callback| must remain valid thoughout the life-cycle of this class,
+  // but the class may be destroyed before the |callback| has been triggered.
+  //
+  // Fetch() must be called only once per fetcher.
+  //
+  // If the network request fails or times out, the callback receives an empty
+  // spec.
+  void Fetch(network::mojom::URLLoaderFactory* loader_factory,
+             const GURL& origin,
+             FetchCallback callback);
+
+ private:
+  void OnFetchComplete(std::unique_ptr<std::string> response_body);
+  void OnFetchTimeout();
+
+  // A version counter for requirements specs. If data changes on the server,
+  // a new version number is pushed out to prevent that clients continue
+  // using old cached data. This allows setting the HTTP caching expiration to
+  // infinity.
+  int version_;
+
+  // The fetcher determines the URL of the spec file by first hashing the eTLD+1
+  // of |origin| and then taking the first |prefix_length_| bits of the hash
+  // value as part of the file name. (See the code for details.)
+  // |prefix_length_| should always be <= 32 as filenames are limited to the
+  // first 4 bytes of the hash prefix.
+  size_t prefix_length_;
+
+  // Timeout in milliseconds after which any ongoing fetch operation is
+  // canceled.
+  int timeout_;
+
+  // Origin for which a spec is fetched. Only set while fetching is in progress
+  // and the callback has not been called.
+  GURL origin_;
+
+  std::unique_ptr<network::SimpleURLLoader> url_loader_;
+
+  // Callback to be called if the network request resolves or is aborted.
+  FetchCallback callback_;
+
+  // Timer to kill pending downloads after |timeout_|.
+  base::OneShotTimer download_timer_;
+
+  DISALLOW_COPY_AND_ASSIGN(PasswordRequirementsSpecFetcher);
+};
+
+}  // namespace autofill
+
+#endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_PASSWORD_REQUIREMENTS_SPEC_FETCHER_H_
diff --git a/components/autofill/core/browser/password_requirements_spec_fetcher_unittest.cc b/components/autofill/core/browser/password_requirements_spec_fetcher_unittest.cc
new file mode 100644
index 0000000..2c42ff0
--- /dev/null
+++ b/components/autofill/core/browser/password_requirements_spec_fetcher_unittest.cc
@@ -0,0 +1,170 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/autofill/core/browser/password_requirements_spec_fetcher.h"
+
+#include "base/logging.h"
+#include "base/test/bind_test_util.h"
+#include "base/test/scoped_task_environment.h"
+#include "components/autofill/core/browser/proto/password_requirements.pb.h"
+#include "services/network/test/test_url_loader_factory.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace autofill {
+
+namespace {
+
+// URL prefix for spec requests.
+#define SERVER_URL "https://www.gstatic.com/chrome/password_requirements/"
+
+TEST(PasswordRequirementsSpecFetcherTest, FetchData) {
+  // An empty spec is returned for all error cases (time outs, server responding
+  // with anything but HTTP_OK).
+  PasswordRequirementsSpec empty_spec;
+
+  // TODO(crbug.com/846694): As there is currently no wire-format for files
+  // that contain multiple specs, the HTTP response from the server is ignored
+  // and any HTTP_OK response generates a PasswordRequirementsSpec with a magic
+  // value of "min_length = 17". Once the wire-format is defined, this should
+  // be updated.
+  constexpr char kSuccessfulResponseContent[] = "Foobar";
+  PasswordRequirementsSpec success_spec;
+  success_spec.set_min_length(17);
+
+  // If this magic timeout value is set, simulate a timeout.
+  const int kMagicTimeout = 10;
+
+  struct {
+    // Name of the test for log output.
+    const char* test_name;
+
+    // Origin for which the spec is fetched.
+    const char* origin;
+
+    // Current configuration that would be set via Finch.
+    int generation = 1;
+    int prefix_length = 32;
+    int timeout = 1000;
+
+    // Handler for the spec requests.
+    const char* requested_url;
+    const char* response_content;
+    net::HttpStatusCode response_status = net::HTTP_OK;
+
+    // Expected spec.
+    PasswordRequirementsSpec* expected_spec;
+  } tests[] = {
+      {
+          .test_name = "Business as usual",
+          .origin = "https://www.example.com",
+          // See echo -n example.com | md5sum | cut -b 1-4
+          .requested_url = SERVER_URL "1/5aba",
+          .response_content = kSuccessfulResponseContent,
+          .expected_spec = &success_spec,
+      },
+      {
+          .test_name = "Parts before the eTLD+1 don't matter",
+          // m.example.com instead of www.example.com creates the same hash
+          // prefix.
+          .origin = "https://m.example.com",
+          .requested_url = SERVER_URL "1/5aba",
+          .response_content = kSuccessfulResponseContent,
+          .expected_spec = &success_spec,
+      },
+      {
+          .test_name = "The generation is encoded in the url",
+          .origin = "https://www.example.com",
+          // Here the test differs from the default:
+          .generation = 2,
+          .requested_url = SERVER_URL "2/5aba",
+          .response_content = kSuccessfulResponseContent,
+          .expected_spec = &success_spec,
+      },
+      {
+          .test_name = "Shorter prefixes are reflected in the URL",
+          .origin = "https://m.example.com",
+          // The prefix "5abc" starts with 0b01011010. If the prefix is limited
+          // to the first 3 bits, b0100 = 0x4 remains and the rest is zeroed
+          // out.
+          .prefix_length = 3,
+          .requested_url = SERVER_URL "1/4000",
+          .response_content = kSuccessfulResponseContent,
+          .expected_spec = &success_spec,
+      },
+      {
+          .test_name = "Simulate a 404 response",
+          .origin = "https://www.example.com",
+          .requested_url = SERVER_URL "1/5aba",
+          .response_content = "Not found",
+          // If a file is not found on the server, the spec should be empty.
+          .response_status = net::HTTP_NOT_FOUND,
+          .expected_spec = &empty_spec,
+      },
+      {
+          .test_name = "Simulate a timeout",
+          .origin = "https://www.example.com",
+          // This simulates a timeout.
+          .timeout = kMagicTimeout,
+          // This makes sure that the server does not respond by itself as
+          // TestURLLoaderFactory reacts as if a response has been added to
+          // a URL.
+          .requested_url = SERVER_URL "dont_respond",
+          .response_content = kSuccessfulResponseContent,
+          .expected_spec = &empty_spec,
+      },
+      {
+          .test_name = "Zero prefix",
+          .origin = "https://www.example.com",
+          // A zero prefix will be the hard-coded Finch default and should work.
+          .prefix_length = 0,
+          .requested_url = SERVER_URL "1/0000",
+          .response_content = kSuccessfulResponseContent,
+          .expected_spec = &success_spec,
+      },
+  };
+
+  for (const auto& test : tests) {
+    SCOPED_TRACE(test.test_name);
+
+    base::test::ScopedTaskEnvironment environment(
+        base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME);
+    network::TestURLLoaderFactory loader_factory;
+    loader_factory.AddResponse(test.requested_url, test.response_content,
+                               test.response_status);
+
+    // Data to be collected from the callback.
+    bool callback_called = false;
+    PasswordRequirementsSpec returned_spec;
+
+    // Trigger the network request and record data of the callback.
+    PasswordRequirementsSpecFetcher fetcher(test.generation, test.prefix_length,
+                                            test.timeout);
+    auto callback =
+        base::BindLambdaForTesting([&](const PasswordRequirementsSpec& spec) {
+          callback_called = true;
+          returned_spec = spec;
+        });
+    fetcher.Fetch(&loader_factory, GURL(test.origin), callback);
+
+    environment.RunUntilIdle();
+
+    if (test.timeout == kMagicTimeout) {
+      // Make sure that the request takes longer than the timeout and gets
+      // killed by the timer.
+      environment.FastForwardBy(
+          base::TimeDelta::FromMilliseconds(2 * kMagicTimeout));
+      environment.RunUntilIdle();
+    }
+
+    ASSERT_TRUE(callback_called);
+    EXPECT_EQ(test.expected_spec->SerializeAsString(),
+              returned_spec.SerializeAsString());
+  }
+}
+
+#undef SERVER_URL
+
+}  // namespace
+
+}  // namespace autofill
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc
index b45d05b..3127fe6 100644
--- a/components/autofill/core/common/autofill_features.cc
+++ b/components/autofill/core/common/autofill_features.cc
@@ -45,6 +45,10 @@
     "AutofillEnforceMinRequiredFieldsForUpload",
     base::FEATURE_ENABLED_BY_DEFAULT};
 
+// Controls whether the manual fill fallback will be present.
+const base::Feature kAutofillManualFallback{"AutofillManualFallback",
+                                            base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Controls whether credit card suggestions are made on insecure pages.
 const base::Feature kAutofillRequireSecureCreditCardContext{
     "AutofillRequireSecureCreditCardContext", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/components/autofill/core/common/autofill_features.h b/components/autofill/core/common/autofill_features.h
index 50e99544..700e2bdc 100644
--- a/components/autofill/core/common/autofill_features.h
+++ b/components/autofill/core/common/autofill_features.h
@@ -18,6 +18,7 @@
 extern const base::Feature kAutofillEnforceMinRequiredFieldsForHeuristics;
 extern const base::Feature kAutofillEnforceMinRequiredFieldsForQuery;
 extern const base::Feature kAutofillEnforceMinRequiredFieldsForUpload;
+extern const base::Feature kAutofillManualFallback;
 extern const base::Feature kAutofillRequireSecureCreditCardContext;
 extern const base::Feature kAutofillRestrictUnownedFieldsToFormlessCheckout;
 extern const base::Feature kAutofillSendExperimentIdsInPaymentsRPCs;
diff --git a/components/browser_sync/profile_sync_service.cc b/components/browser_sync/profile_sync_service.cc
index 93cbffb..163e8da 100644
--- a/components/browser_sync/profile_sync_service.cc
+++ b/components/browser_sync/profile_sync_service.cc
@@ -1372,9 +1372,12 @@
       };
 
   static_assert(41 == syncer::MODEL_TYPE_COUNT,
-                "If adding a user selectable type, update "
-                "UserSelectableSyncType in user_selectable_sync_type.h and "
-                "histograms.xml.");
+                "If adding a user selectable type (that is exposed to the user "
+                "via the sync preferences UI), update "
+                "1) The user_selectable_types[] above;"
+                "2) UserSelectableSyncType in user_selectable_sync_type.h and "
+                "histograms.xml; "
+                "3) UserSelectableTypes() in sync/syncable/model_type.h.");
 
   if (!sync_everything) {
     const syncer::ModelTypeSet current_types = GetPreferredDataTypes();
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn
index 02870147..a61402c 100644
--- a/components/cronet/android/BUILD.gn
+++ b/components/cronet/android/BUILD.gn
@@ -300,6 +300,8 @@
     "java/src/org/chromium/net/impl/VersionSafeCallbacks.java",
   ]
 
+  # Adding deps here won't include those deps in the cronet_impl_common_java.jar.
+  # Please add to cronet_impl_common_java_deps_to_package instead.
   deps = [
     ":cronet_api_java",
     "//third_party/android_tools:android_support_annotations_java",
@@ -632,6 +634,16 @@
   ]
 }
 
+cronet_javatests_deps_to_package = [
+  ":cronet_test_apk_java",
+  "//base:base_java",
+  "//base:base_java_test_support",
+  "//net/android:embedded_test_server_aidl_java",
+  "//net/android:net_java",
+  "//net/android:net_java_test_support",
+  "//url:url_java",
+]
+
 android_library("cronet_javatests") {
   testonly = true
 
@@ -675,17 +687,15 @@
     "test/javatests/src/org/chromium/net/UrlResponseInfoTest.java",
   ]
 
+  # Adding deps here won't include those deps in the cronet_tests_java.jar.
+  # Please add to cronet_javatests_deps_to_package instead.
   deps = [
     ":cronet_api_java",
     ":cronet_impl_all_java",
-    ":cronet_test_apk_java",
-    "//base:base_java",
-    "//base:base_java_test_support",
-    "//net/android:net_java",
-    "//net/android:net_java_test_support",
     "//third_party/android_support_test_runner:runner_java",
     "//third_party/junit",
   ]
+  deps += cronet_javatests_deps_to_package
   data = [
     "//components/cronet/test/data/",
   ]
@@ -916,6 +926,8 @@
   deps += cronet_impl_native_java_deps_to_package
 
   sources = []
+
+  # Extract pre-desugared jar for each dependency.
   foreach(dep, deps) {
     sources += [ get_label_info(dep, "target_gen_dir") + "/" +
                  get_label_info(dep, "name") + ".javac.jar" ]
@@ -982,6 +994,8 @@
   deps += cronet_impl_common_java_deps_to_package
 
   sources = []
+
+  # Extract pre-desugared jar for each dependency.
   foreach(dep, deps) {
     sources += [ get_label_info(dep, "target_gen_dir") + "/" +
                  get_label_info(dep, "name") + ".javac.jar" ]
@@ -1020,6 +1034,9 @@
   ]
 }
 
+cronet_test_deps = [ ":cronet_javatests" ]
+cronet_test_deps += cronet_javatests_deps_to_package
+
 action("extract_cronet_test_jars") {
   # extract_from_jars.py deletes the target directory before extracting.
   script = "//components/cronet/tools/extract_from_jars.py"
@@ -1027,17 +1044,15 @@
   testonly = true
 
   sources = [
-    "$root_out_dir/lib.java/base/base_java.jar",
-    "$root_out_dir/lib.java/base/base_java_test_support.jar",
-    "$root_out_dir/lib.java/components/cronet/android/cronet_javatests.jar",
-    "$root_out_dir/lib.java/components/cronet/android/cronet_test_apk_java.jar",
-    "$root_out_dir/lib.java/net/android/embedded_test_server_aidl_java.jar",
-    "$root_out_dir/lib.java/net/android/net_java.jar",
-    "$root_out_dir/lib.java/net/android/net_java_test_support.jar",
-    "$root_out_dir/lib.java/url/url_java.jar",
     NETTY4_JAR_FILE,
   ]
 
+  # Extract pre-desugared jar for each cronet_test_deps.
+  foreach(dep, cronet_test_deps) {
+    sources += [ get_label_info(dep, "target_gen_dir") + "/" +
+                 get_label_info(dep, "name") + ".javac.jar" ]
+  }
+
   _stamp_file = "$target_gen_dir/$target_name.stamp"
   outputs = [
     _stamp_file,
@@ -1056,16 +1071,9 @@
   ]
 
   deps = [
-    ":cronet_javatests",
-    ":cronet_test_apk_java",
-    "//base:base_java",
-    "//base:base_java_test_support",
-    "//net/android:embedded_test_server_aidl_java",
-    "//net/android:net_java",
-    "//net/android:net_java_test_support",
     "//third_party/netty4:netty_all_java",
-    "//url:url_java",
   ]
+  deps += cronet_test_deps
 }
 
 action("repackage_extracted_test_jars") {
diff --git a/components/cryptauth/fake_secure_channel.cc b/components/cryptauth/fake_secure_channel.cc
index 9fbe29c8..edc5a50 100644
--- a/components/cryptauth/fake_secure_channel.cc
+++ b/components/cryptauth/fake_secure_channel.cc
@@ -12,9 +12,8 @@
                                             const std::string& payload)
     : feature(feature), payload(payload) {}
 
-FakeSecureChannel::FakeSecureChannel(std::unique_ptr<Connection> connection,
-                                     CryptAuthService* cryptauth_service)
-    : SecureChannel(std::move(connection), cryptauth_service) {}
+FakeSecureChannel::FakeSecureChannel(std::unique_ptr<Connection> connection)
+    : SecureChannel(std::move(connection)) {}
 
 FakeSecureChannel::~FakeSecureChannel() {}
 
diff --git a/components/cryptauth/fake_secure_channel.h b/components/cryptauth/fake_secure_channel.h
index 0ec559f..5213590 100644
--- a/components/cryptauth/fake_secure_channel.h
+++ b/components/cryptauth/fake_secure_channel.h
@@ -10,13 +10,10 @@
 
 namespace cryptauth {
 
-class CryptAuthService;
-
 // A fake implementation of SecureChannel to use in tests.
 class FakeSecureChannel : public SecureChannel {
  public:
-  FakeSecureChannel(std::unique_ptr<Connection> connection,
-                    CryptAuthService* cryptauth_service);
+  FakeSecureChannel(std::unique_ptr<Connection> connection);
   ~FakeSecureChannel() override;
 
   struct SentMessage {
diff --git a/components/cryptauth/proto/cryptauth_api.proto b/components/cryptauth/proto/cryptauth_api.proto
index 5aebfb3..1293019 100644
--- a/components/cryptauth/proto/cryptauth_api.proto
+++ b/components/cryptauth/proto/cryptauth_api.proto
@@ -333,9 +333,9 @@
   // A list of multi-device software features supported by the device.
   repeated SoftwareFeature supported_software_features = 411;
 
-  // A list of multi-device software features currently enabled (active) on the
-  // device.
-  repeated SoftwareFeature enabled_software_features = 412;
+  // Previously, field 412 referred to "enabled_software_features". However,
+  // this is not an intrinsic property of a device type, so this field has been
+  // removed.
 
   // The enrollment session id this is sent with
   optional bytes enrollment_session_id = 1000;
diff --git a/components/cryptauth/secure_channel.cc b/components/cryptauth/secure_channel.cc
index 57b540c..1b6746c 100644
--- a/components/cryptauth/secure_channel.cc
+++ b/components/cryptauth/secure_channel.cc
@@ -9,7 +9,6 @@
 #include "base/bind.h"
 #include "base/memory/ptr_util.h"
 #include "chromeos/components/proximity_auth/logging/logging.h"
-#include "components/cryptauth/cryptauth_service.h"
 #include "components/cryptauth/secure_message_delegate_impl.h"
 #include "components/cryptauth/wire_message.h"
 
@@ -20,13 +19,11 @@
 
 // static
 std::unique_ptr<SecureChannel> SecureChannel::Factory::NewInstance(
-    std::unique_ptr<Connection> connection,
-    CryptAuthService* cryptauth_service) {
+    std::unique_ptr<Connection> connection) {
   if (!factory_instance_) {
     factory_instance_ = new Factory();
   }
-  return factory_instance_->BuildInstance(std::move(connection),
-                                          cryptauth_service);
+  return factory_instance_->BuildInstance(std::move(connection));
 }
 
 // static
@@ -35,10 +32,8 @@
 }
 
 std::unique_ptr<SecureChannel> SecureChannel::Factory::BuildInstance(
-    std::unique_ptr<Connection> connection,
-    CryptAuthService* cryptauth_service) {
-  return base::WrapUnique(
-      new SecureChannel(std::move(connection), cryptauth_service));
+    std::unique_ptr<Connection> connection) {
+  return base::WrapUnique(new SecureChannel(std::move(connection)));
 }
 
 // static
@@ -68,11 +63,9 @@
 
 SecureChannel::PendingMessage::~PendingMessage() {}
 
-SecureChannel::SecureChannel(std::unique_ptr<Connection> connection,
-                             CryptAuthService* cryptauth_service)
+SecureChannel::SecureChannel(std::unique_ptr<Connection> connection)
     : status_(Status::DISCONNECTED),
       connection_(std::move(connection)),
-      cryptauth_service_(cryptauth_service),
       weak_ptr_factory_(this) {
   connection_->AddObserver(this);
 }
diff --git a/components/cryptauth/secure_channel.h b/components/cryptauth/secure_channel.h
index 201aa22..32267af 100644
--- a/components/cryptauth/secure_channel.h
+++ b/components/cryptauth/secure_channel.h
@@ -17,8 +17,6 @@
 
 namespace cryptauth {
 
-class CryptAuthService;
-
 // An authenticated bi-directional channel for exchanging messages with remote
 // devices. |SecureChannel| manages a |Connection| by initializing it and
 // authenticating it via a security handshake once the connection has occurred.
@@ -78,15 +76,13 @@
   class Factory {
    public:
     static std::unique_ptr<SecureChannel> NewInstance(
-        std::unique_ptr<Connection> connection,
-        CryptAuthService* cryptauth_service);
+        std::unique_ptr<Connection> connection);
 
     static void SetInstanceForTesting(Factory* factory);
 
    protected:
     virtual std::unique_ptr<SecureChannel> BuildInstance(
-        std::unique_ptr<Connection> connection,
-        CryptAuthService* cryptauth_service);
+        std::unique_ptr<Connection> connection);
 
    private:
     static Factory* factory_instance_;
@@ -123,8 +119,7 @@
   void OnGattCharacteristicsNotAvailable() override;
 
  protected:
-  SecureChannel(std::unique_ptr<Connection> connection,
-                CryptAuthService* cryptauth_service);
+  SecureChannel(std::unique_ptr<Connection> connection);
 
   void NotifyGattCharacteristicsNotAvailable();
 
@@ -160,7 +155,6 @@
       std::unique_ptr<SecureContext> secure_context);
 
   std::unique_ptr<Connection> connection_;
-  CryptAuthService* cryptauth_service_;  // Outlives this instance.
   std::unique_ptr<Authenticator> authenticator_;
   std::unique_ptr<SecureContext> secure_context_;
   base::queue<std::unique_ptr<PendingMessage>> queued_messages_;
diff --git a/components/cryptauth/secure_channel_unittest.cc b/components/cryptauth/secure_channel_unittest.cc
index 8aeb0a5..a02fa5f 100644
--- a/components/cryptauth/secure_channel_unittest.cc
+++ b/components/cryptauth/secure_channel_unittest.cc
@@ -12,7 +12,6 @@
 #include "base/memory/weak_ptr.h"
 #include "components/cryptauth/fake_authenticator.h"
 #include "components/cryptauth/fake_connection.h"
-#include "components/cryptauth/fake_cryptauth_service.h"
 #include "components/cryptauth/fake_secure_context.h"
 #include "components/cryptauth/fake_secure_message_delegate.h"
 #include "components/cryptauth/remote_device_ref.h"
@@ -185,14 +184,12 @@
 
     fake_secure_context_ = nullptr;
 
-    fake_cryptauth_service_ = std::make_unique<FakeCryptAuthService>();
-
     fake_connection_ =
         new FakeConnection(test_device_, /* should_auto_connect */ false);
 
     EXPECT_FALSE(fake_connection_->observers().size());
-    secure_channel_ = base::WrapUnique(new SecureChannel(
-        base::WrapUnique(fake_connection_), fake_cryptauth_service_.get()));
+    secure_channel_ =
+        base::WrapUnique(new SecureChannel(base::WrapUnique(fake_connection_)));
     EXPECT_EQ(static_cast<size_t>(1), fake_connection_->observers().size());
     EXPECT_EQ(secure_channel_.get(), fake_connection_->observers()[0]);
 
@@ -375,8 +372,6 @@
   std::unique_ptr<FakeSecureMessageDelegateFactory>
       fake_secure_message_delegate_factory_;
 
-  std::unique_ptr<FakeCryptAuthService> fake_cryptauth_service_;
-
   // Owned by secure_channel_ once authentication has completed successfully.
   FakeSecureContext* fake_secure_context_;
 
diff --git a/components/nacl/loader/BUILD.gn b/components/nacl/loader/BUILD.gn
index c5de97b..9a61de6b 100644
--- a/components/nacl/loader/BUILD.gn
+++ b/components/nacl/loader/BUILD.gn
@@ -158,6 +158,13 @@
       }
     }
 
+    # The only symbols that nacl_helper needs to export are those specified by
+    # its direct dependencies, so -rdynamic would only serve to unnecessarily
+    # increase the binary size.
+    if (is_desktop_linux) {
+      configs -= [ "//build/config/linux:export_dynamic" ]
+    }
+
     data_deps = [
       "//native_client/src/trusted/service_runtime/linux:bootstrap",
     ]
diff --git a/components/password_manager/core/browser/password_autofill_manager.cc b/components/password_manager/core/browser/password_autofill_manager.cc
index 3911c701..1bea801 100644
--- a/components/password_manager/core/browser/password_autofill_manager.cc
+++ b/components/password_manager/core/browser/password_autofill_manager.cc
@@ -320,7 +320,6 @@
 
 void PasswordAutofillManager::DidNavigateMainFrame() {
   login_to_password_info_.clear();
-  did_show_form_not_secure_warning_ = false;
 }
 
 bool PasswordAutofillManager::FillSuggestionForTest(
diff --git a/components/password_manager/core/browser/password_autofill_manager.h b/components/password_manager/core/browser/password_autofill_manager.h
index e830ca7..97df4a51 100644
--- a/components/password_manager/core/browser/password_autofill_manager.h
+++ b/components/password_manager/core/browser/password_autofill_manager.h
@@ -122,10 +122,6 @@
   // The driver that owns |this|.
   PasswordManagerDriver* password_manager_driver_;
 
-  // True if the Form-Not-Secure warning has been shown on the current
-  // navigation. Used for metrics.
-  bool did_show_form_not_secure_warning_ = false;
-
   // Context in which the "Show all saved passwords" fallback was shown.
   metrics_util::ShowAllSavedPasswordsContext
       show_all_saved_passwords_shown_context_ =
diff --git a/components/pdf/renderer/pdf_accessibility_tree_browsertest.cc b/components/pdf/renderer/pdf_accessibility_tree_browsertest.cc
index a727b4cf..f160c16 100644
--- a/components/pdf/renderer/pdf_accessibility_tree_browsertest.cc
+++ b/components/pdf/renderer/pdf_accessibility_tree_browsertest.cc
@@ -58,6 +58,14 @@
       const base::SharedMemoryHandle& handle) override {
     return base::SharedMemoryHandle();
   }
+  base::UnsafeSharedMemoryRegion ShareUnsafeSharedMemoryRegionWithRemote(
+      const base::UnsafeSharedMemoryRegion& region) override {
+    return base::UnsafeSharedMemoryRegion();
+  }
+  base::ReadOnlySharedMemoryRegion ShareReadOnlySharedMemoryRegionWithRemote(
+      const base::ReadOnlySharedMemoryRegion& region) override {
+    return base::ReadOnlySharedMemoryRegion();
+  }
   bool IsRunningInProcess() const override { return false; }
   std::string GetPluginName() const override { return std::string(); }
   void SetToExternalPluginHost() override {}
diff --git a/components/policy/core/browser/configuration_policy_handler.cc b/components/policy/core/browser/configuration_policy_handler.cc
index aa30a20..4b0a7771 100644
--- a/components/policy/core/browser/configuration_policy_handler.cc
+++ b/components/policy/core/browser/configuration_policy_handler.cc
@@ -11,13 +11,11 @@
 
 #include "base/callback.h"
 #include "base/files/file_path.h"
-#include "base/json/json_reader.h"
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/strings/string16.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
 #include "components/policy/core/browser/policy_error_map.h"
 #include "components/policy/core/common/policy_map.h"
 #include "components/prefs/pref_value_map.h"
@@ -376,7 +374,8 @@
   DCHECK(schema_.valid());
 }
 
-SchemaValidatingPolicyHandler::~SchemaValidatingPolicyHandler() {}
+SchemaValidatingPolicyHandler::~SchemaValidatingPolicyHandler() {
+}
 
 const char* SchemaValidatingPolicyHandler::policy_name() const {
   return policy_name_;
@@ -439,9 +438,11 @@
                                     strategy),
       pref_path_(pref_path),
       allow_recommended_(recommended_permission == RECOMMENDED_ALLOWED),
-      allow_mandatory_(mandatory_permission == MANDATORY_ALLOWED) {}
+      allow_mandatory_(mandatory_permission == MANDATORY_ALLOWED) {
+}
 
-SimpleSchemaValidatingPolicyHandler::~SimpleSchemaValidatingPolicyHandler() {}
+SimpleSchemaValidatingPolicyHandler::~SimpleSchemaValidatingPolicyHandler() {
+}
 
 bool SimpleSchemaValidatingPolicyHandler::CheckPolicySettings(
     const PolicyMap& policies,
@@ -471,136 +472,6 @@
     prefs->SetValue(pref_path_, value->CreateDeepCopy());
 }
 
-// SimpleJsonStringSchemaValidatingPolicyHandler implementation ----------------
-
-SimpleJsonStringSchemaValidatingPolicyHandler::
-    SimpleJsonStringSchemaValidatingPolicyHandler(
-        const char* policy_name,
-        const char* pref_path,
-        Schema schema,
-        SchemaOnErrorStrategy strategy,
-        RecommendedPermission recommended_permission,
-        MandatoryPermission mandatory_permission,
-        bool allow_errors_in_embedded_json)
-    : SimpleSchemaValidatingPolicyHandler(policy_name,
-                                          pref_path,
-                                          schema,
-                                          strategy,
-                                          recommended_permission,
-                                          mandatory_permission),
-      allow_errors_in_embedded_json_(allow_errors_in_embedded_json) {}
-
-SimpleJsonStringSchemaValidatingPolicyHandler::
-    ~SimpleJsonStringSchemaValidatingPolicyHandler() {}
-
-bool SimpleJsonStringSchemaValidatingPolicyHandler::CheckPolicySettings(
-    const PolicyMap& policies,
-    PolicyErrorMap* errors) {
-  const base::Value* root_value = policies.GetValue(policy_name());
-  if (!root_value)
-    return true;
-
-  if (IsListSchema())
-    return CheckListOfJsonStrings(root_value, errors);
-
-  return CheckSingleJsonString(root_value, errors);
-}
-
-bool SimpleJsonStringSchemaValidatingPolicyHandler::CheckSingleJsonString(
-    const base::Value* root_value,
-    PolicyErrorMap* errors) {
-  if (!root_value->is_string()) {
-    if (errors) {
-      errors->AddError(policy_name(), "(ROOT)", IDS_POLICY_TYPE_ERROR,
-                       base::Value::GetTypeName(base::Value::Type::STRING));
-    }
-    return false;
-  }
-  const std::string& json_string = root_value->GetString();
-  return ValidateJsonString(json_string, errors, 0);
-}
-
-bool SimpleJsonStringSchemaValidatingPolicyHandler::CheckListOfJsonStrings(
-    const base::Value* root_value,
-    PolicyErrorMap* errors) {
-  if (!root_value->is_list()) {
-    if (errors) {
-      errors->AddError(policy_name(), "(ROOT)", IDS_POLICY_TYPE_ERROR,
-                       base::Value::GetTypeName(base::Value::Type::LIST));
-    }
-    return false;
-  }
-
-  // We validate every list value, so that if several values have errors, we can
-  // show the users all of the errors insteada of one at a time.
-  bool error_seen = false;
-  const ::base::Value::ListStorage& list = root_value->GetList();
-  for (size_t index = 0; index < list.size(); ++index) {
-    const base::Value& entry = list[index];
-    if (!entry.is_string()) {
-      if (errors) {
-        errors->AddError(policy_name(), index, IDS_POLICY_TYPE_ERROR,
-                         base::Value::GetTypeName(base::Value::Type::STRING));
-      }
-      error_seen |= true;
-      continue;
-    }
-    const std::string& json_string = entry.GetString();
-    if (!ValidateJsonString(json_string, errors, index))
-      error_seen |= true;
-  }
-  return !error_seen;
-}
-
-bool SimpleJsonStringSchemaValidatingPolicyHandler::ValidateJsonString(
-    const std::string& json_string,
-    PolicyErrorMap* errors,
-    int index) {
-  std::string parse_error;
-  std::unique_ptr<base::Value> parsed_value =
-      base::JSONReader::ReadAndReturnError(
-          json_string, base::JSON_ALLOW_TRAILING_COMMAS, nullptr, &parse_error);
-  if (!parse_error.empty()) {
-    // The string contained JSON that could not be parsed.
-    if (errors) {
-      errors->AddError(policy_name(), ErrorPath(index, ""),
-                       IDS_POLICY_INVALID_JSON_ERROR, parse_error);
-    }
-    // Return false - unless we allow JSON errors, in which case, return true.
-    return allow_errors_in_embedded_json_;
-  }
-
-  std::string schema_error;
-  std::string error_path;
-  const Schema json_string_schema =
-      IsListSchema() ? schema_.GetItems() : schema_;
-  bool result = json_string_schema.Validate(*parsed_value, strategy_,
-                                            &error_path, &schema_error);
-  if (!schema_error.empty()) {
-    // The JSON was parsed, but did not match the schema.
-    if (errors) {
-      errors->AddError(policy_name(), ErrorPath(index, error_path),
-                       schema_error);
-    }
-    // Return false - unless we allow JSON errors, in which case, return true.
-    return allow_errors_in_embedded_json_;
-  }
-
-  return result;
-}
-
-std::string SimpleJsonStringSchemaValidatingPolicyHandler::ErrorPath(
-    int index,
-    std::string json_error_path) {
-  if (IsListSchema()) {
-    return json_error_path.empty()
-               ? base::StringPrintf("items[%d]", index)
-               : base::StringPrintf("items[%d].%s", index,
-                                    json_error_path.c_str());
-  }
-  return json_error_path.empty() ? "(ROOT)" : json_error_path;
-}
-
 // LegacyPoliciesDeprecatingPolicyHandler implementation -----------------------
 
 LegacyPoliciesDeprecatingPolicyHandler::LegacyPoliciesDeprecatingPolicyHandler(
diff --git a/components/policy/core/browser/configuration_policy_handler.h b/components/policy/core/browser/configuration_policy_handler.h
index 78a7cfc6..782dc54 100644
--- a/components/policy/core/browser/configuration_policy_handler.h
+++ b/components/policy/core/browser/configuration_policy_handler.h
@@ -327,20 +327,20 @@
                         PolicyErrorMap* errors,
                         std::unique_ptr<base::Value>* output);
 
-  const char* policy_name_;
-  const Schema schema_;
-  const SchemaOnErrorStrategy strategy_;
-
  private:
+  const char* policy_name_;
+  Schema schema_;
+  SchemaOnErrorStrategy strategy_;
+
   DISALLOW_COPY_AND_ASSIGN(SchemaValidatingPolicyHandler);
 };
 
 // Maps policy to pref like SimplePolicyHandler while ensuring that the value
 // set matches the schema. |schema| is the schema used for policies, and
-// |strategy| is the strategy used for schema validation errors.
-// The |recommended_permission| and |mandatory_permission| flags indicate the
-// levels at which the policy can be set. A value set at an unsupported level
-// will be ignored.
+// |strategy| is the strategy used for schema validation errors. The
+// |recommended_permission| and |mandatory_permission| flags indicate the levels
+// at which the policy can be set. A value set at an unsupported level will be
+// ignored.
 class POLICY_EXPORT SimpleSchemaValidatingPolicyHandler
     : public SchemaValidatingPolicyHandler {
  public:
@@ -370,66 +370,6 @@
   DISALLOW_COPY_AND_ASSIGN(SimpleSchemaValidatingPolicyHandler);
 };
 
-// Maps policy to pref like SimplePolicyHandler while ensuring that the value
-// is either a single JSON string or a list of JSON strings, and that when the
-// JSON is parsed it matches the given |schema|.
-// If |allow_errors_in_embedded_json| is true, then errors inside the JSON
-// string only cause warnings, they do not cause validation to fail. However,
-// the value as a whole is still validated by ensuring it is either a single
-// string or a list of strings, whichever is appropriate.
-// NOTE: Do not store new policies using JSON strings! If your policy has a
-// complex schema, store it as a dict of that schema. This has some advantages:
-// - You don't have to parse JSON every time you read it from the pref store.
-// - Nested dicts are simple, but nested JSON strings are complicated.
-class POLICY_EXPORT SimpleJsonStringSchemaValidatingPolicyHandler
-    : public SimpleSchemaValidatingPolicyHandler {
- public:
-  SimpleJsonStringSchemaValidatingPolicyHandler(
-      const char* policy_name,
-      const char* pref_path,
-      Schema schema,
-      SchemaOnErrorStrategy strategy,
-      RecommendedPermission recommended_permission,
-      MandatoryPermission mandatory_permission,
-      bool allow_errors_in_embedded_json);
-  ~SimpleJsonStringSchemaValidatingPolicyHandler() override;
-
-  // SimpleSchemaValidatingPolicyHandler:
-  bool CheckPolicySettings(const PolicyMap& policies,
-                           PolicyErrorMap* errors) override;
-
- private:
-  // Validates |root_value| as a single JSON string that matches the schema.
-  bool CheckSingleJsonString(const base::Value* root_value,
-                             PolicyErrorMap* errors);
-
-  // Validates |root_value| as a list of JSON strings that match the schema.
-  bool CheckListOfJsonStrings(const base::Value* root_value,
-                              PolicyErrorMap* errors);
-
-  // Validates that the given JSON string matches the schema. |index| is the
-  // index of the given string in the list if the root value is a list, and
-  // ignored otherwise. Always returns true if allow_errors_in_embedded_json_
-  // is true, but still adds any errors it finds to |errors|.
-  bool ValidateJsonString(const std::string& json_string,
-                          PolicyErrorMap* errors,
-                          int index);
-
-  // Returns a string describing where an error occurred - |index| describes
-  // which string the error occurred in, and |json_error_path| describes where
-  // it occurred inside a JSON string (this can be empty).
-  std::string ErrorPath(int index, std::string json_error_path);
-
-  // Returns true if the schema root is a list.
-  inline bool IsListSchema() {
-    return schema_.type() == base::Value::Type::LIST;
-  }
-
-  bool allow_errors_in_embedded_json_;
-
-  DISALLOW_COPY_AND_ASSIGN(SimpleJsonStringSchemaValidatingPolicyHandler);
-};
-
 // A policy handler to deprecate multiple legacy policies with a new one.
 // This handler will completely ignore any of legacy policy values if the new
 // one is set.
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index 853c7dc..29a592b 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -140,24 +140,6 @@
 #   be seen by the policy providers either, the 'supported_on' key should be set
 #   to an empty list.
 #
-# Schemas:
-#   All policies have a key 'schema' which describes the schema of the policy.
-#   For many policies this is simply a type eg 'boolean' or 'string', but for
-#   'dict' policies this describes the types of not only the root object, but
-#   also all of its descendants. This schema data is used to validate 'dict'
-#   policies, if a SchemaValidatingPolicyHandler is configured appropriately in
-#   configuration_policy_handler_list_factory.cc
-#
-#   Some policies at first seem to have simple schema e.g. a string or a list of
-#   strings, but those strings are actually JSON strings, and this JSON has
-#   another schema. This type of policy is deprecated. When adding new policies,
-#   make sure the entire schema is described by the 'schema' field and that
-#   there are no strings which contain JSON.
-#   The legacy policies which contain JSON strings have an extra field, the
-#   'validation_schema' which is used to validate not only the schema of the
-#   policy itself, but also the content of the JSON strings inside the policy.
-#   Do not use this field when adding new policies.
-#
 # IDs:
 #   Since a Protocol Buffer definition is generated from this file, unique and
 #   persistent IDs for all fields (but not for groups!) are needed. These are
@@ -3928,16 +3910,6 @@
         'type': 'array',
         'items': { 'type': 'string' },
       },
-      'validation_schema': {
-        'type': 'array',
-        'items': {
-          'type': 'object',
-          'properties': {
-            'pattern': { 'type': 'string'},
-            'filter': { 'type': 'string'}
-          }
-        }
-      },
       'supported_on': ['chrome.*:15-', 'chrome_os:15-'],
       'features': {
         'dynamic_refresh': True,
@@ -3960,16 +3932,6 @@
         'type': 'array',
         'items': { 'type': 'string' },
       },
-      'validation_schema': {
-        'type': 'array',
-        'items': {
-          'type': 'object',
-          'properties': {
-            'pattern': { 'type': 'string'},
-            'filter': { 'type': 'string'}
-          }
-        }
-      },
       'supported_on': ['chrome_os:65-'],
       'device_only': True,
       'features': {
@@ -5460,24 +5422,6 @@
       'name': 'DefaultPrinterSelection',
       'type': 'string',
       'schema': { 'type': 'string' },
-      'validation_schema': {
-        'type': 'object',
-        'properties': {
-          'kind': {
-            'description': 'Whether to limit the search of the matching printer to a specific set of printers.',
-            'type': 'string',
-            'enum': [ 'local', 'cloud' ]
-          },
-          'idPattern': {
-            'description': 'Regular expression to match printer id.',
-            'type': 'string'
-          },
-          'namePattern': {
-            'description': 'Regular expression to match printer display name.',
-            'type': 'string'
-          }
-        }
-      },
       'supported_on': ['chrome.*:48-', 'chrome_os:48-'],
       'features': {
         'dynamic_refresh': True,
@@ -5501,8 +5445,9 @@
         "properties": {
           "kind": {
             "description": "Whether to limit the search of the matching printer to a specific set of printers.",
-            "type": "string",
-            "enum": [ "local", "cloud" ]
+            "type": {
+              "enum": [ "local", "cloud" ]
+            }
           },
           "idPattern": {
             "description": "Regular expression to match printer id.",
diff --git a/components/policy/tools/generate_policy_source.py b/components/policy/tools/generate_policy_source.py
index 86dae634..b83486eb 100755
--- a/components/policy/tools/generate_policy_source.py
+++ b/components/policy/tools/generate_policy_source.py
@@ -78,10 +78,7 @@
     self.supported_chrome_os_management = \
         policy.get('supported_chrome_os_management',
                    ['active_directory', 'google_cloud'])
-
-    # Get the schema to use for validation (this is normally 'schema', but we
-    # override this with the 'validation_schema' field on some legacy policies).
-    self.schema = policy.get('validation_schema', policy['schema'])
+    self.schema = policy.get('schema', {})
     self.has_enterprise_default = 'default_for_enterprise_users' in policy
     if self.has_enterprise_default:
       self.enterprise_default = policy['default_for_enterprise_users']
@@ -128,6 +125,7 @@
                                 (policy['name'], policy['type']))
     self.policy_type, self.protobuf_type, self.policy_protobuf_type, \
         self.restriction_type = PolicyDetails.TYPE_MAP[policy['type']]
+    self.schema = policy['schema']
 
     self.desc = '\n'.join(
         map(str.strip,
diff --git a/components/policy/tools/syntax_check_policy_template_json.py b/components/policy/tools/syntax_check_policy_template_json.py
index 4f7f8da..f2f98a1 100755
--- a/components/policy/tools/syntax_check_policy_template_json.py
+++ b/components/policy/tools/syntax_check_policy_template_json.py
@@ -54,20 +54,6 @@
     'SyncDisabled',
 ]
 
-# List of policies where the 'string' part of the schema is actually a JSON
-# string which has its own schema.
-LEGACY_EMBEDDED_JSON_WHITELIST = [
-  'ArcPolicy',
-  'AutoSelectCertificateForUrls',
-  'DefaultPrinterSelection',
-  'DeviceLoginScreenAutoSelectCertificateForUrls',
-  'DeviceOpenNetworkConfiguration',
-  'OpenNetworkConfiguration',
-  'RemoteAccessHostDebugOverridePolicies',
-  # NOTE: Do not add any new policies to this list! Do not store policies with
-  # complex schemas using stringified JSON - instead, store them as dicts.
-]
-
 class PolicyTemplateChecker(object):
 
   def __init__(self):
@@ -190,35 +176,6 @@
                      'new boolean policies follow the XYZEnabled pattern. ' +
                      'See also http://crbug.com/85687') % policy.get('name'))
 
-      # Checks that the policy doesn't have a validation_schema - the whole
-      # schema should be defined in 'schema'- unless whitelisted as legacy.
-      if (policy.has_key('validation_schema') and
-          policy.get('name') not in LEGACY_EMBEDDED_JSON_WHITELIST):
-        self._Error(('\'validation_schema\' is defined for new policy %s - ' +
-                     'entire schema data should be contained in \'schema\'') %
-                     policy.get('name'))
-
-      # Try to make sure that any policy with a complex schema is storing it as
-      # a 'dict', not embedding it inside JSON strings - unless whitelisted.
-      if (self._AppearsToContainEmbeddedJson(policy.get('example_value')) and
-          policy.get('name') not in LEGACY_EMBEDDED_JSON_WHITELIST):
-        self._Error(('Example value for new policy %s looks like JSON. Do ' +
-                     'not store complex data as stringified JSON - instead, ' +
-                     'store it in a dict and define it in \'schema\'.') %
-                     policy.get('name'))
-
-  # Returns True if the example value for a policy seems to contain JSON
-  # embedded inside a string. Simply checks if strings start with '{', so it
-  # doesn't flag numbers (which are valid JSON) but it does flag both JSON
-  # objects and python objects (regardless of the type of quotes used).
-  def _AppearsToContainEmbeddedJson(self, example_value):
-    if isinstance(example_value, str):
-      return example_value.strip().startswith('{')
-    elif isinstance(example_value, list):
-      return any(self._AppearsToContainEmbeddedJson(v) for v in example_value)
-    elif isinstance(example_value, dict):
-      return any(self._AppearsToContainEmbeddedJson(v)
-          for v in example_value.itervalues())
 
   def _CheckPolicy(self, policy, is_in_group, policy_ids, deleted_policy_ids):
     if not isinstance(policy, dict):
@@ -230,7 +187,7 @@
       if key not in ('name', 'type', 'caption', 'desc', 'device_only',
                      'supported_on', 'label', 'policies', 'items',
                      'example_value', 'features', 'deprecated', 'future',
-                     'id', 'schema', 'validation_schema', 'max_size', 'tags',
+                     'id', 'schema', 'max_size', 'tags',
                      'default_for_enterprise_users',
                      'default_for_managed_devices_doc_only',
                      'arc_support', 'supported_chrome_os_management'):
diff --git a/components/policy_strings.grdp b/components/policy_strings.grdp
index 7c5bf116..3a3d70f 100644
--- a/components/policy_strings.grdp
+++ b/components/policy_strings.grdp
@@ -158,9 +158,6 @@
   <message name="IDS_POLICY_SCHEMA_VALIDATION_ERROR" desc="The text displayed in the status column when the policy value doesn't conform to the policy schema.">
     Schema validation error at "<ph name="ERROR_PATH">$1<ex>AC.Delays.ScreenOff</ex></ph>": <ph name="ERROR">$2<ex>Value is out of range.</ex></ph>
   </message>
-  <message name="IDS_POLICY_INVALID_JSON_ERROR" desc="The text displayed in the status column when the policy value should be a valid JSON string, but it cannot be parsed as JSON.">
-    Error while parsing JSON value: <ph name="ERROR">$1<ex>Line 2, Column 3: Map keys must be quoted.</ex></ph>
-  </message>
   <message name="IDS_POLICY_INVALID_SEARCH_URL_ERROR" desc="The text displayed in the status column when a the URL given for DefaultSearchProviderSearchURL is invalid.">
     Invalid search URL.
   </message>
diff --git a/components/sessions/BUILD.gn b/components/sessions/BUILD.gn
index 5ec556c3..2d4e53b 100644
--- a/components/sessions/BUILD.gn
+++ b/components/sessions/BUILD.gn
@@ -87,6 +87,8 @@
     "core/session_constants.h",
     "core/session_id.cc",
     "core/session_id.h",
+    "core/session_id_generator.cc",
+    "core/session_id_generator.h",
     "core/session_service_commands.cc",
     "core/session_service_commands.h",
     "core/session_types.cc",
@@ -122,6 +124,7 @@
   deps = [
     "//base",
     "//components/keyed_service/core",
+    "//components/prefs",
     "//components/sync",
     "//components/variations",
     "//skia",
@@ -166,6 +169,7 @@
   sources = [
     "core/serialized_navigation_entry_unittest.cc",
     "core/session_backend_unittest.cc",
+    "core/session_id_generator_unittest.cc",
     "core/session_types_unittest.cc",
     "ios/ios_serialized_navigation_builder_unittest.mm",
     "ios/ios_serialized_navigation_driver_unittest.cc",
@@ -185,7 +189,9 @@
   deps = [
     ":test_support",
     "//base/test:test_support",
+    "//components/prefs:test_support",
     "//components/sync",
+    "//testing/gmock",
     "//testing/gtest",
     "//ui/base",  # For page transition types.
     "//url",
diff --git a/components/sessions/core/DEPS b/components/sessions/core/DEPS
index f0bf3d9..f2ecd68b 100644
--- a/components/sessions/core/DEPS
+++ b/components/sessions/core/DEPS
@@ -1,3 +1,4 @@
 include_rules = [
   "+components/keyed_service/core",
+  "+components/prefs",
 ]
diff --git a/components/sessions/core/session_id.cc b/components/sessions/core/session_id.cc
index dcd4921..83d6880 100644
--- a/components/sessions/core/session_id.cc
+++ b/components/sessions/core/session_id.cc
@@ -6,11 +6,11 @@
 
 #include <ostream>
 
-static SessionID::id_type next_id = 1;
+#include "components/sessions/core/session_id_generator.h"
 
 // static
 SessionID SessionID::NewUnique() {
-  return SessionID(next_id++);
+  return sessions::SessionIdGenerator::GetInstance()->NewUnique();
 }
 
 std::ostream& operator<<(std::ostream& out, SessionID id) {
diff --git a/components/sessions/core/session_id.h b/components/sessions/core/session_id.h
index 0941bae..47b2401 100644
--- a/components/sessions/core/session_id.h
+++ b/components/sessions/core/session_id.h
@@ -17,8 +17,8 @@
  public:
   typedef int32_t id_type;
 
-  // Creates a new instance representing an ID that has never been used in the
-  // current session. The same value may be instantiated in future sessions.
+  // Creates a new instance representing an ID that has never been used before
+  // locally (even across browser restarts).
   static SessionID NewUnique();
 
   // Special value representing a null-like, invalid ID. It's the only value
diff --git a/components/sessions/core/session_id_generator.cc b/components/sessions/core/session_id_generator.cc
new file mode 100644
index 0000000..b74b809ca
--- /dev/null
+++ b/components/sessions/core/session_id_generator.cc
@@ -0,0 +1,103 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/sessions/core/session_id_generator.h"
+
+#include "base/bind.h"
+#include "base/rand_util.h"
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/pref_service.h"
+
+namespace sessions {
+namespace {
+
+const char kLastValuePref[] = "session_id_generator_last_value";
+// On startup, we increment the internal counter by |kCautionaryIdPadding| to
+// mitigate issues during ungraceful shutdown, where prefs might not have
+// managed to persist the latest generated session IDs, but other databases
+// (e.g. sync) might have stored those IDs.
+const int kCautionaryIdPadding = 50;
+
+SessionID::id_type DefaultRandGenerator() {
+  return base::RandGenerator(std::numeric_limits<SessionID::id_type>::max());
+}
+
+}  // namespace
+
+// static
+SessionIdGenerator* SessionIdGenerator::GetInstance() {
+  return base::Singleton<SessionIdGenerator>::get();
+}
+
+// static
+void SessionIdGenerator::RegisterPrefs(PrefRegistrySimple* prefs) {
+  prefs->RegisterInt64Pref(kLastValuePref, 0);
+}
+
+void SessionIdGenerator::Init(PrefService* local_state) {
+  DCHECK(local_state);
+  DCHECK(!local_state_);
+  DCHECK_EQ(0, last_value_) << "NewUnique() used before Init()";
+
+  local_state_ = local_state;
+  last_value_ = local_state_->GetInt64(kLastValuePref);
+  if (last_value_ <= 0) {
+    last_value_ = rand_generator_.Run();
+  }
+
+  // Increment by a constant to mitigate issues during ungraceful shutdown,
+  // where prefs might not have managed to persist the latest generated session
+  // IDs, but other databases (e.g. sync) might have stored those IDs.
+  IncrementValueBy(kCautionaryIdPadding);
+}
+
+void SessionIdGenerator::Shutdown() {
+  local_state_ = nullptr;
+  last_value_ = 0;
+}
+
+SessionID SessionIdGenerator::NewUnique() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  // Init() should have been called in production (which initializes
+  // |local_state_|), but for test convenience, we allow operating even without
+  // underlying prefs.
+  if (local_state_) {
+    IncrementValueBy(1);
+    local_state_->SetInt64(kLastValuePref, last_value_);
+  } else {
+    // Test-only path. Will CHECK-fail if Init() is called later.
+    ++last_value_;
+  }
+  DCHECK(SessionID::IsValidValue(last_value_));
+  return SessionID::FromSerializedValue(last_value_);
+}
+
+// static
+std::string SessionIdGenerator::GetLastValuePrefNameForTest() {
+  return kLastValuePref;
+}
+
+void SessionIdGenerator::SetRandomGeneratorForTest(
+    const RandomGenerator& rand_generator) {
+  rand_generator_ = rand_generator;
+}
+
+SessionIdGenerator::SessionIdGenerator()
+    : local_state_(nullptr),
+      last_value_(0),
+      rand_generator_(base::BindRepeating(&DefaultRandGenerator)) {}
+
+SessionIdGenerator::~SessionIdGenerator() {}
+
+void SessionIdGenerator::IncrementValueBy(int increment) {
+  DCHECK_LT(0, increment);
+  DCHECK_LE(0, last_value_);
+  if (last_value_ >
+      std::numeric_limits<SessionID::id_type>::max() - increment) {
+    last_value_ = 0;
+  }
+  last_value_ += increment;
+}
+
+}  // namespace sessions
diff --git a/components/sessions/core/session_id_generator.h b/components/sessions/core/session_id_generator.h
new file mode 100644
index 0000000..9555a59b
--- /dev/null
+++ b/components/sessions/core/session_id_generator.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 COMPONENTS_SESSIONS_CORE_SESSION_ID_GENERATOR_H_
+#define COMPONENTS_SESSIONS_CORE_SESSION_ID_GENERATOR_H_
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/singleton.h"
+#include "base/sequence_checker.h"
+#include "components/sessions/core/session_id.h"
+#include "components/sessions/core/sessions_export.h"
+
+class PrefRegistrySimple;
+class PrefService;
+
+namespace sessions {
+
+class SESSIONS_EXPORT SessionIdGenerator {
+ public:
+  // Returns the singleton instance of this class.
+  static SessionIdGenerator* GetInstance();
+
+  // Register preferences used by this class.
+  static void RegisterPrefs(PrefRegistrySimple* prefs);
+
+  // Initialization of the singleton. Must be called exactly once. |local_state|
+  // must not be null and must exist until Shutdown() is called.
+  void Init(PrefService* local_state);
+  void Shutdown();
+
+  // Creates a new instance representing an ID that has never been used before
+  // locally (even across browser restarts). Must be preceded by Init().
+  SessionID NewUnique();
+
+  // Preference name used to persist the last ID.
+  static std::string GetLastValuePrefNameForTest();
+
+  // Internal random function injection for tests.
+  using RandomGenerator = base::RepeatingCallback<SessionID::id_type()>;
+  void SetRandomGeneratorForTest(const RandomGenerator& rand_generator);
+
+ private:
+  friend struct base::DefaultSingletonTraits<SessionIdGenerator>;
+
+  SessionIdGenerator();
+  ~SessionIdGenerator();
+
+  void IncrementValueBy(int increment);
+
+  SEQUENCE_CHECKER(sequence_checker_);
+  PrefService* local_state_;
+  SessionID::id_type last_value_;
+
+  // Used to override the random number generator for tests.
+  RandomGenerator rand_generator_;
+
+  DISALLOW_COPY_AND_ASSIGN(SessionIdGenerator);
+};
+
+}  // namespace sessions
+
+#endif  // COMPONENTS_SESSIONS_CORE_SESSION_ID_GENERATOR_H_
diff --git a/components/sessions/core/session_id_generator_unittest.cc b/components/sessions/core/session_id_generator_unittest.cc
new file mode 100644
index 0000000..55860406
--- /dev/null
+++ b/components/sessions/core/session_id_generator_unittest.cc
@@ -0,0 +1,161 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/sessions/core/session_id_generator.h"
+
+#include <limits>
+
+#include "base/macros.h"
+#include "base/test/mock_callback.h"
+#include "components/prefs/testing_pref_service.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace sessions {
+namespace {
+
+using testing::Return;
+
+const int kExpectedIdPadding = 50;
+
+class SessionIdGeneratorTest : public testing::Test {
+ protected:
+  SessionIdGeneratorTest() {
+    SessionIdGenerator::RegisterPrefs(prefs_.registry());
+  }
+
+  ~SessionIdGeneratorTest() override {
+    SessionIdGenerator::GetInstance()->Shutdown();
+  }
+
+  void WriteLastValueToPrefs(int64_t value) {
+    prefs_.SetInt64(SessionIdGenerator::GetLastValuePrefNameForTest(), value);
+  }
+
+  int64_t ReadLastValueFromPrefs() {
+    return prefs_.GetInt64(SessionIdGenerator::GetLastValuePrefNameForTest());
+  }
+
+  TestingPrefServiceSimple prefs_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(SessionIdGeneratorTest);
+};
+
+TEST_F(SessionIdGeneratorTest, ShouldGenerateContiguousIds) {
+  SessionIdGenerator* generator = SessionIdGenerator::GetInstance();
+  generator->Init(&prefs_);
+  SessionID session_id1 = generator->NewUnique();
+  SessionID session_id2 = generator->NewUnique();
+  SessionID session_id3 = generator->NewUnique();
+  EXPECT_EQ(session_id2.id(), session_id1.id() + 1);
+  EXPECT_EQ(session_id3.id(), session_id2.id() + 1);
+  EXPECT_EQ(session_id3.id(), ReadLastValueFromPrefs());
+}
+
+TEST_F(SessionIdGeneratorTest, ShouldInitializeWithRandomValue) {
+  base::MockCallback<SessionIdGenerator::RandomGenerator> random_generator;
+  SessionIdGenerator* generator = SessionIdGenerator::GetInstance();
+  generator->SetRandomGeneratorForTest(random_generator.Get());
+
+  EXPECT_CALL(random_generator, Run()).WillOnce(Return(123));
+  generator->Init(&prefs_);
+  EXPECT_EQ(123 + 1 + kExpectedIdPadding, generator->NewUnique().id());
+
+  // Mimic a browser restart with cleared prefs.
+  generator->Shutdown();
+  WriteLastValueToPrefs(-1);
+  EXPECT_CALL(random_generator, Run()).WillOnce(Return(19));
+  generator->Init(&prefs_);
+
+  EXPECT_EQ(19 + 1 + kExpectedIdPadding, generator->NewUnique().id());
+}
+
+TEST_F(SessionIdGeneratorTest, ShouldCornerCasesInRandomFunc) {
+  base::MockCallback<SessionIdGenerator::RandomGenerator> random_generator;
+  SessionIdGenerator* generator = SessionIdGenerator::GetInstance();
+  generator->SetRandomGeneratorForTest(random_generator.Get());
+
+  // Exercise smallest value in range.
+  EXPECT_CALL(random_generator, Run()).WillOnce(Return(0));
+  generator->Init(&prefs_);
+  EXPECT_EQ(0 + 1 + kExpectedIdPadding, generator->NewUnique().id());
+
+  // Exercise maximum value in range.
+  generator->Shutdown();
+  WriteLastValueToPrefs(-1);
+  EXPECT_CALL(random_generator, Run())
+      .WillOnce(Return(std::numeric_limits<SessionID::id_type>::max()));
+  generator->Init(&prefs_);
+  EXPECT_EQ(1 + kExpectedIdPadding, generator->NewUnique().id());
+
+  // Exercise maximum value minus one in range.
+  generator->Shutdown();
+  WriteLastValueToPrefs(-1);
+  EXPECT_CALL(random_generator, Run())
+      .WillOnce(Return(std::numeric_limits<SessionID::id_type>::max() - 1));
+  generator->Init(&prefs_);
+  EXPECT_EQ(1 + kExpectedIdPadding, generator->NewUnique().id());
+
+  // Exercise a random value which is exactly |kExpectedIdPadding| less than
+  // the maximum value in the range.
+  generator->Shutdown();
+  WriteLastValueToPrefs(-1);
+  EXPECT_CALL(random_generator, Run())
+      .WillOnce(Return(std::numeric_limits<SessionID::id_type>::max() -
+                       kExpectedIdPadding));
+  generator->Init(&prefs_);
+  EXPECT_EQ(1, generator->NewUnique().id());
+
+  // Exercise a random value which is |kExpectedIdPadding-1| less than the
+  // maximum value in the range (no overflow expected).
+  generator->Shutdown();
+  WriteLastValueToPrefs(-1);
+  EXPECT_CALL(random_generator, Run())
+      .WillOnce(Return(std::numeric_limits<SessionID::id_type>::max() -
+                       kExpectedIdPadding - 1));
+  generator->Init(&prefs_);
+  EXPECT_EQ(std::numeric_limits<SessionID::id_type>::max(),
+            generator->NewUnique().id());
+}
+
+TEST_F(SessionIdGeneratorTest, ShouldRestoreAndPadLastValueFromPrefs) {
+  WriteLastValueToPrefs(7);
+  SessionIdGenerator* generator = SessionIdGenerator::GetInstance();
+  generator->Init(&prefs_);
+  SessionID session_id = generator->NewUnique();
+  EXPECT_EQ(8 + kExpectedIdPadding, session_id.id());
+  EXPECT_EQ(8 + kExpectedIdPadding, ReadLastValueFromPrefs());
+}
+
+TEST_F(SessionIdGeneratorTest, ShouldHandleOverflowDuringGeneration) {
+  WriteLastValueToPrefs(std::numeric_limits<SessionID::id_type>::max() -
+                        kExpectedIdPadding - 3);
+  SessionIdGenerator* generator = SessionIdGenerator::GetInstance();
+  generator->Init(&prefs_);
+  ASSERT_EQ(std::numeric_limits<SessionID::id_type>::max() - 2,
+            generator->NewUnique().id());
+  EXPECT_EQ(std::numeric_limits<SessionID::id_type>::max() - 1,
+            generator->NewUnique().id());
+  EXPECT_EQ(std::numeric_limits<SessionID::id_type>::max(),
+            generator->NewUnique().id());
+  EXPECT_EQ(1, generator->NewUnique().id());
+}
+
+TEST_F(SessionIdGeneratorTest, ShouldHandleOverflowDuringPadding) {
+  WriteLastValueToPrefs(std::numeric_limits<SessionID::id_type>::max() - 2);
+  SessionIdGenerator* generator = SessionIdGenerator::GetInstance();
+  generator->Init(&prefs_);
+  EXPECT_EQ(kExpectedIdPadding + 1, generator->NewUnique().id());
+}
+
+// Verifies correctness of the test-only codepath.
+TEST(SessionIdGeneratorWithoutInitTest, ShouldStartFromOneAndIncrement) {
+  SessionIdGenerator* generator = SessionIdGenerator::GetInstance();
+  EXPECT_EQ(1, generator->NewUnique().id());
+  EXPECT_EQ(2, generator->NewUnique().id());
+}
+
+}  // namespace
+}  // namespace sessions
diff --git a/components/subresource_filter/core/browser/subresource_filter_features.cc b/components/subresource_filter/core/browser/subresource_filter_features.cc
index ce87045..621f12d1 100644
--- a/components/subresource_filter/core/browser/subresource_filter_features.cc
+++ b/components/subresource_filter/core/browser/subresource_filter_features.cc
@@ -231,9 +231,6 @@
 const base::Feature kSafeBrowsingSubresourceFilter{
     "SubresourceFilter", base::FEATURE_ENABLED_BY_DEFAULT};
 
-const base::Feature kSafeBrowsingSubresourceFilterExperimentalUI{
-    "SubresourceFilterExperimentalUI", base::FEATURE_ENABLED_BY_DEFAULT};
-
 const base::Feature kSafeBrowsingSubresourceFilterConsiderRedirects{
     "SubresourceFilterConsiderRedirects", base::FEATURE_ENABLED_BY_DEFAULT};
 
@@ -360,10 +357,9 @@
       (measurement_rate == 1 || base::RandDouble() < measurement_rate);
 
   // This bit keeps track of BAS enforcement-style logging, not warning logging.
-  state.enable_logging =
-      effective_activation_level == ActivationLevel::ENABLED &&
-      base::FeatureList::IsEnabled(
-          kSafeBrowsingSubresourceFilterExperimentalUI);
+  // TODO(csharrison): Consider removing it since it can be computed directly
+  // from the ActivationLevel.
+  state.enable_logging = effective_activation_level == ActivationLevel::ENABLED;
   return state;
 }
 
diff --git a/components/subresource_filter/core/browser/subresource_filter_features.h b/components/subresource_filter/core/browser/subresource_filter_features.h
index 11d8e3d..9d33b9c 100644
--- a/components/subresource_filter/core/browser/subresource_filter_features.h
+++ b/components/subresource_filter/core/browser/subresource_filter_features.h
@@ -182,9 +182,6 @@
 // The master toggle to enable/disable the Safe Browsing Subresource Filter.
 extern const base::Feature kSafeBrowsingSubresourceFilter;
 
-// Enables the new experimental UI for the Subresource Filter.
-extern const base::Feature kSafeBrowsingSubresourceFilterExperimentalUI;
-
 // Safe Browsing Activation Throttle considers all checks in a redirect chain.
 extern const base::Feature kSafeBrowsingSubresourceFilterConsiderRedirects;
 
diff --git a/components/sync/base/model_type.h b/components/sync/base/model_type.h
index a37d842..d682f34 100644
--- a/components/sync/base/model_type.h
+++ b/components/sync/base/model_type.h
@@ -155,15 +155,6 @@
   LAST_CONTROL_MODEL_TYPE = EXPERIMENTS,
   LAST_REAL_MODEL_TYPE = LAST_CONTROL_MODEL_TYPE,
 
-  // If you are adding a new sync datatype that is exposed to the user via the
-  // sync preferences UI, be sure to update the list in
-  // components/sync/driver/user_selectable_sync_type.h so that the UMA
-  // histograms for sync include your new type.  In this case, be sure to also
-  // update the UserSelectableTypes() definition in
-  // sync/syncable/model_type.cc.
-
-  // Additionally, enum SyncModelTypes and suffix SyncModelType need to be
-  // updated in histograms.xml for all new types.
   MODEL_TYPE_COUNT,
 };
 
diff --git a/components/sync/protocol/proto_value_conversions_unittest.cc b/components/sync/protocol/proto_value_conversions_unittest.cc
index f77018f..e3f0566a 100644
--- a/components/sync/protocol/proto_value_conversions_unittest.cc
+++ b/components/sync/protocol/proto_value_conversions_unittest.cc
@@ -55,18 +55,14 @@
   }
 };
 
-TEST_F(ProtoValueConversionsTest, ProtoChangeCheck) {
-  // If this number changes, that means we added or removed a data
-  // type.  Don't forget to add a unit test for {New
-  // type}SpecificsToValue below.
-  EXPECT_EQ(41, MODEL_TYPE_COUNT);
+static_assert(41 == syncer::MODEL_TYPE_COUNT,
+              "When adding a new type, add a unit test for "
+              "{NewType}SpecificsToValue below.");
 
-  // We'd also like to check if we changed any field in our messages.
-  // However, that's hard to do: sizeof could work, but it's
-  // platform-dependent.  default_instance().ByteSize() won't change
-  // for most changes, since most of our fields are optional.  So we
-  // just settle for comments in the proto files.
-}
+// We'd also like to check if we changed any field in our messages. However,
+// that's hard to do: sizeof could work, but it's platform-dependent.
+// default_instance().ByteSize() won't change for most changes, since most of
+// our fields are optional. So we just settle for comments in the proto files.
 
 TEST_F(ProtoValueConversionsTest, EncryptedDataToValue) {
   TestSpecificsToValue(EncryptedDataToValue);
@@ -365,6 +361,9 @@
 // TODO(akalin): Figure out how to better test EntitySpecificsToValue.
 
 TEST_F(ProtoValueConversionsTest, EntitySpecificsToValue) {
+  static_assert(41 == syncer::MODEL_TYPE_COUNT,
+                "When adding a new type, add its field below.");
+
   sync_pb::EntitySpecifics specifics;
 // Touch the extensions to make sure it shows up in the generated
 // value.
diff --git a/components/sync/syncable/model_type.cc b/components/sync/syncable/model_type.cc
index 36a4b99..f69086e 100644
--- a/components/sync/syncable/model_type.cc
+++ b/components/sync/syncable/model_type.cc
@@ -153,6 +153,14 @@
 static_assert(arraysize(kModelTypeInfoMap) == MODEL_TYPE_COUNT,
               "kModelTypeInfoMap should have MODEL_TYPE_COUNT elements");
 
+static_assert(41 == syncer::MODEL_TYPE_COUNT,
+              "When adding a new type, update enum SyncModelTypes in enums.xml "
+              "and suffix SyncModelType in histograms.xml.");
+
+static_assert(41 == syncer::MODEL_TYPE_COUNT,
+              "When adding a new type, update kAllocatorDumpNameWhitelist in "
+              "base/trace_event/memory_infra_background_whitelist.cc.");
+
 void AddDefaultFieldValue(ModelType type, sync_pb::EntitySpecifics* specifics) {
   switch (type) {
     case UNSPECIFIED:
diff --git a/components/sync_sessions/local_session_event_handler_impl.cc b/components/sync_sessions/local_session_event_handler_impl.cc
index ff72073..cf6ce50 100644
--- a/components/sync_sessions/local_session_event_handler_impl.cc
+++ b/components/sync_sessions/local_session_event_handler_impl.cc
@@ -196,7 +196,9 @@
     // session; the current tabbed windows are now the source of truth.
     session_tracker_->ResetSessionTracking(current_session_tag_);
     current_session->modified_time = base::Time::Now();
-  } else if (option == RELOAD_TABS) {
+  } else {
+    // TODO(mastiz): Investigate if this whole code block should be
+    // conditioned to RELOAD_TABS.
     DVLOG(1) << "Found no tabbed windows. Reloading "
              << current_session->windows.size()
              << " windows from previous session.";
diff --git a/components/sync_sessions/local_session_event_handler_impl_unittest.cc b/components/sync_sessions/local_session_event_handler_impl_unittest.cc
index 38da108..0b6fb36 100644
--- a/components/sync_sessions/local_session_event_handler_impl_unittest.cc
+++ b/components/sync_sessions/local_session_event_handler_impl_unittest.cc
@@ -561,7 +561,12 @@
   EXPECT_CALL(
       *update_mock_batch,
       Put(Pointee(MatchesTab(kSessionTag, kWindowId1, kTabId1, kTabNodeId1,
-                             /*urls=*/{kFoo1, kBaz1}))));
+                             /*urls=*/{kFoo1, kBaz1}))))
+      .Times(2);
+  EXPECT_CALL(
+      *update_mock_batch,
+      Put(Pointee(MatchesTab(kSessionTag, kWindowId2, kTabId2, kTabNodeId2,
+                             /*urls=*/{kBar1}))));
   EXPECT_CALL(*update_mock_batch, Commit());
 
   EXPECT_CALL(mock_delegate_, CreateLocalSessionWriteBatch())
diff --git a/content/browser/background_fetch/background_fetch_data_manager_unittest.cc b/content/browser/background_fetch/background_fetch_data_manager_unittest.cc
index e554be2..8e866b9 100644
--- a/content/browser/background_fetch/background_fetch_data_manager_unittest.cc
+++ b/content/browser/background_fetch/background_fetch_data_manager_unittest.cc
@@ -1113,6 +1113,78 @@
   EXPECT_EQ(settled_fetches.size(), requests.size());
 }
 
+TEST_P(BackgroundFetchDataManagerTest, GetSettledFetchesFromCache) {
+  // This test only applies to persistent storage.
+  if (registration_storage_ ==
+      BackgroundFetchRegistrationStorage::kNonPersistent)
+    return;
+
+  int64_t sw_id = RegisterServiceWorker();
+  ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
+
+  BackgroundFetchRegistrationId registration_id(
+      sw_id, origin(), kExampleDeveloperId, kExampleUniqueId);
+  ServiceWorkerFetchRequest request1;
+  request1.url = GURL(origin().GetURL().spec() + "1");
+  ServiceWorkerFetchRequest request2;
+  request2.url = GURL(origin().GetURL().spec() + "2");
+
+  BackgroundFetchOptions options;
+  blink::mojom::BackgroundFetchError error;
+  CreateRegistration(registration_id, {request1, request2}, options, &error);
+  EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+
+  bool succeeded = false;
+  std::vector<BackgroundFetchSettledFetch> settled_fetches;
+  // Nothing is downloaded yet.
+  GetSettledFetchesForRegistration(registration_id, &error, &succeeded,
+                                   &settled_fetches);
+  EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+  EXPECT_TRUE(succeeded);
+  EXPECT_EQ(settled_fetches.size(), 0u);
+
+  scoped_refptr<BackgroundFetchRequestInfo> request_info;
+  PopNextRequest(registration_id, &request_info);
+  ASSERT_TRUE(request_info);
+  AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
+                                                 true /* success */);
+  MarkRequestAsComplete(registration_id, request_info.get());
+
+  GetSettledFetchesForRegistration(registration_id, &error, &succeeded,
+                                   &settled_fetches);
+  EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+  EXPECT_TRUE(succeeded);
+  EXPECT_EQ(settled_fetches.size(), 1u);
+
+  PopNextRequest(registration_id, &request_info);
+  ASSERT_TRUE(request_info);
+  AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get(),
+                                                 true /* success */);
+  MarkRequestAsComplete(registration_id, request_info.get());
+
+  GetSettledFetchesForRegistration(registration_id, &error, &succeeded,
+                                   &settled_fetches);
+  EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+  EXPECT_TRUE(succeeded);
+  ASSERT_EQ(settled_fetches.size(), 2u);
+
+  // Sanity check that the responses are written to / read from the cache.
+  EXPECT_TRUE(MatchCache(request1));
+  EXPECT_TRUE(MatchCache(request2));
+  EXPECT_EQ(settled_fetches[0].response.cache_storage_cache_name,
+            kExampleUniqueId);
+  EXPECT_EQ(settled_fetches[1].response.cache_storage_cache_name,
+            kExampleUniqueId);
+
+  RestartDataManagerFromPersistentStorage();
+
+  GetSettledFetchesForRegistration(registration_id, &error, &succeeded,
+                                   &settled_fetches);
+  EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE);
+  EXPECT_TRUE(succeeded);
+  EXPECT_EQ(settled_fetches.size(), 2u);
+}
+
 TEST_P(BackgroundFetchDataManagerTest, GetNumCompletedRequests) {
   int64_t sw_id = RegisterServiceWorker();
   ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id);
diff --git a/content/browser/background_fetch/storage/get_settled_fetches_task.cc b/content/browser/background_fetch/storage/get_settled_fetches_task.cc
index 4bacc35..ef7941f 100644
--- a/content/browser/background_fetch/storage/get_settled_fetches_task.cc
+++ b/content/browser/background_fetch/storage/get_settled_fetches_task.cc
@@ -5,8 +5,8 @@
 #include "content/browser/background_fetch/storage/get_settled_fetches_task.h"
 
 #include "base/barrier_closure.h"
-#include "content/browser/background_fetch/background_fetch.pb.h"
 #include "content/browser/background_fetch/storage/database_helpers.h"
+#include "content/browser/cache_storage/cache_storage_manager.h"
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
 
 namespace content {
@@ -29,14 +29,39 @@
 GetSettledFetchesTask::~GetSettledFetchesTask() = default;
 
 void GetSettledFetchesTask::Start() {
+  base::RepeatingClosure barrier_closure = base::BarrierClosure(
+      2u, base::BindOnce(&GetSettledFetchesTask::GetResponses,
+                         weak_factory_.GetWeakPtr()));
+
+  cache_manager_->OpenCache(
+      registration_id_.origin(), CacheStorageOwner::kBackgroundFetch,
+      registration_id_.unique_id() /* cache_name */,
+      base::BindOnce(&GetSettledFetchesTask::DidOpenCache,
+                     weak_factory_.GetWeakPtr(), barrier_closure));
+
   service_worker_context()->GetRegistrationUserDataByKeyPrefix(
       registration_id_.service_worker_registration_id(),
       {CompletedRequestKeyPrefix(registration_id_.unique_id())},
       base::BindOnce(&GetSettledFetchesTask::DidGetCompletedRequests,
-                     weak_factory_.GetWeakPtr()));
+                     weak_factory_.GetWeakPtr(), barrier_closure));
+}
+
+void GetSettledFetchesTask::DidOpenCache(
+    base::OnceClosure done_closure,
+    CacheStorageCacheHandle handle,
+    blink::mojom::CacheStorageError error) {
+  if (error != blink::mojom::CacheStorageError::kSuccess) {
+    // TODO(crbug.com/780025): Log failures to UMA.
+    error_ = blink::mojom::BackgroundFetchError::STORAGE_ERROR;
+  } else {
+    DCHECK(handle.value());
+    handle_ = std::move(handle);
+  }
+  std::move(done_closure).Run();
 }
 
 void GetSettledFetchesTask::DidGetCompletedRequests(
+    base::OnceClosure done_closure,
     const std::vector<std::string>& data,
     ServiceWorkerStatusCode status) {
   switch (ToDatabaseStatus(status)) {
@@ -44,35 +69,44 @@
       break;
     // TODO(crbug.com/780025): Log failures to UMA.
     case DatabaseStatus::kFailed:
-      FinishTaskWithErrorCode(
-          blink::mojom::BackgroundFetchError::STORAGE_ERROR);
-      return;
+      error_ = blink::mojom::BackgroundFetchError::STORAGE_ERROR;
+      break;
     case DatabaseStatus::kNotFound:
       background_fetch_succeeded_ = false;
-      FinishTaskWithErrorCode(blink::mojom::BackgroundFetchError::INVALID_ID);
-      return;
+      error_ = blink::mojom::BackgroundFetchError::INVALID_ID;
+      break;
   }
 
-  // Nothing failed yet so the default state is success.
-  if (data.empty()) {
+  completed_requests_.reserve(data.size());
+  for (const std::string& serialized_completed_request : data) {
+    completed_requests_.emplace_back();
+    if (!completed_requests_.back().ParseFromString(
+            serialized_completed_request)) {
+      NOTREACHED()
+          << "Database is corrupt";  // TODO(crbug.com/780027): Nuke it.
+    }
+  }
+  std::move(done_closure).Run();
+}
+
+void GetSettledFetchesTask::GetResponses() {
+  if (error_ != blink::mojom::BackgroundFetchError::NONE) {
+    FinishTaskWithErrorCode(error_);
+    return;
+  }
+  if (completed_requests_.empty()) {
     FinishTaskWithErrorCode(blink::mojom::BackgroundFetchError::NONE);
     return;
   }
 
   base::RepeatingClosure barrier_closure = base::BarrierClosure(
-      data.size(),
+      completed_requests_.size() + /* finalizer */ 1,
       base::BindOnce(&GetSettledFetchesTask::FinishTaskWithErrorCode,
                      weak_factory_.GetWeakPtr(),
                      blink::mojom::BackgroundFetchError::NONE));
 
-  settled_fetches_.reserve(data.size());
-  for (const std::string& serialized_completed_request : data) {
-    proto::BackgroundFetchCompletedRequest completed_request;
-    if (!completed_request.ParseFromString(serialized_completed_request)) {
-      NOTREACHED()
-          << "Database is corrupt";  // TODO(crbug.com/780027): Nuke it.
-    }
-
+  settled_fetches_.reserve(completed_requests_.size());
+  for (const auto& completed_request : completed_requests_) {
     settled_fetches_.emplace_back(BackgroundFetchSettledFetch());
     settled_fetches_.back().request =
         std::move(ServiceWorkerFetchRequest::ParseFromString(
@@ -81,24 +115,55 @@
       FillFailedResponse(&settled_fetches_.back().response, barrier_closure);
       continue;
     }
-    FillSuccessfulResponse(&settled_fetches_.back().response, barrier_closure);
+    FillSuccessfulResponse(&settled_fetches_.back(), barrier_closure);
   }
+
+  // The callback within |barrier_closure| eventually calls Finished(), which
+  // will destroy |this|. If the callback runs within the loop, the task might
+  // crash since |completed_requests_| will be destroyed, and the for loop
+  // condition statement will access deleted memory. This is why 1 was added to
+  // the |barrier_closure| closure number, so that it can be explicitly called
+  // outside the loop.
+  barrier_closure.Run();
 }
 
-void GetSettledFetchesTask::FillFailedResponse(
-    ServiceWorkerResponse* response,
-    const base::RepeatingClosure& callback) {
+void GetSettledFetchesTask::FillFailedResponse(ServiceWorkerResponse* response,
+                                               base::OnceClosure callback) {
   DCHECK(response);
   background_fetch_succeeded_ = false;
+
   // TODO(rayankans): Fill failed response with error reports.
+  response->response_type = network::mojom::FetchResponseType::kError;
+
   std::move(callback).Run();
 }
 
 void GetSettledFetchesTask::FillSuccessfulResponse(
+    BackgroundFetchSettledFetch* settled_fetch,
+    base::OnceClosure callback) {
+  DCHECK(settled_fetch);
+  DCHECK(handle_.value());
+
+  auto request =
+      std::make_unique<ServiceWorkerFetchRequest>(settled_fetch->request);
+
+  handle_.value()->Match(
+      std::move(request), nullptr /* match_params */,
+      base::BindOnce(&GetSettledFetchesTask::DidMatchRequest,
+                     weak_factory_.GetWeakPtr(), &settled_fetch->response,
+                     std::move(callback)));
+}
+
+void GetSettledFetchesTask::DidMatchRequest(
     ServiceWorkerResponse* response,
-    const base::RepeatingClosure& callback) {
-  DCHECK(response);
-  // TODO(rayankans): Get the response stored in Cache Storage.
+    base::OnceClosure callback,
+    blink::mojom::CacheStorageError error,
+    std::unique_ptr<ServiceWorkerResponse> cache_response) {
+  if (error != blink::mojom::CacheStorageError::kSuccess) {
+    FillFailedResponse(response, std::move(callback));
+    return;
+  }
+  *response = std::move(*cache_response);
   std::move(callback).Run();
 }
 
diff --git a/content/browser/background_fetch/storage/get_settled_fetches_task.h b/content/browser/background_fetch/storage/get_settled_fetches_task.h
index 98cf7c9..94ce337 100644
--- a/content/browser/background_fetch/storage/get_settled_fetches_task.h
+++ b/content/browser/background_fetch/storage/get_settled_fetches_task.h
@@ -6,7 +6,9 @@
 #define CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_GET_SETTLED_FETCHES_TASK_H_
 
 #include "base/callback_forward.h"
+#include "content/browser/background_fetch/background_fetch.pb.h"
 #include "content/browser/background_fetch/storage/database_task.h"
+#include "content/browser/cache_storage/cache_storage_cache_handle.h"
 #include "content/common/service_worker/service_worker_status_code.h"
 #include "storage/browser/blob/blob_data_handle.h"
 
@@ -35,14 +37,26 @@
   void Start() override;
 
  private:
-  void DidGetCompletedRequests(const std::vector<std::string>& data,
+  void DidOpenCache(base::OnceClosure done_closure,
+                    CacheStorageCacheHandle handle,
+                    blink::mojom::CacheStorageError error);
+
+  void DidGetCompletedRequests(base::OnceClosure done_closure,
+                               const std::vector<std::string>& data,
                                ServiceWorkerStatusCode status);
 
-  void FillFailedResponse(ServiceWorkerResponse* response,
-                          const base::RepeatingClosure& callback);
+  void GetResponses();
 
-  void FillSuccessfulResponse(ServiceWorkerResponse* response,
-                              const base::RepeatingClosure& callback);
+  void FillFailedResponse(ServiceWorkerResponse* response,
+                          base::OnceClosure callback);
+
+  void FillSuccessfulResponse(BackgroundFetchSettledFetch* settled_fetch,
+                              base::OnceClosure callback);
+
+  void DidMatchRequest(ServiceWorkerResponse* response,
+                       base::OnceClosure callback,
+                       blink::mojom::CacheStorageError error,
+                       std::unique_ptr<ServiceWorkerResponse> cache_response);
 
   void FinishTaskWithErrorCode(blink::mojom::BackgroundFetchError error);
 
@@ -50,9 +64,16 @@
   CacheStorageManager* cache_manager_;
   SettledFetchesCallback settled_fetches_callback_;
 
+  // SettledFetchesCallback params.
   std::vector<BackgroundFetchSettledFetch> settled_fetches_;
   bool background_fetch_succeeded_ = true;
 
+  // Storage params.
+  CacheStorageCacheHandle handle_;
+  std::vector<proto::BackgroundFetchCompletedRequest> completed_requests_;
+  blink::mojom::BackgroundFetchError error_ =
+      blink::mojom::BackgroundFetchError::NONE;
+
   base::WeakPtrFactory<GetSettledFetchesTask> weak_factory_;  // Keep as last.
 
   DISALLOW_COPY_AND_ASSIGN(GetSettledFetchesTask);
diff --git a/content/browser/devtools/devtools_agent_host_impl.cc b/content/browser/devtools/devtools_agent_host_impl.cc
index a671484..b4eedd7 100644
--- a/content/browser/devtools/devtools_agent_host_impl.cc
+++ b/content/browser/devtools/devtools_agent_host_impl.cc
@@ -400,6 +400,11 @@
     observer.DevToolsAgentHostDetached(this);
 }
 
+void DevToolsAgentHostImpl::NotifyCrashed(base::TerminationStatus status) {
+  for (auto& observer : g_devtools_observers.Get())
+    observer.DevToolsAgentHostCrashed(this, status);
+}
+
 void DevToolsAgentHostImpl::NotifyDestroyed() {
   DCHECK(g_devtools_instances.Get().find(id_) !=
          g_devtools_instances.Get().end());
diff --git a/content/browser/devtools/devtools_agent_host_impl.h b/content/browser/devtools/devtools_agent_host_impl.h
index 68317042..0fc75ad 100644
--- a/content/browser/devtools/devtools_agent_host_impl.h
+++ b/content/browser/devtools/devtools_agent_host_impl.h
@@ -12,6 +12,7 @@
 #include "base/compiler_specific.h"
 #include "base/containers/flat_map.h"
 #include "base/containers/flat_set.h"
+#include "base/process/kill.h"
 #include "content/browser/devtools/devtools_io_context.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/certificate_request_result_type.h"
@@ -71,6 +72,7 @@
 
   void NotifyCreated();
   void NotifyNavigated();
+  void NotifyCrashed(base::TerminationStatus status);
   void ForceDetachAllSessions();
   void ForceDetachRestrictedSessions();
   DevToolsIOContext* GetIOContext() { return &io_context_; }
diff --git a/content/browser/devtools/protocol/target_handler.cc b/content/browser/devtools/protocol/target_handler.cc
index 1ebf94f..0b1bb26 100644
--- a/content/browser/devtools/protocol/target_handler.cc
+++ b/content/browser/devtools/protocol/target_handler.cc
@@ -7,12 +7,14 @@
 #include "base/json/json_reader.h"
 #include "base/strings/stringprintf.h"
 #include "base/values.h"
+#include "build/build_config.h"
 #include "content/browser/devtools/devtools_manager.h"
 #include "content/browser/devtools/devtools_session.h"
 #include "content/browser/frame_host/navigation_handle_impl.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/devtools_agent_host_client.h"
 #include "content/public/browser/navigation_throttle.h"
+#include "content/public/browser/web_contents.h"
 
 namespace content {
 namespace protocol {
@@ -38,6 +40,42 @@
   return target_info;
 }
 
+static std::string TerminationStatusToString(base::TerminationStatus status) {
+  switch (status) {
+    case base::TERMINATION_STATUS_NORMAL_TERMINATION:
+      return "normal";
+    case base::TERMINATION_STATUS_ABNORMAL_TERMINATION:
+      return "abnormal";
+    case base::TERMINATION_STATUS_PROCESS_WAS_KILLED:
+      return "killed";
+    case base::TERMINATION_STATUS_PROCESS_CRASHED:
+      return "crashed";
+    case base::TERMINATION_STATUS_STILL_RUNNING:
+      return "still running";
+#if defined(OS_CHROMEOS)
+    // Used for the case when oom-killer kills a process on ChromeOS.
+    case base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM:
+      return "oom killed";
+#endif
+#if defined(OS_ANDROID)
+    // On Android processes are spawned from the system Zygote and we do not get
+    // the termination status.  We can't know if the termination was a crash or
+    // an oom kill for sure: but we can use status of the strong process
+    // bindings as a hint.
+    case base::TERMINATION_STATUS_OOM_PROTECTED:
+      return "oom protected";
+#endif
+    case base::TERMINATION_STATUS_LAUNCH_FAILED:
+      return "failed to launch";
+    case base::TERMINATION_STATUS_OOM:
+      return "oom";
+    case base::TERMINATION_STATUS_MAX_ENUM:
+      break;
+  }
+  NOTREACHED() << "Unknown Termination Status.";
+  return "unknown";
+}
+
 }  // namespace
 
 // Throttle is owned externally by the navigation subsystem.
@@ -467,5 +505,15 @@
   frontend_->TargetInfoChanged(CreateInfo(host));
 }
 
+void TargetHandler::DevToolsAgentHostCrashed(DevToolsAgentHost* host,
+                                             base::TerminationStatus status) {
+  if (reported_hosts_.find(host) == reported_hosts_.end())
+    return;
+  frontend_->TargetCrashed(host->GetId(), TerminationStatusToString(status),
+                           host->GetWebContents()
+                               ? host->GetWebContents()->GetCrashedErrorCode()
+                               : 0);
+}
+
 }  // namespace protocol
 }  // namespace content
diff --git a/content/browser/devtools/protocol/target_handler.h b/content/browser/devtools/protocol/target_handler.h
index 7d75e62a..10a4159 100644
--- a/content/browser/devtools/protocol/target_handler.h
+++ b/content/browser/devtools/protocol/target_handler.h
@@ -95,6 +95,8 @@
   void DevToolsAgentHostDestroyed(DevToolsAgentHost* agent_host) override;
   void DevToolsAgentHostAttached(DevToolsAgentHost* agent_host) override;
   void DevToolsAgentHostDetached(DevToolsAgentHost* agent_host) override;
+  void DevToolsAgentHostCrashed(DevToolsAgentHost* agent_host,
+                                base::TerminationStatus status) override;
 
   std::unique_ptr<Target::Frontend> frontend_;
   TargetAutoAttacher auto_attacher_;
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc
index af69823..64e7804 100644
--- a/content/browser/devtools/render_frame_devtools_agent_host.cc
+++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -734,6 +734,7 @@
     case base::TERMINATION_STATUS_LAUNCH_FAILED:
       for (auto* inspector : protocol::InspectorHandler::ForAgentHost(this))
         inspector->TargetCrashed();
+      NotifyCrashed(status);
       break;
     default:
       for (auto* inspector : protocol::InspectorHandler::ForAgentHost(this))
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index d3a04d77..9e84453 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -2796,7 +2796,6 @@
 
   was_discarded_ = false;
   is_loading_ = false;
-  navigation_request_.reset();
 
   // Only inform the FrameTreeNode of a change in load state if the load state
   // of this RenderFrameHost is being tracked.
@@ -3773,7 +3772,14 @@
           std::move(url_loader_client_endpoints),
           std::move(subresource_loader_factories),
           std::move(subresource_overrides), std::move(controller),
-          devtools_navigation_token);
+          devtools_navigation_token,
+          navigation_request_
+              ? base::BindOnce(
+                    &RenderFrameHostImpl::OnCrossDocumentCommitProcessed,
+                    base::Unretained(this),
+                    navigation_request_->navigation_handle()->GetNavigationId())
+              : content::mojom::FrameNavigationControl::
+                    CommitNavigationCallback());
     }
 
     // |remote_object| is an associated interface ptr, so calls can't be made on
@@ -3832,7 +3838,11 @@
   } else {
     GetNavigationControl()->CommitFailedNavigation(
         common_params, request_params, has_stale_copy_in_cache, error_code,
-        error_page_content, std::move(subresource_loader_factories));
+        error_page_content, std::move(subresource_loader_factories),
+        base::BindOnce(
+            &RenderFrameHostImpl::OnCrossDocumentCommitProcessed,
+            base::Unretained(this),
+            navigation_request_->navigation_handle()->GetNavigationId()));
   }
 
   // An error page is expected to commit, hence why is_loading_ is set to true.
@@ -5015,19 +5025,12 @@
   if (!ValidateDidCommitParams(validated_params))
     return false;
 
-  if (!navigation_request_) {
-    // The browser has not been notified about the start of the
-    // load in this renderer yet (e.g., for same-document navigations that start
-    // in the renderer). Do it now.
-    // TODO(ahemery): This should never be true for cross-document navigation
-    // apart from race conditions. Move to same navigation specific code when
-    // the full mojo interface is in place.
-    // (https://bugs.chromium.org/p/chromium/issues/detail?id=784904)
-    if (!is_loading()) {
-      bool was_loading = frame_tree_node()->frame_tree()->IsLoading();
-      is_loading_ = true;
-      frame_tree_node()->DidStartLoading(true, was_loading);
-    }
+  // A racy DidStopLoading IPC might have reset the loading state that was set
+  // to true in CommitNavigation. Set it to true now.
+  if (!is_loading()) {
+    bool was_loading = frame_tree_node()->frame_tree()->IsLoading();
+    is_loading_ = true;
+    frame_tree_node()->DidStartLoading(true, was_loading);
   }
 
   if (navigation_request_)
@@ -5074,10 +5077,30 @@
   }
 
   if (result == blink::mojom::CommitResult::Aborted) {
-    // Note: if the commit was successful, navigation_handle_ is reset in
+    // Note: if the commit was successful, navigation_request_ is reset in
     // DidCommitProvisionalLoad.
     same_document_navigation_request_.reset();
   }
 }
 
+void RenderFrameHostImpl::OnCrossDocumentCommitProcessed(
+    int64_t navigation_id,
+    blink::mojom::CommitResult result) {
+  // If the NavigationRequest was deleted, another navigation commit started to
+  // be processed. Let the latest commit go through and stop doing anything.
+  if (!navigation_request_ ||
+      navigation_request_->navigation_handle()->GetNavigationId() !=
+          navigation_id) {
+    return;
+  }
+  DCHECK_NE(blink::mojom::CommitResult::RestartCrossDocument, result);
+
+  // Note: if the commit was successful, navigation_request_ is reset in
+  // DidCommitProvisionalLoad.
+  if (result == blink::mojom::CommitResult::Ok)
+    return;
+
+  navigation_request_.reset();
+}
+
 }  // namespace content
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h
index 4f299ac..02bd6d3 100644
--- a/content/browser/frame_host/render_frame_host_impl.h
+++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -1155,6 +1155,11 @@
                                      bool should_replace_current_entry,
                                      blink::mojom::CommitResult result);
 
+  // Called by the renderer process when it is done processing a cross-document
+  // commit request.
+  void OnCrossDocumentCommitProcessed(int64_t navigation_id,
+                                      blink::mojom::CommitResult result);
+
   // For now, RenderFrameHosts indirectly keep RenderViewHosts alive via a
   // refcount that calls Shutdown when it reaches zero.  This allows each
   // RenderFrameHostManager to just care about RenderFrameHosts, while ensuring
diff --git a/content/browser/renderer_host/media/audio_service_listener.cc b/content/browser/renderer_host/media/audio_service_listener.cc
index adf6f938..8f917a01 100644
--- a/content/browser/renderer_host/media/audio_service_listener.cc
+++ b/content/browser/renderer_host/media/audio_service_listener.cc
@@ -82,24 +82,25 @@
 AudioServiceListener::AudioServiceListener(
     std::unique_ptr<service_manager::Connector> connector)
     : binding_(this),
-      connector_(std::move(connector)),
       metrics_(base::DefaultTickClock::GetInstance()) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
-  if (!connector_)
+  if (!connector)
     return;  // Happens in unittests.
 
   service_manager::mojom::ServiceManagerPtr service_manager;
-  connector_->BindInterface(service_manager::mojom::kServiceName,
-                            &service_manager);
+  connector->BindInterface(service_manager::mojom::kServiceName,
+                           &service_manager);
   service_manager::mojom::ServiceManagerListenerPtr listener;
   service_manager::mojom::ServiceManagerListenerRequest request(
       mojo::MakeRequest(&listener));
   service_manager->AddListener(std::move(listener));
   binding_.Bind(std::move(request));
+  BrowserChildProcessObserver::Add(this);
 }
 
 AudioServiceListener::~AudioServiceListener() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
+  BrowserChildProcessObserver::Remove(this);
 }
 
 base::ProcessId AudioServiceListener::GetProcessId() const {
@@ -161,7 +162,6 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
   if (identity.name() != audio::mojom::kServiceName)
     return;
-  process_id_ = base::kNullProcessId;
   metrics_.ServiceStopped();
 }
 
@@ -170,6 +170,7 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
   if (base::GetProcId(data.handle) != process_id_)
     return;
+  process_id_ = base::kNullProcessId;
   metrics_.ServiceProcessTerminated(
       Metrics::ServiceProcessTerminationStatus::kDisconnect);
 }
@@ -180,6 +181,7 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
   if (base::GetProcId(data.handle) != process_id_)
     return;
+  process_id_ = base::kNullProcessId;
   metrics_.ServiceProcessTerminated(
       Metrics::ServiceProcessTerminationStatus::kCrash);
 }
@@ -190,6 +192,7 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(owning_sequence_);
   if (base::GetProcId(data.handle) != process_id_)
     return;
+  process_id_ = base::kNullProcessId;
   metrics_.ServiceProcessTerminated(
       Metrics::ServiceProcessTerminationStatus::kKill);
 }
diff --git a/content/browser/renderer_host/media/audio_service_listener.h b/content/browser/renderer_host/media/audio_service_listener.h
index 2fe9cdd5..83f3648 100644
--- a/content/browser/renderer_host/media/audio_service_listener.h
+++ b/content/browser/renderer_host/media/audio_service_listener.h
@@ -82,17 +82,15 @@
                            OnInitWithAudioService_ProcessIdNotNull);
   FRIEND_TEST_ALL_PREFIXES(AudioServiceListenerTest,
                            OnAudioServiceCreated_ProcessIdNotNull);
-  FRIEND_TEST_ALL_PREFIXES(AudioServiceListenerTest,
-                           OnAudioServiceStopped_ProcessIdNull);
   FRIEND_TEST_ALL_PREFIXES(
       AudioServiceListenerTest,
-      BrowserChildProcessHostDisconnected_LogProcessTerminationStatus);
+      AudioServiceProcessDisconnected_LogProcessTerminationStatus_ProcessIdNull);
   FRIEND_TEST_ALL_PREFIXES(
       AudioServiceListenerTest,
-      BrowserChildProcessCrashed_LogProcessTerminationStatus);
+      AudioServiceProcessCrashed_LogProcessTerminationStatus_ProcessIdNull);
   FRIEND_TEST_ALL_PREFIXES(
       AudioServiceListenerTest,
-      BrowserChildProcessKilled_LogProcessTerminationStatus);
+      AudioServiceProcessKilled_LogProcessTerminationStatus_ProcessIdNull);
   FRIEND_TEST_ALL_PREFIXES(AudioServiceListenerTest,
                            StartService_LogStartStatus);
 
@@ -118,7 +116,6 @@
                                  const ChildProcessTerminationInfo& info) final;
 
   mojo::Binding<service_manager::mojom::ServiceManagerListener> binding_;
-  std::unique_ptr<service_manager::Connector> connector_;
   base::ProcessId process_id_ = base::kNullProcessId;
   Metrics metrics_;
   SEQUENCE_CHECKER(owning_sequence_);
diff --git a/content/browser/renderer_host/media/audio_service_listener_unittest.cc b/content/browser/renderer_host/media/audio_service_listener_unittest.cc
index 374e8a00..661c2743 100644
--- a/content/browser/renderer_host/media/audio_service_listener_unittest.cc
+++ b/content/browser/renderer_host/media/audio_service_listener_unittest.cc
@@ -181,15 +181,66 @@
   EXPECT_EQ(pid, audio_service_listener.GetProcessId());
 }
 
-TEST(AudioServiceListenerTest, OnAudioServiceStopped_ProcessIdNull) {
+TEST(
+    AudioServiceListenerTest,
+    AudioServiceProcessDisconnected_LogProcessTerminationStatus_ProcessIdNull) {
+  base::HistogramTester histogram_tester;
   AudioServiceListener audio_service_listener(nullptr);
   service_manager::Identity audio_service_identity(audio::mojom::kServiceName);
-  constexpr base::ProcessId pid(42);
+  base::ProcessHandle handle = base::GetCurrentProcessHandle();
+  base::ProcessId pid = base::GetCurrentProcId();
   audio_service_listener.OnServiceCreated(
       MakeTestServiceInfo(audio_service_identity, pid));
   audio_service_listener.OnServiceStarted(audio_service_identity, pid);
-  EXPECT_EQ(pid, audio_service_listener.GetProcessId());
-  audio_service_listener.OnServiceStopped(audio_service_identity);
+  ChildProcessData data(content::ProcessType::PROCESS_TYPE_UTILITY);
+  data.handle = handle;
+  audio_service_listener.BrowserChildProcessHostDisconnected(data);
+  histogram_tester.ExpectUniqueSample(
+      "Media.AudioService.ObservedProcessTerminationStatus",
+      AudioServiceListener::Metrics::ServiceProcessTerminationStatus::
+          kDisconnect,
+      1);
+  EXPECT_EQ(base::kNullProcessId, audio_service_listener.GetProcessId());
+}
+
+TEST(AudioServiceListenerTest,
+     AudioServiceProcessCrashed_LogProcessTerminationStatus_ProcessIdNull) {
+  base::HistogramTester histogram_tester;
+  AudioServiceListener audio_service_listener(nullptr);
+  service_manager::Identity audio_service_identity(audio::mojom::kServiceName);
+  base::ProcessHandle handle = base::GetCurrentProcessHandle();
+  base::ProcessId pid = base::GetCurrentProcId();
+  audio_service_listener.OnServiceCreated(
+      MakeTestServiceInfo(audio_service_identity, pid));
+  audio_service_listener.OnServiceStarted(audio_service_identity, pid);
+  ChildProcessData data(content::ProcessType::PROCESS_TYPE_UTILITY);
+  data.handle = handle;
+  audio_service_listener.BrowserChildProcessCrashed(
+      data, content::ChildProcessTerminationInfo());
+  histogram_tester.ExpectUniqueSample(
+      "Media.AudioService.ObservedProcessTerminationStatus",
+      AudioServiceListener::Metrics::ServiceProcessTerminationStatus::kCrash,
+      1);
+  EXPECT_EQ(base::kNullProcessId, audio_service_listener.GetProcessId());
+}
+
+TEST(AudioServiceListenerTest,
+     AudioServiceProcessKilled_LogProcessTerminationStatus_ProcessIdNull) {
+  base::HistogramTester histogram_tester;
+  AudioServiceListener audio_service_listener(nullptr);
+  service_manager::Identity audio_service_identity(audio::mojom::kServiceName);
+  base::ProcessHandle handle = base::GetCurrentProcessHandle();
+  base::ProcessId pid = base::GetCurrentProcId();
+  audio_service_listener.OnServiceCreated(
+      MakeTestServiceInfo(audio_service_identity, pid));
+  audio_service_listener.OnServiceStarted(audio_service_identity, pid);
+  ChildProcessData data(content::ProcessType::PROCESS_TYPE_UTILITY);
+  data.handle = handle;
+  audio_service_listener.BrowserChildProcessKilled(
+      data, content::ChildProcessTerminationInfo());
+  histogram_tester.ExpectUniqueSample(
+      "Media.AudioService.ObservedProcessTerminationStatus",
+      AudioServiceListener::Metrics::ServiceProcessTerminationStatus::kKill, 1);
   EXPECT_EQ(base::kNullProcessId, audio_service_listener.GetProcessId());
 }
 
diff --git a/content/browser/web_package/signed_exchange_cert_fetcher.cc b/content/browser/web_package/signed_exchange_cert_fetcher.cc
index 083d6c6..411e5f6 100644
--- a/content/browser/web_package/signed_exchange_cert_fetcher.cc
+++ b/content/browser/web_package/signed_exchange_cert_fetcher.cc
@@ -218,6 +218,23 @@
     Abort();
     return;
   }
+
+  // https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html#cert-chain-format
+  // "The resource at a signature's cert-url MUST have the
+  // application/cert-chain+cbor content type" [spec text]
+  std::string mime_type;
+  if (!head.headers->GetMimeType(&mime_type) ||
+      mime_type != "application/cert-chain+cbor") {
+    signed_exchange_utils::ReportErrorAndEndTraceEvent(
+        devtools_proxy_, "SignedExchangeCertFetcher::OnReceiveResponse",
+        base::StringPrintf(
+            "Content type of cert-url must be application/cert-chain+cbor. "
+            "Actual content type: %s",
+            mime_type.c_str()));
+    Abort();
+    return;
+  }
+
   if (head.content_length > 0) {
     if (base::checked_cast<size_t>(head.content_length) >
         g_max_cert_size_for_signed_exchange) {
diff --git a/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc b/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc
index 00db6af7..51e1073 100644
--- a/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc
+++ b/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc
@@ -215,7 +215,8 @@
     network::ResourceResponseHead resource_response;
     resource_response.headers =
         base::MakeRefCounted<net::HttpResponseHeaders>("HTTP/1.1 200 OK");
-
+    resource_response.headers->AddHeader(
+        "Content-Type: application/cert-chain+cbor");
     mock_loader_factory_.client_ptr()->OnReceiveResponse(
         resource_response, nullptr /* downloaded_file */);
   }
@@ -449,6 +450,22 @@
   EXPECT_FALSE(cert_result_);
 }
 
+TEST_F(SignedExchangeCertFetcherTest, WrongContentType) {
+  std::unique_ptr<SignedExchangeCertFetcher> fetcher =
+      CreateFetcherAndStart(false /* force_fetch */);
+  network::ResourceResponseHead resource_response;
+  resource_response.headers =
+      base::MakeRefCounted<net::HttpResponseHeaders>("HTTP/1.1 200 OK");
+  resource_response.headers->AddHeader(
+      "Content-Type: application/octet-stream");
+  mock_loader_factory_.client_ptr()->OnReceiveResponse(
+      resource_response, nullptr /* downloaded_file */);
+  RunUntilIdle();
+
+  EXPECT_TRUE(callback_called_);
+  EXPECT_FALSE(cert_result_);
+}
+
 TEST_F(SignedExchangeCertFetcherTest, Invalid_CertData) {
   std::unique_ptr<SignedExchangeCertFetcher> fetcher =
       CreateFetcherAndStart(false /* force_fetch */);
diff --git a/content/browser/web_package/signed_exchange_consts.h b/content/browser/web_package/signed_exchange_consts.h
index 4f02828..6e8bd521 100644
--- a/content/browser/web_package/signed_exchange_consts.h
+++ b/content/browser/web_package/signed_exchange_consts.h
@@ -22,7 +22,6 @@
 constexpr char kHeadersKey[] = "headers";
 constexpr char kIntegrity[] = "integrity";
 constexpr char kMethodKey[] = ":method";
-constexpr char kSignature[] = "signature";
 constexpr char kSig[] = "sig";
 constexpr char kStatusKey[] = ":status";
 constexpr char kUrlKey[] = ":url";
diff --git a/content/browser/web_package/signed_exchange_envelope.cc b/content/browser/web_package/signed_exchange_envelope.cc
index a82c8141..baa80303 100644
--- a/content/browser/web_package/signed_exchange_envelope.cc
+++ b/content/browser/web_package/signed_exchange_envelope.cc
@@ -261,12 +261,14 @@
 
 // static
 base::Optional<SignedExchangeEnvelope> SignedExchangeEnvelope::Parse(
-    base::span<const uint8_t> input,
+    base::StringPiece signature_header_field,
+    base::span<const uint8_t> cbor_header,
     SignedExchangeDevToolsProxy* devtools_proxy) {
   TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("loading"),
                      "SignedExchangeEnvelope::Parse");
   cbor::CBORReader::DecoderError error;
-  base::Optional<cbor::CBORValue> value = cbor::CBORReader::Read(input, &error);
+  base::Optional<cbor::CBORValue> value =
+      cbor::CBORReader::Read(cbor_header, &error);
   if (!value.has_value()) {
     signed_exchange_utils::ReportErrorAndEndTraceEvent(
         devtools_proxy, "SignedExchangeEnvelope::Parse",
@@ -309,21 +311,13 @@
     return base::nullopt;
   }
 
-  auto signature_iter = ret.response_headers_.find(kSignature);
-  if (signature_iter == ret.response_headers_.end()) {
-    signed_exchange_utils::ReportErrorAndEndTraceEvent(
-        devtools_proxy, "SignedExchangeEnvelope::Parse",
-        "No signature header found.");
-    return base::nullopt;
-  }
-
   base::Optional<std::vector<SignedExchangeSignatureHeaderField::Signature>>
       signatures = SignedExchangeSignatureHeaderField::ParseSignature(
-          signature_iter->second, devtools_proxy);
+          signature_header_field, devtools_proxy);
   if (!signatures || signatures->empty()) {
     signed_exchange_utils::ReportErrorAndEndTraceEvent(
         devtools_proxy, "SignedExchangeEnvelope::Parse",
-        "Failed to parse signature.");
+        "Failed to parse signature header field.");
     return base::nullopt;
   }
 
diff --git a/content/browser/web_package/signed_exchange_envelope.h b/content/browser/web_package/signed_exchange_envelope.h
index 63793ab..4f90e1d 100644
--- a/content/browser/web_package/signed_exchange_envelope.h
+++ b/content/browser/web_package/signed_exchange_envelope.h
@@ -36,7 +36,8 @@
   // This also performs the step 3 and 4 of "Cross-origin trust" validation.
   // https://wicg.github.io/webpackage/draft-yasskin-httpbis-origin-signed-exchanges-impl.html#cross-origin-trust
   static base::Optional<SignedExchangeEnvelope> Parse(
-      base::span<const uint8_t> input,
+      base::StringPiece signature_header_field,
+      base::span<const uint8_t> cbor_header,
       SignedExchangeDevToolsProxy* devtools_proxy);
   SignedExchangeEnvelope();
   SignedExchangeEnvelope(const SignedExchangeEnvelope&);
diff --git a/content/browser/web_package/signed_exchange_envelope_unittest.cc b/content/browser/web_package/signed_exchange_envelope_unittest.cc
index 4e232f3c..813b158 100644
--- a/content/browser/web_package/signed_exchange_envelope_unittest.cc
+++ b/content/browser/web_package/signed_exchange_envelope_unittest.cc
@@ -34,6 +34,7 @@
 }
 
 base::Optional<SignedExchangeEnvelope> GenerateHeaderAndParse(
+    base::StringPiece signature,
     const std::map<const char*, const char*>& request_map,
     const std::map<const char*, const char*>& response_map) {
   cbor::CBORValue::MapValue request_cbor_map;
@@ -49,7 +50,7 @@
 
   auto serialized = cbor::CBORWriter::Write(cbor::CBORValue(std::move(array)));
   return SignedExchangeEnvelope::Parse(
-      base::make_span(serialized->data(), serialized->size()),
+      signature, base::make_span(serialized->data(), serialized->size()),
       nullptr /* devtools_proxy */);
 }
 
@@ -65,35 +66,42 @@
   ASSERT_TRUE(base::ReadFileToString(test_htxg_path, &contents));
   auto* contents_bytes = reinterpret_cast<const uint8_t*>(contents.data());
 
-  ASSERT_GT(contents.size(), SignedExchangePrologue::kEncodedLengthInBytes);
-  size_t header_size =
-      SignedExchangePrologue::ParseEncodedLength(base::make_span(
-          contents_bytes, SignedExchangePrologue::kEncodedLengthInBytes));
-  ASSERT_GT(contents.size(),
-            SignedExchangePrologue::kEncodedLengthInBytes + header_size);
+  ASSERT_GT(contents.size(), SignedExchangePrologue::kEncodedPrologueInBytes);
+  base::Optional<SignedExchangePrologue> prologue =
+      SignedExchangePrologue::Parse(
+          base::make_span(contents_bytes,
+                          SignedExchangePrologue::kEncodedPrologueInBytes),
+          nullptr /* devtools_proxy */);
+  ASSERT_TRUE(prologue.has_value());
+  ASSERT_GT(contents.size(), SignedExchangePrologue::kEncodedPrologueInBytes +
+                                 prologue->ComputeFollowingSectionsLength());
 
+  base::StringPiece signature_header_field(
+      contents.data() + SignedExchangePrologue::kEncodedPrologueInBytes,
+      prologue->signature_header_field_length());
   const auto cbor_bytes = base::make_span<const uint8_t>(
-      contents_bytes + SignedExchangePrologue::kEncodedLengthInBytes,
-      header_size);
+      contents_bytes + SignedExchangePrologue::kEncodedPrologueInBytes +
+          prologue->signature_header_field_length(),
+      prologue->cbor_header_length());
   const base::Optional<SignedExchangeEnvelope> header =
-      SignedExchangeEnvelope::Parse(cbor_bytes, nullptr /* devtools_proxy */);
+      SignedExchangeEnvelope::Parse(signature_header_field, cbor_bytes,
+                                    nullptr /* devtools_proxy */);
   ASSERT_TRUE(header.has_value());
   EXPECT_EQ(header->request_url(), GURL("https://test.example.org/test/"));
   EXPECT_EQ(header->request_method(), "GET");
   EXPECT_EQ(header->response_code(), static_cast<net::HttpStatusCode>(200u));
-  EXPECT_EQ(header->response_headers().size(), 4u);
+  EXPECT_EQ(header->response_headers().size(), 3u);
   EXPECT_EQ(header->response_headers().find("content-encoding")->second,
             "mi-sha256");
 }
 
 TEST(SignedExchangeEnvelopeTest, ValidHeader) {
   auto header = GenerateHeaderAndParse(
+      kSignatureString,
       {
           {kUrlKey, "https://test.example.org/test/"}, {kMethodKey, "GET"},
       },
-      {
-          {kStatusKey, "200"}, {kSignature, kSignatureString},
-      });
+      {{kStatusKey, "200"}, {"content-type", "text/html"}});
   ASSERT_TRUE(header.has_value());
   EXPECT_EQ(header->request_url(), GURL("https://test.example.org/test/"));
   EXPECT_EQ(header->request_method(), "GET");
@@ -103,93 +111,97 @@
 
 TEST(SignedExchangeEnvelopeTest, UnsafeMethod) {
   auto header = GenerateHeaderAndParse(
+      kSignatureString,
       {
           {kUrlKey, "https://test.example.org/test/"}, {kMethodKey, "POST"},
       },
       {
-          {kStatusKey, "200"}, {kSignature, kSignatureString},
+          {kStatusKey, "200"},
       });
   ASSERT_FALSE(header.has_value());
 }
 
 TEST(SignedExchangeEnvelopeTest, InvalidURL) {
   auto header = GenerateHeaderAndParse(
+      kSignatureString,
       {
           {kUrlKey, "https:://test.example.org/test/"}, {kMethodKey, "GET"},
       },
       {
-          {kStatusKey, "200"}, {kSignature, kSignatureString},
+          {kStatusKey, "200"},
       });
   ASSERT_FALSE(header.has_value());
 }
 
 TEST(SignedExchangeEnvelopeTest, URLWithFragment) {
   auto header = GenerateHeaderAndParse(
+      kSignatureString,
       {
           {kUrlKey, "https://test.example.org/test/#foo"}, {kMethodKey, "GET"},
       },
       {
-          {kStatusKey, "200"}, {kSignature, kSignatureString},
+          {kStatusKey, "200"},
       });
   ASSERT_FALSE(header.has_value());
 }
 
 TEST(SignedExchangeEnvelopeTest, RelativeURL) {
-  auto header = GenerateHeaderAndParse(
-      {
-          {kUrlKey, "test/"}, {kMethodKey, "GET"},
-      },
-      {
-          {kStatusKey, "200"}, {kSignature, kSignatureString},
-      });
+  auto header =
+      GenerateHeaderAndParse(kSignatureString,
+                             {
+                                 {kUrlKey, "test/"}, {kMethodKey, "GET"},
+                             },
+                             {
+                                 {kStatusKey, "200"},
+                             });
   ASSERT_FALSE(header.has_value());
 }
 
 TEST(SignedExchangeEnvelopeTest, StatefulRequestHeader) {
-  auto header = GenerateHeaderAndParse(
-      {
-          {kUrlKey, "https://test.example.org/test/"},
-          {kMethodKey, "GET"},
-          {"authorization", "Basic Zm9vOmJhcg=="},
-      },
-      {
-          {kStatusKey, "200"}, {kSignature, kSignatureString},
-      });
+  auto header =
+      GenerateHeaderAndParse(kSignatureString,
+                             {
+                                 {kUrlKey, "https://test.example.org/test/"},
+                                 {kMethodKey, "GET"},
+                                 {"authorization", "Basic Zm9vOmJhcg=="},
+                             },
+                             {
+                                 {kStatusKey, "200"},
+                             });
   ASSERT_FALSE(header.has_value());
 }
 
 TEST(SignedExchangeEnvelopeTest, StatefulResponseHeader) {
   auto header = GenerateHeaderAndParse(
+      kSignatureString,
       {
           {kUrlKey, "https://test.example.org/test/"}, {kMethodKey, "GET"},
       },
       {
-          {kStatusKey, "200"},
-          {kSignature, kSignatureString},
-          {"set-cookie", "foo=bar"},
+          {kStatusKey, "200"}, {"set-cookie", "foo=bar"},
       });
   ASSERT_FALSE(header.has_value());
 }
 
 TEST(SignedExchangeEnvelopeTest, UppercaseRequestMap) {
-  auto header = GenerateHeaderAndParse(
-      {{kUrlKey, "https://test.example.org/test/"},
-       {kMethodKey, "GET"},
-       {"Accept-Language", "en-us"}},
-      {
-          {kStatusKey, "200"}, {kSignature, kSignatureString},
-      });
+  auto header =
+      GenerateHeaderAndParse(kSignatureString,
+                             {{kUrlKey, "https://test.example.org/test/"},
+                              {kMethodKey, "GET"},
+                              {"Accept-Language", "en-us"}},
+                             {
+                                 {kStatusKey, "200"},
+                             });
   ASSERT_FALSE(header.has_value());
 }
 
 TEST(SignedExchangeEnvelopeTest, UppercaseResponseMap) {
   auto header = GenerateHeaderAndParse(
+      kSignatureString,
       {
           {kUrlKey, "https://test.example.org/test/"}, {kMethodKey, "GET"},
       },
-      {{kStatusKey, "200"},
-       {kSignature, kSignatureString},
-       {"Content-Length", "123"}});
+      {{kStatusKey, "200"}, {"Content-Length", "123"}});
   ASSERT_FALSE(header.has_value());
 }
 
diff --git a/content/browser/web_package/signed_exchange_handler.cc b/content/browser/web_package/signed_exchange_handler.cc
index b6fc028..5bfef87 100644
--- a/content/browser/web_package/signed_exchange_handler.cc
+++ b/content/browser/web_package/signed_exchange_handler.cc
@@ -40,10 +40,6 @@
 
 namespace {
 
-// 256KB (Maximum header size) * 2, since signed exchange header contains
-// request and response headers.
-constexpr size_t kMaxHeadersCBORLength = 512 * 1024;
-
 constexpr char kMiHeader[] = "MI";
 
 net::CertVerifier* g_cert_verifier_for_testing = nullptr;
@@ -107,8 +103,8 @@
     return;
   }
 
-  // Triggering the read (asynchronously) for the encoded header length.
-  SetupBuffers(SignedExchangePrologue::kEncodedLengthInBytes);
+  // Triggering the read (asynchronously) for the prologue bytes.
+  SetupBuffers(SignedExchangePrologue::kEncodedPrologueInBytes);
   base::SequencedTaskRunnerHandle::Get()->PostTask(
       FROM_HERE, base::BindOnce(&SignedExchangeHandler::DoHeaderLoop,
                                 weak_factory_.GetWeakPtr()));
@@ -127,8 +123,7 @@
 }
 
 void SignedExchangeHandler::DoHeaderLoop() {
-  DCHECK(state_ == State::kReadingHeadersLength ||
-         state_ == State::kReadingHeaders);
+  DCHECK(state_ == State::kReadingPrologue || state_ == State::kReadingHeaders);
   int rv = source_->Read(
       header_read_buf_.get(), header_read_buf_->BytesRemaining(),
       base::BindRepeating(&SignedExchangeHandler::DidReadHeader,
@@ -138,8 +133,7 @@
 }
 
 void SignedExchangeHandler::DidReadHeader(bool completed_syncly, int result) {
-  DCHECK(state_ == State::kReadingHeadersLength ||
-         state_ == State::kReadingHeaders);
+  DCHECK(state_ == State::kReadingPrologue || state_ == State::kReadingHeaders);
 
   TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("loading"),
                      "SignedExchangeHandler::DidReadHeader");
@@ -162,8 +156,8 @@
   header_read_buf_->DidConsume(result);
   if (header_read_buf_->BytesRemaining() == 0) {
     switch (state_) {
-      case State::kReadingHeadersLength:
-        if (!ParseHeadersLength()) {
+      case State::kReadingPrologue:
+        if (!ParsePrologue()) {
           RunErrorCallback(net::ERR_INVALID_SIGNED_EXCHANGE);
           return;
         }
@@ -188,8 +182,7 @@
   }
 
   // Trigger the next read.
-  DCHECK(state_ == State::kReadingHeadersLength ||
-         state_ == State::kReadingHeaders);
+  DCHECK(state_ == State::kReadingPrologue || state_ == State::kReadingHeaders);
   if (completed_syncly) {
     base::SequencedTaskRunnerHandle::Get()->PostTask(
         FROM_HERE, base::BindOnce(&SignedExchangeHandler::DoHeaderLoop,
@@ -201,26 +194,19 @@
                    "SignedExchangeHandler::DidReadHeader");
 }
 
-bool SignedExchangeHandler::ParseHeadersLength() {
-  TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("loading"),
-                     "SignedExchangeHandler::ParseHeadersLength");
-  DCHECK_EQ(state_, State::kReadingHeadersLength);
+bool SignedExchangeHandler::ParsePrologue() {
+  DCHECK_EQ(state_, State::kReadingPrologue);
 
-  headers_length_ = SignedExchangePrologue::ParseEncodedLength(
+  prologue_ = SignedExchangePrologue::Parse(
       base::make_span(reinterpret_cast<uint8_t*>(header_buf_->data()),
-                      SignedExchangePrologue::kEncodedLengthInBytes));
-  if (headers_length_ == 0 || headers_length_ > kMaxHeadersCBORLength) {
-    signed_exchange_utils::ReportErrorAndEndTraceEvent(
-        devtools_proxy_.get(), "SignedExchangeHandler::ParseHeadersLength",
-        base::StringPrintf("Invalid CBOR header length: %zu", headers_length_));
+                      SignedExchangePrologue::kEncodedPrologueInBytes),
+      devtools_proxy_.get());
+  if (!prologue_)
     return false;
-  }
 
-  // Set up a new buffer for CBOR-encoded buffer reading.
-  SetupBuffers(headers_length_);
+  // Set up a new buffer for Signature + CBOR-encoded header reading.
+  SetupBuffers(prologue_->ComputeFollowingSectionsLength());
   state_ = State::kReadingHeaders;
-  TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("loading"),
-                   "SignedExchangeHandler::ParseHeadersLength");
   return true;
 }
 
@@ -229,10 +215,14 @@
                      "SignedExchangeHandler::ParseHeadersAndFetchCertificate");
   DCHECK_EQ(state_, State::kReadingHeaders);
 
-  header_ = SignedExchangeEnvelope::Parse(
-      base::make_span(reinterpret_cast<uint8_t*>(header_buf_->data()),
-                      headers_length_),
-      devtools_proxy_.get());
+  base::StringPiece data(header_buf_->data(), header_read_buf_->size());
+  base::StringPiece signature_header_field =
+      data.substr(0, prologue_->signature_header_field_length());
+  base::span<const uint8_t> cbor_header = base::as_bytes(
+      base::make_span(data.substr(prologue_->signature_header_field_length(),
+                                  prologue_->cbor_header_length())));
+  header_ = SignedExchangeEnvelope::Parse(signature_header_field, cbor_header,
+                                          devtools_proxy_.get());
   header_read_buf_ = nullptr;
   header_buf_ = nullptr;
   if (!header_) {
diff --git a/content/browser/web_package/signed_exchange_handler.h b/content/browser/web_package/signed_exchange_handler.h
index be9f98a8..0684b20 100644
--- a/content/browser/web_package/signed_exchange_handler.h
+++ b/content/browser/web_package/signed_exchange_handler.h
@@ -12,6 +12,7 @@
 #include "base/time/time.h"
 #include "content/browser/web_package/signed_exchange_consts.h"
 #include "content/browser/web_package/signed_exchange_envelope.h"
+#include "content/browser/web_package/signed_exchange_prologue.h"
 #include "content/common/content_export.h"
 #include "mojo/public/cpp/system/data_pipe.h"
 #include "net/base/completion_callback.h"
@@ -80,7 +81,7 @@
 
  private:
   enum class State {
-    kReadingHeadersLength,
+    kReadingPrologue,
     kReadingHeaders,
     kFetchingCertificate,
     kHeadersCallbackCalled,
@@ -89,7 +90,7 @@
   void SetupBuffers(size_t size);
   void DoHeaderLoop();
   void DidReadHeader(bool completed_syncly, int result);
-  bool ParseHeadersLength();
+  bool ParsePrologue();
   bool ParseHeadersAndFetchCertificate();
   void RunErrorCallback(net::Error);
 
@@ -102,12 +103,12 @@
   base::Optional<SignedExchangeVersion> version_;
   std::unique_ptr<net::SourceStream> source_;
 
-  State state_ = State::kReadingHeadersLength;
+  State state_ = State::kReadingPrologue;
   // Buffer used for header reading.
   scoped_refptr<net::IOBuffer> header_buf_;
   // Wrapper around |header_buf_| to progressively read fixed-size data.
   scoped_refptr<net::DrainableIOBuffer> header_read_buf_;
-  size_t headers_length_ = 0;
+  base::Optional<SignedExchangePrologue> prologue_;
 
   base::Optional<SignedExchangeEnvelope> header_;
 
diff --git a/content/browser/web_package/signed_exchange_handler_unittest.cc b/content/browser/web_package/signed_exchange_handler_unittest.cc
index 21c2189a..ac99319 100644
--- a/content/browser/web_package/signed_exchange_handler_unittest.cc
+++ b/content/browser/web_package/signed_exchange_handler_unittest.cc
@@ -313,8 +313,9 @@
   EXPECT_EQ(rv, static_cast<int>(expected_payload.size()));
 }
 
-TEST_P(SignedExchangeHandlerTest, ParseError) {
-  const uint8_t data[] = {0x00, 0x00, 0x01, 0x00};
+TEST_P(SignedExchangeHandlerTest, HeaderParseError) {
+  const uint8_t data[] = {'s',  'x',  'g',  '1',  '-',  'b',  '1',  '\0',
+                          0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00};
   source_->AddReadResult(reinterpret_cast<const char*>(data), sizeof(data),
                          net::OK, GetParam());
   WaitForHeader();
diff --git a/content/browser/web_package/signed_exchange_signature_verifier.cc b/content/browser/web_package/signed_exchange_signature_verifier.cc
index 4ff7f5f..9aeda87 100644
--- a/content/browser/web_package/signed_exchange_signature_verifier.cc
+++ b/content/browser/web_package/signed_exchange_signature_verifier.cc
@@ -29,7 +29,7 @@
 
 namespace {
 
-// https://wicg.github.io/webpackage/draft-yasskin-httpbis-origin-signed-exchanges-impl.html#signature-validity
+// https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html#signature-validity
 // Step 7. "Let message be the concatenation of the following byte strings."
 constexpr uint8_t kMessageHeader[] =
     // 7.1. "A string that consists of octet 32 (0x20) repeated 64 times."
@@ -38,10 +38,12 @@
     "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
     "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
     "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
-    // 7.2. "A context string: the ASCII encoding of "HTTP Exchange"."
+    // 7.2. "A context string: the ASCII encoding of "HTTP Exchange 1"." ...
+    // "but implementations of drafts MUST NOT use it and MUST use another
+    // draft-specific string beginning with "HTTP Exchange 1 " instead."
     // [spec text]
     // 7.3. "A single 0 byte which serves as a separator." [spec text]
-    "HTTP Exchange";
+    "HTTP Exchange 1 b1";
 
 base::Optional<cbor::CBORValue> GenerateCanonicalRequestCBOR(
     const SignedExchangeEnvelope& header) {
@@ -67,8 +69,6 @@
       cbor::CBORValue(kStatusKey, cbor::CBORValue::Type::BYTE_STRING),
       cbor::CBORValue(response_code_str, cbor::CBORValue::Type::BYTE_STRING));
   for (const auto& pair : headers) {
-    if (pair.first == kSignature)
-      continue;
     map.insert_or_assign(
         cbor::CBORValue(pair.first, cbor::CBORValue::Type::BYTE_STRING),
         cbor::CBORValue(pair.second, cbor::CBORValue::Type::BYTE_STRING));
diff --git a/content/browser/web_package/signed_exchange_signature_verifier_unittest.cc b/content/browser/web_package/signed_exchange_signature_verifier_unittest.cc
index 2ba3d3d..12e981f 100644
--- a/content/browser/web_package/signed_exchange_signature_verifier_unittest.cc
+++ b/content/browser/web_package/signed_exchange_signature_verifier_unittest.cc
@@ -66,11 +66,11 @@
 // clang-format off
 constexpr char kSignatureHeaderRSA[] =
     "label; "
-    "sig=*C0Oh9FEKos7Vk1bLyMazdZpgBTpPhIgnY3CDqyECut1HdMP2Ye8kxZXkT9BLQSv48leG"
-    "NS/hePxRtwJJybWMan/hFMhcz+s8aHxLT6E2e87iI9tNh29NPGGFVgiJ+hljSH/QAPP8sFIBb"
-    "pD/VGWy6NgpsSHft8DVlqhloBZMR9MUPXe36tdaOf5krUbY76Daj5kVQ0LZxrZhbzb97Bstvg"
-    "gVnTQe/RV1ElOql/xhYvsYxNgM0+Bkmu2hSWFMlLHMQ29LhMHS7oYUfuqqP2qhBj7VEArgDsC"
-    "hQ1W5r8K4WaI9krdvG3UsXlFufKbqGIQ2zKbeUWJUHoelkjb/ixBhwg==*; "
+    "sig=*RBFZPtl5xPDQyZuq4TcXY9fPkso5Edl7NofpdA9Bylwhvdsd7uCBAmOYx0BvXjrg8UVj"
+    "axIHeVNavLzTU42NZgSBd3po1qrT4TZb6piN/BMqmBWtaxEFxLaLZyBgrQpXN/l+OkWSvCF30"
+    "J9QEhqaI749SlVrrV37121Ik/WBIuo6Peo88HRP9292FEsrgwH3ggTJcTvkBbOIttO3UddEtN"
+    "3hQNNowNhsUCr3fXn0lIMW8Gyp0V6TVedIhgT7zqUxRqJRjedQzY+Bm7F01/jKzvD1etAcw7r"
+    "CidWFISmcyWjsLG1dlNtiZynO9gyyZduOSzBwEb9QcMTHekFsnmzFtg==*; "
     "validity-url=\"https://example.com/resource.validity.msg\"; "
     "integrity=\"mi\"; "
     "cert-url=\"https://example.com/cert.msg\"; "
@@ -82,8 +82,8 @@
 // clang-format off
 constexpr char kSignatureHeaderECDSAP256[] =
     "label; "
-    "sig=*MEUCIQCycBCSrsmT04lZBFklDiAdp2UkMoLhLKLv/79a39qqbgIgNI8ApHxPUPuXiko7"
-    "IPehUcU9i+jHGEYO3f0fKFn3dIg=*; "
+    "sig=*MEUCIEbg974hkbM6gy0bT4ZpO0afUtpeViz+mojLqtSnqepvAiEApKfMyaKxhE8xofyW"
+    "DlBjGTwsoOvNBycL9YfN9C72Rhs=*; "
     "validity-url=\"https://example.com/resource.validity.msg\"; "
     "integrity=\"mi\"; "
     "cert-url=\"https://example.com/cert.msg\"; "
@@ -95,8 +95,8 @@
 // clang-format off
 constexpr char kSignatureHeaderECDSAP384[] =
     "label; "
-    "sig=*MGUCMQCIdT4ipb0lb8AW+oxxXlv1F8kdhwoL9jsOJww2C3zTCM71Zsvu7U/BxcBCT5H7I"
-    "mkCMEatuNz+wa0q6pg2Zr3lYZ8Jy4xZbDJHVILmBqGMKxUVDGT3aw8/yJXPLPgSU6f6ZQ==*; "
+    "sig=*MGUCMQC2Sw+qw8pFB8S7gCqFdJlaimbZCA9BOOnjPHuRa8nGbYwnQBJEZnNwWxW+7ffwQ"
+    "skCMBVWAWya/ahn1XebSGAFeV8d6jC/xe9Rc8YCvb/KlV0tRxF0v06VasWcHx6OL8gZUg==*; "
     "validity-url=\"https://example.com/resource.validity.msg\"; "
     "integrity=\"mi\"; "
     "cert-url=\"https://example.com/cert.msg\"; "
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index c09bcb72..be996456 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -441,6 +441,9 @@
     WebRuntimeFeatures::EnableExperimentalProductivityFeatures(true);
   }
 
+  if (base::FeatureList::IsEnabled(features::kPageLifecycle))
+    WebRuntimeFeatures::EnablePageLifecycle(true);
+
 #if defined(OS_ANDROID)
   if (base::FeatureList::IsEnabled(features::kDisplayCutoutAPI))
     WebRuntimeFeatures::EnableDisplayCutoutAPI(true);
diff --git a/content/common/frame.mojom b/content/common/frame.mojom
index 0fc0e56..58393bd 100644
--- a/content/common/frame.mojom
+++ b/content/common/frame.mojom
@@ -91,7 +91,8 @@
       URLLoaderFactoryBundle? subresource_loader_factories,
       array<TransferrableURLLoader>? subresource_overrides,
       ControllerServiceWorkerInfo? controller_service_worker_info,
-      mojo_base.mojom.UnguessableToken devtools_navigation_token);
+      mojo_base.mojom.UnguessableToken devtools_navigation_token)
+      => (blink.mojom.CommitResult commit_result);
 
   // Tells the renderer that a failed navigation is ready to commit.
   //
@@ -108,7 +109,8 @@
       bool has_stale_copy_in_cache,
       int32 error_code,
       string? error_page_content,
-      URLLoaderFactoryBundle? subresource_loader_factories);
+      URLLoaderFactoryBundle? subresource_loader_factories)
+      => (blink.mojom.CommitResult commit_result);
 
   // Tells the renderer that a same-document navigation should be committed.
   // The renderer will return a status value indicating whether the commit
diff --git a/content/ppapi_plugin/ppapi_thread.cc b/content/ppapi_plugin/ppapi_thread.cc
index bb0abafb..5e7da13 100644
--- a/content/ppapi_plugin/ppapi_thread.cc
+++ b/content/ppapi_plugin/ppapi_thread.cc
@@ -200,6 +200,22 @@
   return base::SharedMemory::DuplicateHandle(handle);
 }
 
+base::UnsafeSharedMemoryRegion
+PpapiThread::ShareUnsafeSharedMemoryRegionWithRemote(
+    const base::UnsafeSharedMemoryRegion& region,
+    base::ProcessId remote_pid) {
+  DCHECK(remote_pid != base::kNullProcessId);
+  return region.Duplicate();
+}
+
+base::ReadOnlySharedMemoryRegion
+PpapiThread::ShareReadOnlySharedMemoryRegionWithRemote(
+    const base::ReadOnlySharedMemoryRegion& region,
+    base::ProcessId remote_pid) {
+  DCHECK(remote_pid != base::kNullProcessId);
+  return region.Duplicate();
+}
+
 std::set<PP_Instance>* PpapiThread::GetGloballySeenInstanceIDSet() {
   return &globally_seen_instance_ids_;
 }
diff --git a/content/ppapi_plugin/ppapi_thread.h b/content/ppapi_plugin/ppapi_thread.h
index f3425cb..b54f470 100644
--- a/content/ppapi_plugin/ppapi_thread.h
+++ b/content/ppapi_plugin/ppapi_thread.h
@@ -89,6 +89,12 @@
   base::SharedMemoryHandle ShareSharedMemoryHandleWithRemote(
       const base::SharedMemoryHandle& handle,
       base::ProcessId remote_pid) override;
+  base::UnsafeSharedMemoryRegion ShareUnsafeSharedMemoryRegionWithRemote(
+      const base::UnsafeSharedMemoryRegion& region,
+      base::ProcessId remote_pid) override;
+  base::ReadOnlySharedMemoryRegion ShareReadOnlySharedMemoryRegionWithRemote(
+      const base::ReadOnlySharedMemoryRegion& region,
+      base::ProcessId remote_pid) override;
   uint32_t Register(ppapi::proxy::PluginDispatcher* plugin_dispatcher) override;
   void Unregister(uint32_t plugin_dispatcher_id) override;
 
diff --git a/content/public/browser/devtools_agent_host_observer.cc b/content/public/browser/devtools_agent_host_observer.cc
index 3020923..0dc6ae58 100644
--- a/content/public/browser/devtools_agent_host_observer.cc
+++ b/content/public/browser/devtools_agent_host_observer.cc
@@ -32,4 +32,8 @@
     DevToolsAgentHost* agent_host) {
 }
 
+void DevToolsAgentHostObserver::DevToolsAgentHostCrashed(
+    DevToolsAgentHost* agent_host,
+    base::TerminationStatus status) {}
+
 }  // namespace content
diff --git a/content/public/browser/devtools_agent_host_observer.h b/content/public/browser/devtools_agent_host_observer.h
index 88d345e..a971b751 100644
--- a/content/public/browser/devtools_agent_host_observer.h
+++ b/content/public/browser/devtools_agent_host_observer.h
@@ -5,6 +5,7 @@
 #ifndef CONTENT_PUBLIC_BROWSER_DEVTOOLS_AGENT_HOST_OBSERVER_H_
 #define CONTENT_PUBLIC_BROWSER_DEVTOOLS_AGENT_HOST_OBSERVER_H_
 
+#include "base/process/kill.h"
 #include "content/common/content_export.h"
 
 namespace content {
@@ -33,6 +34,10 @@
   // Called when client has detached from DevToolsAgentHost.
   virtual void DevToolsAgentHostDetached(DevToolsAgentHost* agent_host);
 
+  // Called when DevToolsAgentHost crashed.
+  virtual void DevToolsAgentHostCrashed(DevToolsAgentHost* agent_host,
+                                        base::TerminationStatus status);
+
   // Called when DevToolsAgentHost was destroyed.
   virtual void DevToolsAgentHostDestroyed(DevToolsAgentHost* agent_host);
 };
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index b6a0838..2dbebfd 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -256,6 +256,10 @@
 const base::Feature kOriginTrials{"OriginTrials",
                                   base::FEATURE_ENABLED_BY_DEFAULT};
 
+// Blink PageLifecycle feature. See https://crbug.com/775194
+const base::Feature kPageLifecycle{"PageLifecycle",
+                                   base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Whether document level event listeners should default 'passive' to true.
 const base::Feature kPassiveDocumentEventListeners{
     "PassiveDocumentEventListeners", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
index 2134f63..c85d375 100644
--- a/content/public/common/content_features.h
+++ b/content/public/common/content_features.h
@@ -66,6 +66,7 @@
 CONTENT_EXPORT extern const base::Feature kOffMainThreadWebSocket;
 CONTENT_EXPORT extern const base::Feature kOriginManifest;
 CONTENT_EXPORT extern const base::Feature kOriginTrials;
+CONTENT_EXPORT extern const base::Feature kPageLifecycle;
 CONTENT_EXPORT extern const base::Feature kPassiveDocumentEventListeners;
 CONTENT_EXPORT extern const base::Feature kPassiveEventListenersDueToFling;
 CONTENT_EXPORT extern const base::Feature kPdfIsolation;
diff --git a/content/public/renderer/renderer_ppapi_host.h b/content/public/renderer/renderer_ppapi_host.h
index b376692d..5d56971 100644
--- a/content/public/renderer/renderer_ppapi_host.h
+++ b/content/public/renderer/renderer_ppapi_host.h
@@ -9,8 +9,10 @@
 
 #include "base/callback_forward.h"
 #include "base/files/file.h"
+#include "base/memory/read_only_shared_memory_region.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/shared_memory.h"
+#include "base/memory/unsafe_shared_memory_region.h"
 #include "base/process/process.h"
 #include "content/common/content_export.h"
 #include "ipc/ipc_platform_file.h"
@@ -119,6 +121,12 @@
   // message fails, the returned handle is properly closed by the IPC system.
   virtual base::SharedMemoryHandle ShareSharedMemoryHandleWithRemote(
       const base::SharedMemoryHandle& handle) = 0;
+  virtual base::UnsafeSharedMemoryRegion
+  ShareUnsafeSharedMemoryRegionWithRemote(
+      const base::UnsafeSharedMemoryRegion& region) = 0;
+  virtual base::ReadOnlySharedMemoryRegion
+  ShareReadOnlySharedMemoryRegionWithRemote(
+      const base::ReadOnlySharedMemoryRegion& region) = 0;
 
   // Returns true if the plugin is running in process.
   virtual bool IsRunningInProcess() const = 0;
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc
index 658487ec..fd52438 100644
--- a/content/public/test/browser_test_utils.cc
+++ b/content/public/test/browser_test_utils.cc
@@ -1472,6 +1472,24 @@
   return static_cast<WebContentsImpl*>(web_contents)->GetKeyboardLockWidget();
 }
 
+bool RequestKeyboardLock(WebContents* web_contents,
+                         base::Optional<base::flat_set<ui::DomCode>> codes) {
+  DCHECK(!codes.has_value() || !codes.value().empty());
+  WebContentsImpl* web_contents_impl =
+      static_cast<WebContentsImpl*>(web_contents);
+  RenderWidgetHostImpl* render_widget_host_impl =
+      web_contents_impl->GetMainFrame()->GetRenderWidgetHost();
+  return render_widget_host_impl->RequestKeyboardLock(std::move(codes));
+}
+
+void CancelKeyboardLock(WebContents* web_contents) {
+  WebContentsImpl* web_contents_impl =
+      static_cast<WebContentsImpl*>(web_contents);
+  RenderWidgetHostImpl* render_widget_host_impl =
+      web_contents_impl->GetMainFrame()->GetRenderWidgetHost();
+  render_widget_host_impl->CancelKeyboardLock();
+}
+
 bool IsInnerInterstitialPageConnected(InterstitialPage* interstitial_page) {
   InterstitialPageImpl* impl =
       static_cast<InterstitialPageImpl*>(interstitial_page);
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h
index ca80821..52fb5b6 100644
--- a/content/public/test/browser_test_utils.h
+++ b/content/public/test/browser_test_utils.h
@@ -11,11 +11,13 @@
 
 #include "base/callback.h"
 #include "base/compiler_specific.h"
+#include "base/containers/flat_set.h"
 #include "base/containers/queue.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
+#include "base/optional.h"
 #include "base/process/process.h"
 #include "base/run_loop.h"
 #include "base/strings/string16.h"
@@ -487,6 +489,15 @@
 // Returns the RenderWidgetHost that holds the keyboard lock.
 RenderWidgetHost* GetKeyboardLockWidget(WebContents* web_contents);
 
+// Allows tests to drive keyboard lock functionality without requiring access
+// to the RenderWidgetHostImpl header or setting up an HTTP test server.
+// |codes| represents the set of keys to lock.  If |codes| has no value, then
+// all keys will be considered locked.  If |codes| has a value, then at least
+// one key must be specified.
+bool RequestKeyboardLock(WebContents* web_contents,
+                         base::Optional<base::flat_set<ui::DomCode>> codes);
+void CancelKeyboardLock(WebContents* web_contents);
+
 // Returns true if inner |interstitial_page| is connected to an outer
 // WebContents.
 bool IsInnerInterstitialPageConnected(InterstitialPage* interstitial_page);
diff --git a/content/public/test/navigation_simulator.cc b/content/public/test/navigation_simulator.cc
index 47db84f..fb35a43d 100644
--- a/content/public/test/navigation_simulator.cc
+++ b/content/public/test/navigation_simulator.cc
@@ -477,6 +477,25 @@
     CHECK_EQ(1, num_did_finish_navigation_called_);
 }
 
+void NavigationSimulator::AbortCommit() {
+  CHECK_LE(state_, FAILED)
+      << "NavigationSimulator::AbortCommit cannot be called after "
+         "NavigationSimulator::Commit or  "
+         "NavigationSimulator::CommitErrorPage.";
+  if (state_ < READY_TO_COMMIT) {
+    ReadyToCommit();
+    if (state_ == FINISHED)
+      return;
+  }
+
+  CHECK(render_frame_host_) << "NavigationSimulator::AbortCommit can only be "
+                               "called for navigations that commit.";
+  render_frame_host_->AbortNavigationCommit();
+
+  state_ = FINISHED;
+  CHECK_EQ(1, num_did_finish_navigation_called_);
+}
+
 void NavigationSimulator::Fail(int error_code) {
   CHECK_LE(state_, STARTED) << "NavigationSimulator::Fail can only be "
                                "called once, and cannot be called after "
diff --git a/content/public/test/navigation_simulator.h b/content/public/test/navigation_simulator.h
index 3d7ee6b..223bd44c 100644
--- a/content/public/test/navigation_simulator.h
+++ b/content/public/test/navigation_simulator.h
@@ -193,6 +193,9 @@
   // Simulates the commit of the navigation in the RenderFrameHost.
   virtual void Commit();
 
+  // Simulates the commit of a navigation or an error page aborting.
+  virtual void AbortCommit();
+
   // Simulates the navigation failing with the error code |error_code|.
   virtual void Fail(int error_code);
 
diff --git a/content/renderer/media/audio_output_ipc_factory_unittest.cc b/content/renderer/media/audio_output_ipc_factory_unittest.cc
index 6f675a5..e64a920a 100644
--- a/content/renderer/media/audio_output_ipc_factory_unittest.cc
+++ b/content/renderer/media/audio_output_ipc_factory_unittest.cc
@@ -72,7 +72,7 @@
   void OnDeviceAuthorized(media::OutputDeviceStatus device_status,
                           const media::AudioParameters& output_params,
                           const std::string& matched_device_id) override {}
-  void OnStreamCreated(base::SharedMemoryHandle handle,
+  void OnStreamCreated(base::UnsafeSharedMemoryRegion region,
                        base::SyncSocket::Handle socket_handle,
                        bool playing_automatically) override {}
   void OnIPCClosed() override {}
diff --git a/content/renderer/media/mojo_audio_input_ipc.cc b/content/renderer/media/mojo_audio_input_ipc.cc
index 44b2e55..39d485d 100644
--- a/content/renderer/media/mojo_audio_input_ipc.cc
+++ b/content/renderer/media/mojo_audio_input_ipc.cc
@@ -104,14 +104,13 @@
       mojo::UnwrapPlatformFile(std::move(data_pipe->socket), &socket_handle);
   DCHECK_EQ(result, MOJO_RESULT_OK);
 
-  base::SharedMemoryHandle memory_handle;
-  mojo::UnwrappedSharedMemoryHandleProtection protection;
-  result = mojo::UnwrapSharedMemoryHandle(std::move(data_pipe->shared_memory),
-                                          &memory_handle, nullptr, &protection);
-  DCHECK_EQ(result, MOJO_RESULT_OK);
-  DCHECK_EQ(protection, mojo::UnwrappedSharedMemoryHandleProtection::kReadOnly);
+  base::ReadOnlySharedMemoryRegion shared_memory_region =
+      mojo::UnwrapReadOnlySharedMemoryRegion(
+          std::move(data_pipe->shared_memory));
+  DCHECK(shared_memory_region.IsValid());
 
-  delegate_->OnStreamCreated(memory_handle, socket_handle, initially_muted);
+  delegate_->OnStreamCreated(std::move(shared_memory_region), socket_handle,
+                             initially_muted);
 }
 
 void MojoAudioInputIPC::OnError() {
diff --git a/content/renderer/media/mojo_audio_input_ipc_unittest.cc b/content/renderer/media/mojo_audio_input_ipc_unittest.cc
index 540cb312..6a093b99 100644
--- a/content/renderer/media/mojo_audio_input_ipc_unittest.cc
+++ b/content/renderer/media/mojo_audio_input_ipc_unittest.cc
@@ -52,11 +52,9 @@
   MockDelegate() {}
   ~MockDelegate() override {}
 
-  void OnStreamCreated(base::SharedMemoryHandle mem_handle,
+  void OnStreamCreated(base::ReadOnlySharedMemoryRegion mem_handle,
                        base::SyncSocket::Handle socket_handle,
                        bool initially_muted) override {
-    base::SharedMemory sh_mem(
-        mem_handle, /*read_only*/ true);  // Releases the shared memory handle.
     base::SyncSocket socket(socket_handle);  // Releases the socket descriptor.
     GotOnStreamCreated(initially_muted);
   }
@@ -88,8 +86,8 @@
     factory_client_->StreamCreated(
         std::move(stream_ptr), mojo::MakeRequest(&stream_client_),
         {base::in_place,
-         mojo::SharedBufferHandle::Create(kMemoryLength)
-             ->Clone(mojo::SharedBufferHandle::AccessMode::READ_ONLY),
+         mojo::WrapReadOnlySharedMemoryRegion(
+             base::ReadOnlySharedMemoryRegion::Create(kMemoryLength).region),
          mojo::WrapPlatformFile(foreign_socket.Release())},
         initially_muted_, base::UnguessableToken::Create());
   }
diff --git a/content/renderer/media/mojo_audio_output_ipc.cc b/content/renderer/media/mojo_audio_output_ipc.cc
index 35ead19..c4734eb 100644
--- a/content/renderer/media/mojo_audio_output_ipc.cc
+++ b/content/renderer/media/mojo_audio_output_ipc.cc
@@ -228,17 +228,11 @@
       mojo::UnwrapPlatformFile(std::move(data_pipe->socket), &socket_handle);
   DCHECK_EQ(result, MOJO_RESULT_OK);
 
-  base::SharedMemoryHandle memory_handle;
-  mojo::UnwrappedSharedMemoryHandleProtection protection;
-  size_t memory_length = 0;
-  result = mojo::UnwrapSharedMemoryHandle(std::move(data_pipe->shared_memory),
-                                          &memory_handle, &memory_length,
-                                          &protection);
-  DCHECK_EQ(result, MOJO_RESULT_OK);
-  DCHECK_EQ(protection,
-            mojo::UnwrappedSharedMemoryHandleProtection::kReadWrite);
+  auto shared_memory_region =
+      mojo::UnwrapUnsafeSharedMemoryRegion(std::move(data_pipe->shared_memory));
+  DCHECK(shared_memory_region.IsValid());
 
-  delegate_->OnStreamCreated(memory_handle, socket_handle,
+  delegate_->OnStreamCreated(std::move(shared_memory_region), socket_handle,
                              expected_state_ == kPlaying);
 
   if (volume_)
diff --git a/content/renderer/media/mojo_audio_output_ipc_unittest.cc b/content/renderer/media/mojo_audio_output_ipc_unittest.cc
index 58be5468..bfd1db2 100644
--- a/content/renderer/media/mojo_audio_output_ipc_unittest.cc
+++ b/content/renderer/media/mojo_audio_output_ipc_unittest.cc
@@ -70,7 +70,9 @@
         base::CancelableSyncSocket::CreatePair(&socket_, &foreign_socket));
     provider_client_->Created(
         std::move(stream_ptr),
-        {base::in_place, mojo::SharedBufferHandle::Create(kMemoryLength),
+        {base::in_place,
+         mojo::WrapUnsafeSharedMemoryRegion(
+             base::UnsafeSharedMemoryRegion::Create(kMemoryLength)),
          mojo::WrapPlatformFile(foreign_socket.Release())});
   }
 
@@ -180,11 +182,9 @@
   MockDelegate() {}
   ~MockDelegate() override {}
 
-  void OnStreamCreated(base::SharedMemoryHandle mem_handle,
+  void OnStreamCreated(base::UnsafeSharedMemoryRegion mem_handle,
                        base::SyncSocket::Handle socket_handle,
                        bool playing_automatically) override {
-    base::SharedMemory sh_mem(
-        mem_handle, /*read_only*/ false);  // Releases the shared memory handle.
     base::SyncSocket socket(socket_handle);  // Releases the socket descriptor.
     GotOnStreamCreated();
   }
diff --git a/content/renderer/media/stream/media_stream_constraints_util_audio.cc b/content/renderer/media/stream/media_stream_constraints_util_audio.cc
index 69a8d3a..9445630 100644
--- a/content/renderer/media/stream/media_stream_constraints_util_audio.cc
+++ b/content/renderer/media/stream/media_stream_constraints_util_audio.cc
@@ -47,9 +47,6 @@
   NUM_BOOL_CONSTRAINTS
 };
 
-const char kEchoCancellerTypeBrowser[] = "browser";
-const char kEchoCancellerTypeSystem[] = "system";
-
 // This struct groups related fields or entries from AudioProcessingProperties,
 // SingleDeviceCandidateSet::bool_sets_ and blink::WebMediaTrackConstraintSet.
 struct AudioPropertyConstraintPair {
@@ -227,13 +224,13 @@
       // it's set up differently. The browser echo canceller is always available
       // when we don't have a source.
       std::vector<std::string> echo_cancellation_types = {
-          kEchoCancellerTypeBrowser};
+          blink::kEchoCancellationTypeBrowser};
 
       // Add the system (e.g. hardware) EC if available, based on the
       // parameters.
       if (parameters_.effects() &
           media::AudioParameters::EXPERIMENTAL_ECHO_CANCELLER) {
-        echo_cancellation_types.push_back(kEchoCancellerTypeSystem);
+        echo_cancellation_types.push_back(blink::kEchoCancellationTypeSystem);
       }
       echo_cancellation_type_set_ =
           DiscreteSet<std::string>(std::move(echo_cancellation_types));
@@ -277,10 +274,10 @@
     if (experimental_hardware_echo_cancellation_available &&
         !properties.enable_sw_echo_cancellation) {
       echo_cancellation_type_set_ =
-          DiscreteSet<std::string>({kEchoCancellerTypeSystem});
+          DiscreteSet<std::string>({blink::kEchoCancellationTypeSystem});
     } else if (properties.enable_sw_echo_cancellation) {
       echo_cancellation_type_set_ =
-          DiscreteSet<std::string>({kEchoCancellerTypeBrowser});
+          DiscreteSet<std::string>({blink::kEchoCancellationTypeBrowser});
     }
 
     bool_sets_[GOOG_AUDIO_MIRRORING] =
@@ -501,7 +498,7 @@
 
     properties.enable_experimental_hw_echo_cancellation =
         (echo_cancellation_type &&
-         *echo_cancellation_type == kEchoCancellerTypeSystem) &&
+         *echo_cancellation_type == blink::kEchoCancellationTypeSystem) &&
         !properties.disable_hw_echo_cancellation;
 
     properties.enable_sw_echo_cancellation = SelectEnableSwEchoCancellation(
diff --git a/content/renderer/media/stream/user_media_processor.cc b/content/renderer/media/stream/user_media_processor.cc
index 41674c1..bd63ad97 100644
--- a/content/renderer/media/stream/user_media_processor.cc
+++ b/content/renderer/media/stream/user_media_processor.cc
@@ -856,6 +856,15 @@
 
   blink::WebMediaStreamSource::Capabilities capabilities;
   capabilities.echo_cancellation = {true, false};
+  capabilities.echo_cancellation_type.reserve(2);
+  capabilities.echo_cancellation_type.emplace_back(
+      blink::WebString::FromASCII(blink::kEchoCancellationTypeBrowser));
+  if (device.input.effects() &
+      (media::AudioParameters::ECHO_CANCELLER |
+       media::AudioParameters::EXPERIMENTAL_ECHO_CANCELLER)) {
+    capabilities.echo_cancellation_type.emplace_back(
+        blink::WebString::FromASCII(blink::kEchoCancellationTypeSystem));
+  }
   capabilities.auto_gain_control = {true, false};
   capabilities.noise_suppression = {true, false};
   capabilities.device_id = blink::WebString::FromUTF8(device.id);
diff --git a/content/renderer/media/webrtc/rtc_video_decoder.cc b/content/renderer/media/webrtc/rtc_video_decoder.cc
index 238e3a9d..d406787 100644
--- a/content/renderer/media/webrtc/rtc_video_decoder.cc
+++ b/content/renderer/media/webrtc/rtc_video_decoder.cc
@@ -13,6 +13,7 @@
 #include "base/numerics/safe_conversions.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/task_runner_util.h"
+#include "build/build_config.h"
 #include "content/renderer/media/webrtc/webrtc_video_frame_adapter.h"
 #include "gpu/command_buffer/common/mailbox_holder.h"
 #include "media/base/bind_to_current_loop.h"
@@ -157,14 +158,25 @@
 }
 
 int32_t RTCVideoDecoder::Decode(
-    const webrtc::EncodedImage& inputImage,
-    bool missingFrames,
-    const webrtc::CodecSpecificInfo* /*codecSpecificInfo*/,
-    int64_t /*renderTimeMs*/) {
+    const webrtc::EncodedImage& input_image,
+    bool missing_frames,
+    const webrtc::CodecSpecificInfo* codec_specific_info,
+    int64_t render_time_ms) {
   DVLOG(3) << "Decode";
+  DCHECK(!codec_specific_info ||
+         video_codec_type_ == codec_specific_info->codecType);
+
+#if defined(OS_WIN)
+  // Hardware VP9 decoders don't handle more than one spatial layer. Fall back
+  // to software decoding. See https://crbug.com/webrtc/9304.
+  if (video_codec_type_ == webrtc::kVideoCodecVP9 && codec_specific_info &&
+      codec_specific_info->codecSpecific.VP9.ss_data_available &&
+      codec_specific_info->codecSpecific.VP9.num_spatial_layers > 1) {
+    return WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
+  }
+#endif  // defined(OS_WIN)
 
   base::AutoLock auto_lock(lock_);
-
   if (state_ == UNINITIALIZED || !decode_complete_callback_) {
     LOG(ERROR) << "The decoder has not initialized.";
     return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
@@ -180,7 +192,7 @@
     return WEBRTC_VIDEO_CODEC_ERROR;
   }
 
-  if (missingFrames || !inputImage._completeFrame) {
+  if (missing_frames || !input_image._completeFrame) {
     DLOG(ERROR) << "Missing or incomplete frames.";
     // Unlike the SW decoder in libvpx, hw decoder cannot handle broken frames.
     // Return an error to request a key frame.
@@ -198,8 +210,8 @@
 #endif
 
   bool need_to_reset_for_midstream_resize = false;
-  const gfx::Size new_frame_size(inputImage._encodedWidth,
-                                 inputImage._encodedHeight);
+  const gfx::Size new_frame_size(input_image._encodedWidth,
+                                 input_image._encodedHeight);
   if (!new_frame_size.IsEmpty() && new_frame_size != frame_size_) {
     DVLOG(2) << "Got new size=" << new_frame_size.ToString();
 
@@ -230,10 +242,8 @@
   }
 
   // Create buffer metadata.
-  BufferData buffer_data(next_bitstream_buffer_id_,
-                         inputImage._timeStamp,
-                         inputImage._length,
-                         gfx::Rect(frame_size_));
+  BufferData buffer_data(next_bitstream_buffer_id_, input_image._timeStamp,
+                         input_image._length, gfx::Rect(frame_size_));
   // Mask against 30 bits, to avoid (undefined) wraparound on signed integer.
   next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & ID_LAST;
 
@@ -242,9 +252,9 @@
   // immediately. Otherwise, save the buffer in the queue for later decode.
   std::unique_ptr<base::SharedMemory> shm_buffer;
   if (!need_to_reset_for_midstream_resize && pending_buffers_.empty())
-    shm_buffer = GetSHM_Locked(inputImage._length);
+    shm_buffer = GetSHM_Locked(input_image._length);
   if (!shm_buffer) {
-    if (!SaveToPendingBuffers_Locked(inputImage, buffer_data)) {
+    if (!SaveToPendingBuffers_Locked(input_image, buffer_data)) {
       // We have exceeded the pending buffers count, we are severely behind.
       // Since we are returning ERROR, WebRTC will not be interested in the
       // remaining buffers, and will provide us with a new keyframe instead.
@@ -263,7 +273,7 @@
     return WEBRTC_VIDEO_CODEC_OK;
   }
 
-  SaveToDecodeBuffers_Locked(inputImage, std::move(shm_buffer), buffer_data);
+  SaveToDecodeBuffers_Locked(input_image, std::move(shm_buffer), buffer_data);
   factories_->GetTaskRunner()->PostTask(
       FROM_HERE, base::BindOnce(&RTCVideoDecoder::RequestBufferDecode,
                                 weak_factory_.GetWeakPtr()));
diff --git a/content/renderer/navigation_client.cc b/content/renderer/navigation_client.cc
index 18f6c8e..a52cbf74 100644
--- a/content/renderer/navigation_client.cc
+++ b/content/renderer/navigation_client.cc
@@ -32,7 +32,8 @@
       head, common_params, request_params,
       std::move(url_loader_client_endpoints), std::move(subresource_loaders),
       std::move(subresource_overrides),
-      std::move(controller_service_worker_info), devtools_navigation_token);
+      std::move(controller_service_worker_info), devtools_navigation_token,
+      mojom::FrameNavigationControl::CommitNavigationCallback());
 }
 
 void NavigationClient::CommitFailedNavigation(
@@ -45,7 +46,8 @@
   ResetDisconnectionHandler();
   render_frame_->CommitFailedNavigation(
       common_params, request_params, has_stale_copy_in_cache, error_code,
-      error_page_content, std::move(subresource_loaders));
+      error_page_content, std::move(subresource_loaders),
+      mojom::FrameNavigationControl::CommitFailedNavigationCallback());
 }
 
 void NavigationClient::Bind(mojom::NavigationClientAssociatedRequest request) {
diff --git a/content/renderer/navigation_state_impl.cc b/content/renderer/navigation_state_impl.cc
index 80ee5e3b..5b9e23f 100644
--- a/content/renderer/navigation_state_impl.cc
+++ b/content/renderer/navigation_state_impl.cc
@@ -7,20 +7,23 @@
 namespace content {
 
 NavigationStateImpl::~NavigationStateImpl() {
+  RunCommitNavigationCallback(blink::mojom::CommitResult::Aborted);
 }
 
 NavigationStateImpl* NavigationStateImpl::CreateBrowserInitiated(
     const CommonNavigationParams& common_params,
     const RequestNavigationParams& request_params,
-    base::TimeTicks time_commit_requested) {
+    base::TimeTicks time_commit_requested,
+    mojom::FrameNavigationControl::CommitNavigationCallback callback) {
   return new NavigationStateImpl(common_params, request_params,
-                                 time_commit_requested, false);
+                                 time_commit_requested, false,
+                                 std::move(callback));
 }
 
 NavigationStateImpl* NavigationStateImpl::CreateContentInitiated() {
-  return new NavigationStateImpl(CommonNavigationParams(),
-                                 RequestNavigationParams(), base::TimeTicks(),
-                                 true);
+  return new NavigationStateImpl(
+      CommonNavigationParams(), RequestNavigationParams(), base::TimeTicks(),
+      true, content::mojom::FrameNavigationControl::CommitNavigationCallback());
 }
 
 ui::PageTransition NavigationStateImpl::GetTransitionType() {
@@ -35,17 +38,25 @@
   return is_content_initiated_;
 }
 
+void NavigationStateImpl::RunCommitNavigationCallback(
+    blink::mojom::CommitResult result) {
+  if (commit_callback_)
+    std::move(commit_callback_).Run(result);
+}
+
 NavigationStateImpl::NavigationStateImpl(
     const CommonNavigationParams& common_params,
     const RequestNavigationParams& request_params,
     base::TimeTicks time_commit_requested,
-    bool is_content_initiated)
+    bool is_content_initiated,
+    mojom::FrameNavigationControl::CommitNavigationCallback callback)
     : request_committed_(false),
       was_within_same_document_(false),
       is_content_initiated_(is_content_initiated),
       common_params_(common_params),
       request_params_(request_params),
       time_commit_requested_(time_commit_requested),
-      navigation_client_(nullptr) {}
+      navigation_client_(nullptr),
+      commit_callback_(std::move(callback)) {}
 
 }  // namespace content
diff --git a/content/renderer/navigation_state_impl.h b/content/renderer/navigation_state_impl.h
index dd0da764..8ea0ec0 100644
--- a/content/renderer/navigation_state_impl.h
+++ b/content/renderer/navigation_state_impl.h
@@ -8,9 +8,11 @@
 #include <string>
 
 #include "base/macros.h"
+#include "content/common/frame.mojom.h"
 #include "content/common/navigation_params.h"
 #include "content/public/renderer/navigation_state.h"
 #include "content/renderer/navigation_client.h"
+#include "third_party/blink/public/web/commit_result.mojom.h"
 
 namespace content {
 
@@ -21,7 +23,8 @@
   static NavigationStateImpl* CreateBrowserInitiated(
       const CommonNavigationParams& common_params,
       const RequestNavigationParams& request_params,
-      base::TimeTicks time_commit_requested);
+      base::TimeTicks time_commit_requested,
+      mojom::FrameNavigationControl::CommitNavigationCallback callback);
 
   static NavigationStateImpl* CreateContentInitiated();
 
@@ -54,11 +57,16 @@
     navigation_client_ = std::move(navigation_client_impl);
   }
 
+  void RunCommitNavigationCallback(blink::mojom::CommitResult result);
+
  private:
-  NavigationStateImpl(const CommonNavigationParams& common_params,
-                      const RequestNavigationParams& request_params,
-                      base::TimeTicks time_commit_requested,
-                      bool is_content_initiated);
+  NavigationStateImpl(
+      const CommonNavigationParams& common_params,
+      const RequestNavigationParams& request_params,
+      base::TimeTicks time_commit_requested,
+      bool is_content_initiated,
+      content::mojom::FrameNavigationControl::CommitNavigationCallback
+          callback);
 
   bool request_committed_;
   bool was_within_same_document_;
@@ -89,6 +97,10 @@
   // Only used when PerNavigationMojoInterface is enabled.
   std::unique_ptr<NavigationClient> navigation_client_;
 
+  // Used to notify whether a commit request from the browser process was
+  // successful or not.
+  mojom::FrameNavigationControl::CommitNavigationCallback commit_callback_;
+
   DISALLOW_COPY_AND_ASSIGN(NavigationStateImpl);
 };
 
diff --git a/content/renderer/pepper/audio_helper.cc b/content/renderer/pepper/audio_helper.cc
index fd92532..81ed67b 100644
--- a/content/renderer/pepper/audio_helper.cc
+++ b/content/renderer/pepper/audio_helper.cc
@@ -15,7 +15,7 @@
 
 // AudioHelper -----------------------------------------------------------------
 
-AudioHelper::AudioHelper() : shared_memory_size_for_create_callback_(0) {}
+AudioHelper::AudioHelper() {}
 
 AudioHelper::~AudioHelper() {}
 
@@ -28,26 +28,22 @@
   return PP_ERROR_FAILED;
 }
 
-int32_t AudioHelper::GetSharedMemoryImpl(base::SharedMemory** shm,
-                                         uint32_t* shm_size) {
-  if (shared_memory_for_create_callback_) {
-    *shm = shared_memory_for_create_callback_.get();
-    *shm_size = shared_memory_size_for_create_callback_;
+int32_t AudioHelper::GetSharedMemoryImpl(base::UnsafeSharedMemoryRegion** shm) {
+  if (shared_memory_for_create_callback_.IsValid()) {
+    *shm = &shared_memory_for_create_callback_;
     return PP_OK;
   }
   return PP_ERROR_FAILED;
 }
 
-void AudioHelper::StreamCreated(base::SharedMemoryHandle shared_memory_handle,
-                                size_t shared_memory_size,
-                                base::SyncSocket::Handle socket_handle) {
+void AudioHelper::StreamCreated(
+    base::UnsafeSharedMemoryRegion shared_memory_region,
+    base::SyncSocket::Handle socket_handle) {
   if (TrackedCallback::IsPending(create_callback_)) {
     // Trusted side of proxy can specify a callback to receive handles. In
     // this case we don't need to map any data or start the thread since it
     // will be handled by the proxy.
-    shared_memory_for_create_callback_.reset(
-        new base::SharedMemory(shared_memory_handle, false));
-    shared_memory_size_for_create_callback_ = shared_memory_size;
+    shared_memory_for_create_callback_ = std::move(shared_memory_region);
     socket_for_create_callback_.reset(new base::SyncSocket(socket_handle));
 
     create_callback_->Run(PP_OK);
@@ -60,7 +56,7 @@
     // the I/O thread and back, but this extra complexity doesn't seem worth it
     // just to clean up these handles faster.
   } else {
-    OnSetStreamInfo(shared_memory_handle, shared_memory_size, socket_handle);
+    OnSetStreamInfo(std::move(shared_memory_region), socket_handle);
   }
 }
 
diff --git a/content/renderer/pepper/audio_helper.h b/content/renderer/pepper/audio_helper.h
index 1d4a543..d541169 100644
--- a/content/renderer/pepper/audio_helper.h
+++ b/content/renderer/pepper/audio_helper.h
@@ -11,7 +11,7 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "base/memory/shared_memory.h"
+#include "base/memory/unsafe_shared_memory_region.h"
 #include "base/sync_socket.h"
 #include "ppapi/c/pp_completion_callback.h"
 #include "ppapi/shared_impl/resource.h"
@@ -26,8 +26,7 @@
   virtual ~AudioHelper();
 
   // Called when the stream is created.
-  void StreamCreated(base::SharedMemoryHandle shared_memory_handle,
-                     size_t shared_memory_size_,
+  void StreamCreated(base::UnsafeSharedMemoryRegion shared_memory_region,
                      base::SyncSocket::Handle socket);
 
   void SetCreateCallback(scoped_refptr<ppapi::TrackedCallback> create_callback);
@@ -37,12 +36,12 @@
 
   // To be called by implementations of |PPB_Audio_API|/|PPB_AudioInput_API|.
   int32_t GetSyncSocketImpl(int* sync_socket);
-  int32_t GetSharedMemoryImpl(base::SharedMemory** shm, uint32_t* shm_size);
+  int32_t GetSharedMemoryImpl(base::UnsafeSharedMemoryRegion** shm);
 
   // To be implemented by subclasses to call their |SetStreamInfo()|.
-  virtual void OnSetStreamInfo(base::SharedMemoryHandle shared_memory_handle,
-                               size_t shared_memory_size,
-                               base::SyncSocket::Handle socket_handle) = 0;
+  virtual void OnSetStreamInfo(
+      base::UnsafeSharedMemoryRegion shared_memory_region,
+      base::SyncSocket::Handle socket_handle) = 0;
 
  private:
   scoped_refptr<ppapi::TrackedCallback> create_callback_;
@@ -51,8 +50,7 @@
   // querying from the callback. The proxy uses this to get the handles to the
   // other process instead of mapping them in the renderer. These will be
   // invalid all other times.
-  std::unique_ptr<base::SharedMemory> shared_memory_for_create_callback_;
-  size_t shared_memory_size_for_create_callback_;
+  base::UnsafeSharedMemoryRegion shared_memory_for_create_callback_;
   std::unique_ptr<base::SyncSocket> socket_for_create_callback_;
 
   DISALLOW_COPY_AND_ASSIGN(AudioHelper);
diff --git a/content/renderer/pepper/mock_renderer_ppapi_host.cc b/content/renderer/pepper/mock_renderer_ppapi_host.cc
index ad9a0df..80e59655 100644
--- a/content/renderer/pepper/mock_renderer_ppapi_host.cc
+++ b/content/renderer/pepper/mock_renderer_ppapi_host.cc
@@ -85,6 +85,20 @@
   return base::SharedMemoryHandle();
 }
 
+base::UnsafeSharedMemoryRegion
+MockRendererPpapiHost::ShareUnsafeSharedMemoryRegionWithRemote(
+    const base::UnsafeSharedMemoryRegion& region) {
+  NOTIMPLEMENTED();
+  return base::UnsafeSharedMemoryRegion();
+}
+
+base::ReadOnlySharedMemoryRegion
+MockRendererPpapiHost::ShareReadOnlySharedMemoryRegionWithRemote(
+    const base::ReadOnlySharedMemoryRegion& region) {
+  NOTIMPLEMENTED();
+  return base::ReadOnlySharedMemoryRegion();
+}
+
 bool MockRendererPpapiHost::IsRunningInProcess() const { return false; }
 
 std::string MockRendererPpapiHost::GetPluginName() const {
diff --git a/content/renderer/pepper/mock_renderer_ppapi_host.h b/content/renderer/pepper/mock_renderer_ppapi_host.h
index 375c212..fedbf7c9 100644
--- a/content/renderer/pepper/mock_renderer_ppapi_host.h
+++ b/content/renderer/pepper/mock_renderer_ppapi_host.h
@@ -48,6 +48,10 @@
       bool should_close_source) override;
   base::SharedMemoryHandle ShareSharedMemoryHandleWithRemote(
       const base::SharedMemoryHandle& handle) override;
+  base::UnsafeSharedMemoryRegion ShareUnsafeSharedMemoryRegionWithRemote(
+      const base::UnsafeSharedMemoryRegion& region) override;
+  base::ReadOnlySharedMemoryRegion ShareReadOnlySharedMemoryRegionWithRemote(
+      const base::ReadOnlySharedMemoryRegion& region) override;
   bool IsRunningInProcess() const override;
   std::string GetPluginName() const override;
   void SetToExternalPluginHost() override;
diff --git a/content/renderer/pepper/pepper_audio_input_host.cc b/content/renderer/pepper/pepper_audio_input_host.cc
index 1ca9e46..08f47d7 100644
--- a/content/renderer/pepper/pepper_audio_input_host.cc
+++ b/content/renderer/pepper/pepper_audio_input_host.cc
@@ -52,14 +52,13 @@
 }
 
 void PepperAudioInputHost::StreamCreated(
-    base::SharedMemoryHandle shared_memory_handle,
-    size_t shared_memory_size,
+    base::ReadOnlySharedMemoryRegion shared_memory_region,
     base::SyncSocket::Handle socket) {
-  OnOpenComplete(PP_OK, shared_memory_handle, shared_memory_size, socket);
+  OnOpenComplete(PP_OK, std::move(shared_memory_region), socket);
 }
 
 void PepperAudioInputHost::StreamCreationFailed() {
-  OnOpenComplete(PP_ERROR_FAILED, base::SharedMemoryHandle(), 0,
+  OnOpenComplete(PP_ERROR_FAILED, base::ReadOnlySharedMemoryRegion(),
                  base::SyncSocket::kInvalidHandle);
 }
 
@@ -113,12 +112,10 @@
 
 void PepperAudioInputHost::OnOpenComplete(
     int32_t result,
-    base::SharedMemoryHandle shared_memory_handle,
-    size_t shared_memory_size,
+    base::ReadOnlySharedMemoryRegion shared_memory_region,
     base::SyncSocket::Handle socket_handle) {
   // Make sure the handles are cleaned up.
   base::SyncSocket scoped_socket(socket_handle);
-  base::SharedMemory scoped_shared_memory(shared_memory_handle, false);
 
   if (!open_context_.is_valid()) {
     NOTREACHED();
@@ -128,17 +125,19 @@
   ppapi::proxy::SerializedHandle serialized_socket_handle(
       ppapi::proxy::SerializedHandle::SOCKET);
   ppapi::proxy::SerializedHandle serialized_shared_memory_handle(
-      ppapi::proxy::SerializedHandle::SHARED_MEMORY);
+      ppapi::proxy::SerializedHandle::SHARED_MEMORY_REGION);
 
   if (result == PP_OK) {
     IPC::PlatformFileForTransit temp_socket =
         IPC::InvalidPlatformFileForTransit();
-    base::SharedMemoryHandle temp_shmem;
-    result = GetRemoteHandles(
-        scoped_socket, scoped_shared_memory, &temp_socket, &temp_shmem);
+    base::ReadOnlySharedMemoryRegion temp_shmem;
+    result = GetRemoteHandles(scoped_socket, shared_memory_region, &temp_socket,
+                              &temp_shmem);
 
     serialized_socket_handle.set_socket(temp_socket);
-    serialized_shared_memory_handle.set_shmem(temp_shmem, shared_memory_size);
+    serialized_shared_memory_handle.set_shmem_region(
+        base::ReadOnlySharedMemoryRegion::TakeHandleForSerialization(
+            std::move(temp_shmem)));
   }
 
   // Send all the values, even on error. This simplifies some of our cleanup
@@ -153,18 +152,18 @@
 
 int32_t PepperAudioInputHost::GetRemoteHandles(
     const base::SyncSocket& socket,
-    const base::SharedMemory& shared_memory,
+    const base::ReadOnlySharedMemoryRegion& shared_memory_region,
     IPC::PlatformFileForTransit* remote_socket_handle,
-    base::SharedMemoryHandle* remote_shared_memory_handle) {
+    base::ReadOnlySharedMemoryRegion* remote_shared_memory_region) {
   *remote_socket_handle =
       renderer_ppapi_host_->ShareHandleWithRemote(socket.handle(), false);
   if (*remote_socket_handle == IPC::InvalidPlatformFileForTransit())
     return PP_ERROR_FAILED;
 
-  *remote_shared_memory_handle =
-      renderer_ppapi_host_->ShareSharedMemoryHandleWithRemote(
-          shared_memory.handle());
-  if (!base::SharedMemory::IsHandleValid(*remote_shared_memory_handle))
+  *remote_shared_memory_region =
+      renderer_ppapi_host_->ShareReadOnlySharedMemoryRegionWithRemote(
+          shared_memory_region);
+  if (!remote_shared_memory_region->IsValid())
     return PP_ERROR_FAILED;
 
   return PP_OK;
diff --git a/content/renderer/pepper/pepper_audio_input_host.h b/content/renderer/pepper/pepper_audio_input_host.h
index 084ce33e..366d94a1b 100644
--- a/content/renderer/pepper/pepper_audio_input_host.h
+++ b/content/renderer/pepper/pepper_audio_input_host.h
@@ -13,7 +13,7 @@
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
-#include "base/memory/shared_memory.h"
+#include "base/memory/read_only_shared_memory_region.h"
 #include "base/sync_socket.h"
 #include "content/renderer/pepper/pepper_device_enumeration_host_helper.h"
 #include "ipc/ipc_platform_file.h"
@@ -37,8 +37,7 @@
       ppapi::host::HostMessageContext* context) override;
 
   // Called when the stream is created.
-  void StreamCreated(base::SharedMemoryHandle shared_memory_handle,
-                     size_t shared_memory_size,
+  void StreamCreated(base::ReadOnlySharedMemoryRegion shared_memory_region,
                      base::SyncSocket::Handle socket);
   void StreamCreationFailed();
 
@@ -51,15 +50,14 @@
   int32_t OnClose(ppapi::host::HostMessageContext* context);
 
   void OnOpenComplete(int32_t result,
-                      base::SharedMemoryHandle shared_memory_handle,
-                      size_t shared_memory_size,
+                      base::ReadOnlySharedMemoryRegion shared_memory_region,
                       base::SyncSocket::Handle socket_handle);
 
   int32_t GetRemoteHandles(
       const base::SyncSocket& socket,
-      const base::SharedMemory& shared_memory,
+      const base::ReadOnlySharedMemoryRegion& shared_memory_region,
       IPC::PlatformFileForTransit* remote_socket_handle,
-      base::SharedMemoryHandle* remote_shared_memory_handle);
+      base::ReadOnlySharedMemoryRegion* remote_shared_memory_region);
 
   void Close();
 
diff --git a/content/renderer/pepper/pepper_audio_output_host.cc b/content/renderer/pepper/pepper_audio_output_host.cc
index 15ec4610..49a4bb62 100644
--- a/content/renderer/pepper/pepper_audio_output_host.cc
+++ b/content/renderer/pepper/pepper_audio_output_host.cc
@@ -71,14 +71,13 @@
 }
 
 void PepperAudioOutputHost::StreamCreated(
-    base::SharedMemoryHandle shared_memory_handle,
-    size_t shared_memory_size,
+    base::UnsafeSharedMemoryRegion shared_memory_region,
     base::SyncSocket::Handle socket) {
-  OnOpenComplete(PP_OK, shared_memory_handle, shared_memory_size, socket);
+  OnOpenComplete(PP_OK, std::move(shared_memory_region), socket);
 }
 
 void PepperAudioOutputHost::StreamCreationFailed() {
-  OnOpenComplete(PP_ERROR_FAILED, base::SharedMemoryHandle(), 0,
+  OnOpenComplete(PP_ERROR_FAILED, base::UnsafeSharedMemoryRegion(),
                  base::SyncSocket::kInvalidHandle);
 }
 
@@ -150,12 +149,10 @@
 
 void PepperAudioOutputHost::OnOpenComplete(
     int32_t result,
-    base::SharedMemoryHandle shared_memory_handle,
-    size_t shared_memory_size,
+    base::UnsafeSharedMemoryRegion shared_memory_region,
     base::SyncSocket::Handle socket_handle) {
   // Make sure the handles are cleaned up.
   base::SyncSocket scoped_socket(socket_handle);
-  base::SharedMemory scoped_shared_memory(shared_memory_handle, false);
 
   if (!open_context_.is_valid()) {
     NOTREACHED();
@@ -165,17 +162,19 @@
   ppapi::proxy::SerializedHandle serialized_socket_handle(
       ppapi::proxy::SerializedHandle::SOCKET);
   ppapi::proxy::SerializedHandle serialized_shared_memory_handle(
-      ppapi::proxy::SerializedHandle::SHARED_MEMORY);
+      ppapi::proxy::SerializedHandle::SHARED_MEMORY_REGION);
 
   if (result == PP_OK) {
     IPC::PlatformFileForTransit temp_socket =
         IPC::InvalidPlatformFileForTransit();
-    base::SharedMemoryHandle temp_shmem;
-    result = GetRemoteHandles(scoped_socket, scoped_shared_memory, &temp_socket,
+    base::UnsafeSharedMemoryRegion temp_shmem;
+    result = GetRemoteHandles(scoped_socket, shared_memory_region, &temp_socket,
                               &temp_shmem);
 
     serialized_socket_handle.set_socket(temp_socket);
-    serialized_shared_memory_handle.set_shmem(temp_shmem, shared_memory_size);
+    serialized_shared_memory_handle.set_shmem_region(
+        base::UnsafeSharedMemoryRegion::TakeHandleForSerialization(
+            std::move(temp_shmem)));
   }
 
   // Send all the values, even on error. This simplifies some of our cleanup
@@ -190,18 +189,18 @@
 
 int32_t PepperAudioOutputHost::GetRemoteHandles(
     const base::SyncSocket& socket,
-    const base::SharedMemory& shared_memory,
+    const base::UnsafeSharedMemoryRegion& shared_memory_region,
     IPC::PlatformFileForTransit* remote_socket_handle,
-    base::SharedMemoryHandle* remote_shared_memory_handle) {
+    base::UnsafeSharedMemoryRegion* remote_shared_memory_region) {
   *remote_socket_handle =
       renderer_ppapi_host_->ShareHandleWithRemote(socket.handle(), false);
   if (*remote_socket_handle == IPC::InvalidPlatformFileForTransit())
     return PP_ERROR_FAILED;
 
-  *remote_shared_memory_handle =
-      renderer_ppapi_host_->ShareSharedMemoryHandleWithRemote(
-          shared_memory.handle());
-  if (!base::SharedMemory::IsHandleValid(*remote_shared_memory_handle))
+  *remote_shared_memory_region =
+      renderer_ppapi_host_->ShareUnsafeSharedMemoryRegionWithRemote(
+          shared_memory_region);
+  if (!remote_shared_memory_region->IsValid())
     return PP_ERROR_FAILED;
 
   return PP_OK;
diff --git a/content/renderer/pepper/pepper_audio_output_host.h b/content/renderer/pepper/pepper_audio_output_host.h
index e8ea573..ea2602a 100644
--- a/content/renderer/pepper/pepper_audio_output_host.h
+++ b/content/renderer/pepper/pepper_audio_output_host.h
@@ -13,7 +13,7 @@
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
-#include "base/memory/shared_memory.h"
+#include "base/memory/unsafe_shared_memory_region.h"
 #include "base/sync_socket.h"
 #include "content/public/renderer/plugin_instance_throttler.h"
 #include "content/renderer/pepper/pepper_device_enumeration_host_helper.h"
@@ -39,8 +39,7 @@
       ppapi::host::HostMessageContext* context) override;
 
   // Called when the stream is created.
-  void StreamCreated(base::SharedMemoryHandle shared_memory_handle,
-                     size_t shared_memory_size,
+  void StreamCreated(base::UnsafeSharedMemoryRegion shared_memory_region,
                      base::SyncSocket::Handle socket);
   void StreamCreationFailed();
   void SetVolume(double volume);
@@ -55,15 +54,14 @@
   int32_t OnClose(ppapi::host::HostMessageContext* context);
 
   void OnOpenComplete(int32_t result,
-                      base::SharedMemoryHandle shared_memory_handle,
-                      size_t shared_memory_size,
+                      base::UnsafeSharedMemoryRegion shared_memory_region,
                       base::SyncSocket::Handle socket_handle);
 
   int32_t GetRemoteHandles(
       const base::SyncSocket& socket,
-      const base::SharedMemory& shared_memory,
+      const base::UnsafeSharedMemoryRegion& shared_memory_region,
       IPC::PlatformFileForTransit* remote_socket_handle,
-      base::SharedMemoryHandle* remote_shared_memory_handle);
+      base::UnsafeSharedMemoryRegion* remote_shared_memory_region);
 
   void Close();
 
diff --git a/content/renderer/pepper/pepper_platform_audio_input.cc b/content/renderer/pepper/pepper_platform_audio_input.cc
index 1d8fb3ff..5a5ea3b0 100644
--- a/content/renderer/pepper/pepper_platform_audio_input.cc
+++ b/content/renderer/pepper/pepper_platform_audio_input.cc
@@ -76,34 +76,32 @@
 }
 
 void PepperPlatformAudioInput::OnStreamCreated(
-    base::SharedMemoryHandle handle,
+    base::ReadOnlySharedMemoryRegion shared_memory_region,
     base::SyncSocket::Handle socket_handle,
     bool initially_muted) {
+  DCHECK(shared_memory_region.IsValid());
 #if defined(OS_WIN)
-  DCHECK(handle.IsValid());
   DCHECK(socket_handle);
 #else
-  DCHECK(base::SharedMemory::IsHandleValid(handle));
   DCHECK_NE(-1, socket_handle);
 #endif
-  DCHECK(handle.GetSize());
+  DCHECK_GT(shared_memory_region.GetSize(), 0u);
 
   if (base::ThreadTaskRunnerHandle::Get().get() != main_task_runner_.get()) {
     // If shutdown has occurred, |client_| will be NULL and the handles will be
     // cleaned up on the main thread.
     main_task_runner_->PostTask(
-        FROM_HERE,
-        base::BindOnce(&PepperPlatformAudioInput::OnStreamCreated, this, handle,
-                       socket_handle, initially_muted));
+        FROM_HERE, base::BindOnce(&PepperPlatformAudioInput::OnStreamCreated,
+                                  this, std::move(shared_memory_region),
+                                  socket_handle, initially_muted));
   } else {
     // Must dereference the client only on the main thread. Shutdown may have
     // occurred while the request was in-flight, so we need to NULL check.
     if (client_) {
-      client_->StreamCreated(handle, handle.GetSize(), socket_handle);
+      client_->StreamCreated(std::move(shared_memory_region), socket_handle);
     } else {
-      // Clean up the handles.
+      // Clean up the handle.
       base::SyncSocket temp_socket(socket_handle);
-      base::SharedMemory temp_shared_memory(handle, false);
     }
   }
 }
diff --git a/content/renderer/pepper/pepper_platform_audio_input.h b/content/renderer/pepper/pepper_platform_audio_input.h
index d7f69bbd..0d83fb4 100644
--- a/content/renderer/pepper/pepper_platform_audio_input.h
+++ b/content/renderer/pepper/pepper_platform_audio_input.h
@@ -55,7 +55,7 @@
   void ShutDown();
 
   // media::AudioInputIPCDelegate.
-  void OnStreamCreated(base::SharedMemoryHandle handle,
+  void OnStreamCreated(base::ReadOnlySharedMemoryRegion shared_memory_region,
                        base::SyncSocket::Handle socket_handle,
                        bool initially_muted) override;
   void OnError() override;
diff --git a/content/renderer/pepper/pepper_platform_audio_output.cc b/content/renderer/pepper/pepper_platform_audio_output.cc
index 267fe95c..3850b11b 100644
--- a/content/renderer/pepper/pepper_platform_audio_output.cc
+++ b/content/renderer/pepper/pepper_platform_audio_output.cc
@@ -89,27 +89,27 @@
 }
 
 void PepperPlatformAudioOutput::OnStreamCreated(
-    base::SharedMemoryHandle handle,
+    base::UnsafeSharedMemoryRegion shared_memory_region,
     base::SyncSocket::Handle socket_handle,
     bool playing_automatically) {
-  DCHECK(handle.IsValid());
+  DCHECK(shared_memory_region.IsValid());
 #if defined(OS_WIN)
   DCHECK(socket_handle);
 #else
   DCHECK_NE(-1, socket_handle);
 #endif
-  DCHECK(handle.GetSize());
+  DCHECK_GT(shared_memory_region.GetSize(), 0u);
 
   if (base::ThreadTaskRunnerHandle::Get().get() == main_task_runner_.get()) {
     // Must dereference the client only on the main thread. Shutdown may have
     // occurred while the request was in-flight, so we need to NULL check.
     if (client_)
-      client_->StreamCreated(handle, handle.GetSize(), socket_handle);
+      client_->StreamCreated(std::move(shared_memory_region), socket_handle);
   } else {
     main_task_runner_->PostTask(
-        FROM_HERE,
-        base::BindOnce(&PepperPlatformAudioOutput::OnStreamCreated, this,
-                       handle, socket_handle, playing_automatically));
+        FROM_HERE, base::BindOnce(&PepperPlatformAudioOutput::OnStreamCreated,
+                                  this, std::move(shared_memory_region),
+                                  socket_handle, playing_automatically));
   }
 }
 
diff --git a/content/renderer/pepper/pepper_platform_audio_output.h b/content/renderer/pepper/pepper_platform_audio_output.h
index 43be22d0..fb0559d 100644
--- a/content/renderer/pepper/pepper_platform_audio_output.h
+++ b/content/renderer/pepper/pepper_platform_audio_output.h
@@ -57,7 +57,7 @@
   void OnDeviceAuthorized(media::OutputDeviceStatus device_status,
                           const media::AudioParameters& output_params,
                           const std::string& matched_device_id) override;
-  void OnStreamCreated(base::SharedMemoryHandle handle,
+  void OnStreamCreated(base::UnsafeSharedMemoryRegion shared_memory_region,
                        base::SyncSocket::Handle socket_handle,
                        bool playing_automatically) override;
   void OnIPCClosed() override;
diff --git a/content/renderer/pepper/pepper_platform_audio_output_dev.cc b/content/renderer/pepper/pepper_platform_audio_output_dev.cc
index c4f75ab..52fec89 100644
--- a/content/renderer/pepper/pepper_platform_audio_output_dev.cc
+++ b/content/renderer/pepper/pepper_platform_audio_output_dev.cc
@@ -180,22 +180,22 @@
 }
 
 void PepperPlatformAudioOutputDev::OnStreamCreated(
-    base::SharedMemoryHandle handle,
+    base::UnsafeSharedMemoryRegion shared_memory_region,
     base::SyncSocket::Handle socket_handle,
     bool playing_automatically) {
-  DCHECK(handle.IsValid());
+  DCHECK(shared_memory_region.IsValid());
 #if defined(OS_WIN)
   DCHECK(socket_handle);
 #else
   DCHECK_NE(-1, socket_handle);
 #endif
-  DCHECK(handle.GetSize());
+  DCHECK_GT(shared_memory_region.GetSize(), 0u);
 
   if (base::ThreadTaskRunnerHandle::Get().get() == main_task_runner_.get()) {
     // Must dereference the client only on the main thread. Shutdown may have
     // occurred while the request was in-flight, so we need to NULL check.
     if (client_)
-      client_->StreamCreated(handle, handle.GetSize(), socket_handle);
+      client_->StreamCreated(std::move(shared_memory_region), socket_handle);
   } else {
     DCHECK(io_task_runner_->BelongsToCurrentThread());
     if (state_ != CREATING_STREAM)
@@ -208,7 +208,8 @@
     main_task_runner_->PostTask(
         FROM_HERE,
         base::BindOnce(&PepperPlatformAudioOutputDev::OnStreamCreated, this,
-                       handle, socket_handle, playing_automatically));
+                       std::move(shared_memory_region), socket_handle,
+                       playing_automatically));
   }
 }
 
diff --git a/content/renderer/pepper/pepper_platform_audio_output_dev.h b/content/renderer/pepper/pepper_platform_audio_output_dev.h
index 71ca1450..dbb23a45 100644
--- a/content/renderer/pepper/pepper_platform_audio_output_dev.h
+++ b/content/renderer/pepper/pepper_platform_audio_output_dev.h
@@ -62,7 +62,7 @@
   void OnDeviceAuthorized(media::OutputDeviceStatus device_status,
                           const media::AudioParameters& output_params,
                           const std::string& matched_device_id) override;
-  void OnStreamCreated(base::SharedMemoryHandle handle,
+  void OnStreamCreated(base::UnsafeSharedMemoryRegion shared_memory_region,
                        base::SyncSocket::Handle socket_handle,
                        bool playing_automatically) override;
   void OnIPCClosed() override;
diff --git a/content/renderer/pepper/pepper_proxy_channel_delegate_impl.cc b/content/renderer/pepper/pepper_proxy_channel_delegate_impl.cc
index c97d6a5..e026b2fe 100644
--- a/content/renderer/pepper/pepper_proxy_channel_delegate_impl.cc
+++ b/content/renderer/pepper/pepper_proxy_channel_delegate_impl.cc
@@ -39,4 +39,18 @@
   return base::SharedMemory::DuplicateHandle(handle);
 }
 
+base::UnsafeSharedMemoryRegion
+PepperProxyChannelDelegateImpl::ShareUnsafeSharedMemoryRegionWithRemote(
+    const base::UnsafeSharedMemoryRegion& region,
+    base::ProcessId remote_pid) {
+  return region.Duplicate();
+}
+
+base::ReadOnlySharedMemoryRegion
+PepperProxyChannelDelegateImpl::ShareReadOnlySharedMemoryRegionWithRemote(
+    const base::ReadOnlySharedMemoryRegion& region,
+    base::ProcessId remote_pid) {
+  return region.Duplicate();
+}
+
 }  // namespace content
diff --git a/content/renderer/pepper/pepper_proxy_channel_delegate_impl.h b/content/renderer/pepper/pepper_proxy_channel_delegate_impl.h
index 6bfd2a1b..147c68cc 100644
--- a/content/renderer/pepper/pepper_proxy_channel_delegate_impl.h
+++ b/content/renderer/pepper/pepper_proxy_channel_delegate_impl.h
@@ -25,6 +25,12 @@
   base::SharedMemoryHandle ShareSharedMemoryHandleWithRemote(
       const base::SharedMemoryHandle& handle,
       base::ProcessId remote_pid) override;
+  base::UnsafeSharedMemoryRegion ShareUnsafeSharedMemoryRegionWithRemote(
+      const base::UnsafeSharedMemoryRegion& region,
+      base::ProcessId remote_pid) override;
+  base::ReadOnlySharedMemoryRegion ShareReadOnlySharedMemoryRegionWithRemote(
+      const base::ReadOnlySharedMemoryRegion& region,
+      base::ProcessId remote_pid) override;
 };
 
 }  // namespace content
diff --git a/content/renderer/pepper/ppb_audio_impl.cc b/content/renderer/pepper/ppb_audio_impl.cc
index 21d9392..98f3a272a 100644
--- a/content/renderer/pepper/ppb_audio_impl.cc
+++ b/content/renderer/pepper/ppb_audio_impl.cc
@@ -152,20 +152,15 @@
   return GetSyncSocketImpl(sync_socket);
 }
 
-int32_t PPB_Audio_Impl::GetSharedMemory(base::SharedMemory** shm,
-                                        uint32_t* shm_size) {
-  return GetSharedMemoryImpl(shm, shm_size);
+int32_t PPB_Audio_Impl::GetSharedMemory(base::UnsafeSharedMemoryRegion** shm) {
+  return GetSharedMemoryImpl(shm);
 }
 
 void PPB_Audio_Impl::OnSetStreamInfo(
-    base::SharedMemoryHandle shared_memory_handle,
-    size_t shared_memory_size,
+    base::UnsafeSharedMemoryRegion shared_memory_region,
     base::SyncSocket::Handle socket_handle) {
   EnterResourceNoLock<PPB_AudioConfig_API> enter(config_, true);
-  SetStreamInfo(pp_instance(),
-                shared_memory_handle,
-                shared_memory_size,
-                socket_handle,
+  SetStreamInfo(pp_instance(), std::move(shared_memory_region), socket_handle,
                 enter.object()->GetSampleRate(),
                 enter.object()->GetSampleFrameCount());
 }
diff --git a/content/renderer/pepper/ppb_audio_impl.h b/content/renderer/pepper/ppb_audio_impl.h
index e0618ff..abcd04b0 100644
--- a/content/renderer/pepper/ppb_audio_impl.h
+++ b/content/renderer/pepper/ppb_audio_impl.h
@@ -10,7 +10,7 @@
 
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
-#include "base/memory/shared_memory.h"
+#include "base/memory/unsafe_shared_memory_region.h"
 #include "base/sync_socket.h"
 #include "content/public/renderer/plugin_instance_throttler.h"
 #include "content/renderer/pepper/audio_helper.h"
@@ -47,8 +47,7 @@
   int32_t Open(PP_Resource config_id,
                scoped_refptr<ppapi::TrackedCallback> create_callback) override;
   int32_t GetSyncSocket(int* sync_socket) override;
-  int32_t GetSharedMemory(base::SharedMemory** shm,
-                          uint32_t* shm_size) override;
+  int32_t GetSharedMemory(base::UnsafeSharedMemoryRegion** shm) override;
 
   void SetVolume(double volume);
 
@@ -56,8 +55,7 @@
   ~PPB_Audio_Impl() override;
 
   // AudioHelper implementation.
-  void OnSetStreamInfo(base::SharedMemoryHandle shared_memory_handle,
-                       size_t shared_memory_size_,
+  void OnSetStreamInfo(base::UnsafeSharedMemoryRegion shared_memory_region,
                        base::SyncSocket::Handle socket) override;
 
   // PluginInstanceThrottler::Observer implementation.
diff --git a/content/renderer/pepper/renderer_ppapi_host_impl.cc b/content/renderer/pepper/renderer_ppapi_host_impl.cc
index 2e9658a..9568688 100644
--- a/content/renderer/pepper/renderer_ppapi_host_impl.cc
+++ b/content/renderer/pepper/renderer_ppapi_host_impl.cc
@@ -237,6 +237,26 @@
   return dispatcher_->ShareSharedMemoryHandleWithRemote(handle);
 }
 
+base::UnsafeSharedMemoryRegion
+RendererPpapiHostImpl::ShareUnsafeSharedMemoryRegionWithRemote(
+    const base::UnsafeSharedMemoryRegion& region) {
+  if (!dispatcher_) {
+    DCHECK(is_running_in_process_);
+    return region.Duplicate();
+  }
+  return dispatcher_->ShareUnsafeSharedMemoryRegionWithRemote(region);
+}
+
+base::ReadOnlySharedMemoryRegion
+RendererPpapiHostImpl::ShareReadOnlySharedMemoryRegionWithRemote(
+    const base::ReadOnlySharedMemoryRegion& region) {
+  if (!dispatcher_) {
+    DCHECK(is_running_in_process_);
+    return region.Duplicate();
+  }
+  return dispatcher_->ShareReadOnlySharedMemoryRegionWithRemote(region);
+}
+
 bool RendererPpapiHostImpl::IsRunningInProcess() const {
   return is_running_in_process_;
 }
diff --git a/content/renderer/pepper/renderer_ppapi_host_impl.h b/content/renderer/pepper/renderer_ppapi_host_impl.h
index d8d6edda..a94ef56a 100644
--- a/content/renderer/pepper/renderer_ppapi_host_impl.h
+++ b/content/renderer/pepper/renderer_ppapi_host_impl.h
@@ -89,6 +89,10 @@
       bool should_close_source) override;
   base::SharedMemoryHandle ShareSharedMemoryHandleWithRemote(
       const base::SharedMemoryHandle& handle) override;
+  base::UnsafeSharedMemoryRegion ShareUnsafeSharedMemoryRegionWithRemote(
+      const base::UnsafeSharedMemoryRegion& region) override;
+  base::ReadOnlySharedMemoryRegion ShareReadOnlySharedMemoryRegionWithRemote(
+      const base::ReadOnlySharedMemoryRegion& region) override;
   bool IsRunningInProcess() const override;
   std::string GetPluginName() const override;
   void SetToExternalPluginHost() override;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index 65cfaa3c..a8ec6a9 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -303,12 +303,16 @@
 // Helper struct keeping track in one place of all the parameters the browser
 // provided to the renderer to commit a navigation.
 struct PendingNavigationParams {
-  PendingNavigationParams(const CommonNavigationParams& common_params,
-                          const RequestNavigationParams& request_params,
-                          base::TimeTicks time_commit_requested)
+  PendingNavigationParams(
+      const CommonNavigationParams& common_params,
+      const RequestNavigationParams& request_params,
+      base::TimeTicks time_commit_requested,
+      content::mojom::FrameNavigationControl::CommitNavigationCallback
+          commit_callback)
       : common_params(common_params),
         request_params(request_params),
-        time_commit_requested(time_commit_requested) {}
+        time_commit_requested(time_commit_requested),
+        commit_callback_(std::move(commit_callback)) {}
   ~PendingNavigationParams() = default;
 
   CommonNavigationParams common_params;
@@ -316,6 +320,9 @@
 
   // Time when RenderFrameImpl::CommitNavigation() is called.
   base::TimeTicks time_commit_requested;
+
+  content::mojom::FrameNavigationControl::CommitNavigationCallback
+      commit_callback_;
 };
 
 namespace {
@@ -2446,8 +2453,8 @@
   if (!navigation_state->IsContentInitiated()) {
     pending_navigation_params_.reset(new PendingNavigationParams(
         navigation_state->common_params(), navigation_state->request_params(),
-        base::TimeTicks()  // not used for failed navigation.
-        ));
+        base::TimeTicks(),  // not used for failed navigation.
+        CommitNavigationCallback()));
   }
 
   // Load an error page.
@@ -2870,7 +2877,8 @@
     base::Optional<std::vector<mojom::TransferrableURLLoaderPtr>>
         subresource_overrides,
     mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info,
-    const base::UnguessableToken& devtools_navigation_token) {
+    const base::UnguessableToken& devtools_navigation_token,
+    CommitNavigationCallback callback) {
   DCHECK(!IsRendererDebugURL(common_params.url));
   DCHECK(
       !FrameMsg_Navigate_Type::IsSameDocument(common_params.navigation_type));
@@ -2881,6 +2889,7 @@
       browser_side_navigation_pending_url_ == request_params.original_url &&
       request_params.nav_entry_id == 0) {
     browser_side_navigation_pending_url_ = GURL();
+    std::move(callback).Run(blink::mojom::CommitResult::Aborted);
     return;
   }
 
@@ -2910,8 +2919,9 @@
   if (request_params.is_view_source)
     frame_->EnableViewSourceMode(true);
 
-  pending_navigation_params_.reset(new PendingNavigationParams(
-      common_params, request_params, base::TimeTicks::Now()));
+  pending_navigation_params_.reset(
+      new PendingNavigationParams(common_params, request_params,
+                                  base::TimeTicks::Now(), std::move(callback)));
   PrepareFrameForCommit();
 
   blink::WebFrameLoadType load_type = NavigationTypeToLoadType(
@@ -2999,7 +3009,8 @@
     bool has_stale_copy_in_cache,
     int error_code,
     const base::Optional<std::string>& error_page_content,
-    std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories) {
+    std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loader_factories,
+    CommitFailedNavigationCallback callback) {
   DCHECK(
       !FrameMsg_Navigate_Type::IsSameDocument(common_params.navigation_type));
   bool is_reload =
@@ -3024,8 +3035,8 @@
 
   pending_navigation_params_.reset(new PendingNavigationParams(
       common_params, request_params,
-      base::TimeTicks()  // Not used for failed navigation.
-      ));
+      base::TimeTicks(),  // Not used for failed navigation.
+      std::move(callback)));
 
   // Send the provisional load failure.
   WebURLError error(
@@ -3040,6 +3051,9 @@
   if (!ShouldDisplayErrorPageForFailedLoad(error_code, common_params.url)) {
     // The browser expects this frame to be loading an error page. Inform it
     // that the load stopped.
+    std::move(pending_navigation_params_->commit_callback_)
+        .Run(blink::mojom::CommitResult::Aborted);
+    pending_navigation_params_.reset();
     Send(new FrameHostMsg_DidStopLoading(routing_id_));
     browser_side_navigation_pending_ = false;
     browser_side_navigation_pending_url_ = GURL();
@@ -3057,6 +3071,9 @@
       // either, as the frame has already been populated with something
       // unrelated to this navigation failure. In that case, just send a stop
       // IPC to the browser to unwind its state, and leave the frame as-is.
+      std::move(pending_navigation_params_->commit_callback_)
+          .Run(blink::mojom::CommitResult::Aborted);
+      pending_navigation_params_.reset();
       Send(new FrameHostMsg_DidStopLoading(routing_id_));
     }
     browser_side_navigation_pending_ = false;
@@ -3133,10 +3150,15 @@
       common_params.has_user_gesture ? new blink::WebScopedUserGesture(frame_)
                                      : nullptr);
 
+  // Note: The CommitNavigationCallback below is not used: the commit of
+  // same-document navigation is synchronous so there is enough information at
+  // the end of this function to run |callback| directly.
+  // TODO(clamy): See if PendingNavigationParams should not be set at all for
+  // same-document navigations.
   pending_navigation_params_.reset(new PendingNavigationParams(
       common_params, request_params,
-      base::TimeTicks()  // Not used for same-document navigation.
-      ));
+      base::TimeTicks(),  // Not used for same-document navigation.
+      CommitNavigationCallback()));
   PrepareFrameForCommit();
 
   blink::WebFrameLoadType load_type = NavigationTypeToLoadType(
@@ -4097,6 +4119,7 @@
   if (media_permission_dispatcher_)
     media_permission_dispatcher_->OnNavigation();
 
+  navigation_state->RunCommitNavigationCallback(blink::mojom::CommitResult::Ok);
   DidCommitNavigationInternal(item, commit_type,
                               false /* was_within_same_document */,
                               std::move(remote_interface_provider_request));
@@ -6804,7 +6827,8 @@
     return NavigationStateImpl::CreateBrowserInitiated(
         pending_navigation_params_->common_params,
         pending_navigation_params_->request_params,
-        pending_navigation_params_->time_commit_requested);
+        pending_navigation_params_->time_commit_requested,
+        std::move(pending_navigation_params_->commit_callback_));
   }
   return NavigationStateImpl::CreateContentInitiated();
 }
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 6c43d468..5b8f758 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -526,14 +526,16 @@
       base::Optional<std::vector<mojom::TransferrableURLLoaderPtr>>
           subresource_overrides,
       mojom::ControllerServiceWorkerInfoPtr controller_service_worker_info,
-      const base::UnguessableToken& devtools_navigation_token) override;
+      const base::UnguessableToken& devtools_navigation_token,
+      CommitNavigationCallback callback) override;
   void CommitFailedNavigation(
       const CommonNavigationParams& common_params,
       const RequestNavigationParams& request_params,
       bool has_stale_copy_in_cache,
       int error_code,
       const base::Optional<std::string>& error_page_content,
-      std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders) override;
+      std::unique_ptr<URLLoaderFactoryBundleInfo> subresource_loaders,
+      CommitFailedNavigationCallback callback) override;
   void CommitSameDocumentNavigation(
       const CommonNavigationParams& common_params,
       const RequestNavigationParams& request_params,
diff --git a/content/test/data/htxg/README b/content/test/data/htxg/README
index 537dbb1..7ae660f 100644
--- a/content/test/data/htxg/README
+++ b/content/test/data/htxg/README
@@ -2,22 +2,15 @@
 this directory are generated using the following commands.
 
 gen-certurl and gen-signedexchange are available in webpackage repository [1].
-We're using a fork of this repository [2] that implements the "Implementation
-Checkpoints" of the signed-exchange spec [3].
+Revision 01e618f6af is used to generate these files.
 
  [1] https://github.com/WICG/webpackage
- [2] https://github.com/nyaxt/webpackage
- [3] https://jyasskin.github.io/webpackage/implementation-draft/draft-yasskin-httpbis-origin-signed-exchanges-impl.html
 
-# Install gen-certurl command from [1]
+# Install gen-certurl command.
 go get github.com/WICG/webpackage/go/signedexchange/cmd/gen-certurl
 
-# Install gen-signedexchange command from [2],
-go get github.com/nyaxt/webpackage/go/signedexchange/cmd/gen-signedexchange
-# and cherry-pick the following changes from [1].
-https://github.com/WICG/webpackage/commit/c173772a4fb3c923d705a319e5e9f2fb1fd569d7
-https://github.com/WICG/webpackage/commit/2635cc5d8fc3177092806ce19826e9cd8f8461c9
-https://github.com/WICG/webpackage/commit/2e88a4422a565221178891f50ed68c71cbcb6086
+# Install gen-signedexchange command.
+go get github.com/WICG/webpackage/go/signedexchange/cmd/gen-signedexchange
 
 # Get the private key of "*.example.org".
 sed -ne '/-BEGIN PRIVATE KEY-/,/-END PRIVATE KEY-/p' \
@@ -105,21 +98,21 @@
   -out secp384r1-sha256.crt -set_serial 1
 
 # Generate test signatures in signed_exchange_signature_verifier_unittest.cc
-./gen-signedexchange \
+gen-signedexchange \
   -uri https://test.example.org/test/ \
   -content test.html \
   -certificate /tmp/wildcard_example.org.public.pem \
   -privateKey /tmp/wildcard_example.org.private.pem \
   -date 2018-02-06T04:45:41Z
 
-./gen-signedexchange \
+gen-signedexchange \
   -uri https://test.example.org/test/ \
   -content test.html \
   -certificate ./prime256v1-sha256.crt \
   -privateKey ./prime256v1.key \
   -date 2018-02-06T04:45:41Z
 
-./gen-signedexchange \
+gen-signedexchange \
   -uri https://test.example.org/test/ \
   -content test.html \
   -certificate ./secp384r1-sha256.crt \
diff --git a/content/test/data/htxg/test.example.com_invalid_test.htxg b/content/test/data/htxg/test.example.com_invalid_test.htxg
index 724c35a9..d02c8e9 100644
--- a/content/test/data/htxg/test.example.com_invalid_test.htxg
+++ b/content/test/data/htxg/test.example.com_invalid_test.htxg
Binary files differ
diff --git a/content/test/data/htxg/test.example.org_hello.txt.htxg b/content/test/data/htxg/test.example.org_hello.txt.htxg
index fa37fa1..885029a 100644
--- a/content/test/data/htxg/test.example.org_hello.txt.htxg
+++ b/content/test/data/htxg/test.example.org_hello.txt.htxg
Binary files differ
diff --git a/content/test/data/htxg/test.example.org_test.htxg b/content/test/data/htxg/test.example.org_test.htxg
index f16bff5e..47ef736 100644
--- a/content/test/data/htxg/test.example.org_test.htxg
+++ b/content/test/data/htxg/test.example.org_test.htxg
Binary files differ
diff --git a/content/test/data/htxg/wildcard_example.org.public.pem.cbor.mock-http-headers b/content/test/data/htxg/wildcard_example.org.public.pem.cbor.mock-http-headers
new file mode 100644
index 0000000..ba8c1b7
--- /dev/null
+++ b/content/test/data/htxg/wildcard_example.org.public.pem.cbor.mock-http-headers
@@ -0,0 +1,2 @@
+HTTP/1.1 200 OK
+Content-Type: application/cert-chain+cbor
diff --git a/content/test/fuzzer/signed_exchange_envelope_fuzzer.cc b/content/test/fuzzer/signed_exchange_envelope_fuzzer.cc
index e0aa8a01..f2fa65b 100644
--- a/content/test/fuzzer/signed_exchange_envelope_fuzzer.cc
+++ b/content/test/fuzzer/signed_exchange_envelope_fuzzer.cc
@@ -21,18 +21,29 @@
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
   if (size < SignedExchangePrologue::kEncodedLengthInBytes)
     return 0;
-  auto encoded_length =
-      base::make_span(data, SignedExchangePrologue::kEncodedLengthInBytes);
-  size_t header_len =
-      SignedExchangePrologue::ParseEncodedLength(encoded_length);
-  data += SignedExchangePrologue::kEncodedLengthInBytes;
-  size -= SignedExchangePrologue::kEncodedLengthInBytes;
+  auto prologue_bytes =
+      base::make_span(data, SignedExchangePrologue::kEncodedPrologueInBytes);
+  base::Optional<SignedExchangePrologue> prologue =
+      SignedExchangePrologue::Parse(prologue_bytes,
+                                    nullptr /* devtools_proxy */);
+  if (!prologue)
+    return 0;
 
-  // Copy the header into a separate buffer so that out-of-bounds access can be
+  data += SignedExchangePrologue::kEncodedPrologueInBytes;
+  size -= SignedExchangePrologue::kEncodedPrologueInBytes;
+
+  // Copy the headers into separate buffers so that out-of-bounds access can be
   // detected.
-  std::vector<uint8_t> header(data, data + std::min(size, header_len));
+  std::string signature_header_field(
+      reinterpret_cast<const char*>(data),
+      std::min(size, prologue->signature_header_field_length()));
+  data += signature_header_field.size();
+  size -= signature_header_field.size();
+  std::vector<uint8_t> cbor_header(
+      data, data + std::min(size, prologue->cbor_header_length()));
 
-  SignedExchangeEnvelope::Parse(base::make_span(header),
+  SignedExchangeEnvelope::Parse(signature_header_field,
+                                base::make_span(cbor_header),
                                 nullptr /* devtools_proxy */);
   return 0;
 }
diff --git a/content/test/test_render_frame.cc b/content/test/test_render_frame.cc
index 1647efa7..038dd05b 100644
--- a/content/test/test_render_frame.cc
+++ b/content/test/test_render_frame.cc
@@ -149,12 +149,12 @@
 
 void TestRenderFrame::Navigate(const CommonNavigationParams& common_params,
                                const RequestNavigationParams& request_params) {
-  CommitNavigation(network::ResourceResponseHead(), common_params,
-                   request_params,
-                   network::mojom::URLLoaderClientEndpointsPtr(),
-                   std::make_unique<URLLoaderFactoryBundleInfo>(),
-                   base::nullopt, mojom::ControllerServiceWorkerInfoPtr(),
-                   base::UnguessableToken::Create());
+  CommitNavigation(
+      network::ResourceResponseHead(), common_params, request_params,
+      network::mojom::URLLoaderClientEndpointsPtr(),
+      std::make_unique<URLLoaderFactoryBundleInfo>(), base::nullopt,
+      mojom::ControllerServiceWorkerInfoPtr(), base::UnguessableToken::Create(),
+      CommitNavigationCallback());
 }
 
 void TestRenderFrame::SwapOut(
diff --git a/content/test/test_render_frame_host.cc b/content/test/test_render_frame_host.cc
index ed213551..3a43fe2 100644
--- a/content/test/test_render_frame_host.cc
+++ b/content/test/test_render_frame_host.cc
@@ -571,6 +571,14 @@
   }
 }
 
+void TestRenderFrameHost::AbortNavigationCommit() {
+  if (navigation_request_) {
+    RenderFrameHostImpl::OnCrossDocumentCommitProcessed(
+        navigation_request_->navigation_handle()->GetNavigationId(),
+        blink::mojom::CommitResult::Aborted);
+  }
+}
+
 WebBluetoothServiceImpl*
 TestRenderFrameHost::CreateWebBluetoothServiceForTesting() {
   WebBluetoothServiceImpl* service =
diff --git a/content/test/test_render_frame_host.h b/content/test/test_render_frame_host.h
index 872f0b7..f03d812 100644
--- a/content/test/test_render_frame_host.h
+++ b/content/test/test_render_frame_host.h
@@ -172,6 +172,10 @@
   // interaction with the IO thread up until the response is ready to commit.
   void PrepareForCommitIfNecessary();
 
+  // Used to simulate the abort of a navigation waiting to be committed in this
+  // RenderFrameHost.
+  void AbortNavigationCommit();
+
   // Send a message with the sandbox flags and feature policy
   void SendFramePolicy(blink::WebSandboxFlags sandbox_flags,
                        const blink::ParsedFeaturePolicy& declared_policy);
diff --git a/extensions/common/permissions/api_permission.h b/extensions/common/permissions/api_permission.h
index 76591e7..7ab192b 100644
--- a/extensions/common/permissions/api_permission.h
+++ b/extensions/common/permissions/api_permission.h
@@ -253,6 +253,7 @@
     kWebrtcLoggingPrivateAudioDebug,
     kEnterpriseReportingPrivate,
     kCecPrivate,
+    kSafeBrowsingPrivate,
     // Last entry: Add new entries above and ensure to update the
     // "ExtensionPermission3" enum in tools/metrics/histograms/histograms.xml
     // (by running update_extension_permission.py).
diff --git a/extensions/shell/BUILD.gn b/extensions/shell/BUILD.gn
index 3427661..e7728d2 100644
--- a/extensions/shell/BUILD.gn
+++ b/extensions/shell/BUILD.gn
@@ -48,6 +48,7 @@
     "//components/network_session_configurator/common",
     "//components/pref_registry",
     "//components/prefs",
+    "//components/sessions",
     "//components/storage_monitor",
     "//components/update_client",
     "//components/user_prefs",
diff --git a/extensions/shell/browser/DEPS b/extensions/shell/browser/DEPS
index 850b28b..20cb7b5 100644
--- a/extensions/shell/browser/DEPS
+++ b/extensions/shell/browser/DEPS
@@ -7,6 +7,7 @@
   "+components/nacl/common",
   "+components/network_session_configurator/common",
   "+components/pref_registry",
+  "+components/sessions",
   "+components/update_client",
   "+components/user_prefs",
   "+components/web_modal",
diff --git a/extensions/shell/browser/shell_browser_main_parts.cc b/extensions/shell/browser/shell_browser_main_parts.cc
index 9c5e1c3a..ff8268f 100644
--- a/extensions/shell/browser/shell_browser_main_parts.cc
+++ b/extensions/shell/browser/shell_browser_main_parts.cc
@@ -12,6 +12,7 @@
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/nacl/common/buildflags.h"
 #include "components/prefs/pref_service.h"
+#include "components/sessions/core/session_id_generator.h"
 #include "components/storage_monitor/storage_monitor.h"
 #include "components/update_client/update_query_params.h"
 #include "content/public/browser/child_process_security_policy.h"
@@ -188,6 +189,7 @@
   // app_shell only supports a single user, so all preferences live in the user
   // data directory, including the device-wide local state.
   local_state_ = shell_prefs::CreateLocalState(browser_context_->GetPath());
+  sessions::SessionIdGenerator::GetInstance()->Init(local_state_.get());
   user_pref_service_ =
       shell_prefs::CreateUserPrefService(browser_context_.get());
   extensions_browser_client_->InitWithBrowserContext(browser_context_.get(),
@@ -297,6 +299,8 @@
   chromeos::CrasAudioHandler::Shutdown();
 #endif
 
+  sessions::SessionIdGenerator::GetInstance()->Shutdown();
+
   user_pref_service_->CommitPendingWrite();
   user_pref_service_.reset();
   local_state_->CommitPendingWrite();
diff --git a/extensions/shell/browser/shell_prefs.cc b/extensions/shell/browser/shell_prefs.cc
index 0715b48..651a4a0d 100644
--- a/extensions/shell/browser/shell_prefs.cc
+++ b/extensions/shell/browser/shell_prefs.cc
@@ -13,6 +13,7 @@
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 #include "components/prefs/pref_service_factory.h"
+#include "components/sessions/core/session_id_generator.h"
 #include "components/user_prefs/user_prefs.h"
 #include "content/public/browser/browser_context.h"
 #include "extensions/browser/api/audio/audio_api.h"
@@ -29,6 +30,7 @@
 namespace {
 
 void RegisterLocalStatePrefs(PrefRegistrySimple* registry) {
+  sessions::SessionIdGenerator::RegisterPrefs(registry);
 #if defined(OS_CHROMEOS)
   chromeos::AudioDevicesPrefHandlerImpl::RegisterPrefs(registry);
 #endif
diff --git a/infra/config/global/luci-milo-dev.cfg b/infra/config/global/luci-milo-dev.cfg
index 0ba7180..406ddcc 100644
--- a/infra/config/global/luci-milo-dev.cfg
+++ b/infra/config/global/luci-milo-dev.cfg
@@ -1263,24 +1263,14 @@
     short_name: "nvi"
   }
   builders: {
-    name: "buildbot/chromium.perf/Mac 10.12 Perf"
-    category: "perf|mac"
-    short_name: "12"
-  }
-  builders: {
     name: "buildbot/chromium.perf/mac-10_12_laptop_low_end-perf"
     category: "perf|mac"
     short_name: "low"
   }
   builders: {
-    name: "buildbot/chromium.perf/Mac Pro 10.11 Perf"
+    name: "buildbot/chromium.perf/mac-10_13_laptop_high_end-perf"
     category: "perf|mac"
-    short_name: "pro"
-  }
-  builders: {
-    name: "buildbot/chromium.perf/Mac Air 10.11 Perf"
-    category: "perf|mac"
-    short_name: "air"
+    short_name: "high"
   }
   builders: {
     name: "buildbot/chromium.perf/linux-perf"
@@ -2921,10 +2911,6 @@
     category: "linux"
   }
   builders: {
-    name: "buildbot/chromium.perf.fyi/Mac 10.13 Laptop High End"
-    category: "mac"
-  }
-  builders: {
     name: "buildbot/chromium.perf.fyi/Android Go"
     category: "android"
   }
diff --git a/infra/config/global/luci-milo.cfg b/infra/config/global/luci-milo.cfg
index 4fb179a3..46afc1f 100644
--- a/infra/config/global/luci-milo.cfg
+++ b/infra/config/global/luci-milo.cfg
@@ -1394,30 +1394,18 @@
     short_name: "nvi"
   }
   builders {
-    name: "buildbot/chromium.perf/Mac 10.12 Perf"
-    name: "buildbucket/luci.chromium.ci/Mac 10.12 Perf"
-    category: "perf|mac"
-    short_name: "12"
-  }
-  builders {
-    name: "buildbot/chromium.perf/Mac Pro 10.11 Perf"
-    name: "buildbucket/luci.chromium.ci/Mac Pro 10.11 Perf"
-    category: "perf|mac"
-    short_name: "pro"
-  }
-  builders {
-    name: "buildbot/chromium.perf/Mac Air 10.11 Perf"
-    name: "buildbucket/luci.chromium.ci/Mac Air 10.11 Perf"
-    category: "perf|mac"
-    short_name: "air"
-  }
-  builders {
     name: "buildbot/chromium.perf/mac-10_12_laptop_low_end-perf"
     name: "buildbucket/luci.chromium.ci/mac-10_12_laptop_low_end-perf"
     category: "perf|mac"
     short_name: "low"
   }
   builders {
+    name: "buildbot/chromium.perf/mac-10_13_laptop_high_end-perf"
+    name: "buildbucket/luci.chromium.ci/mac-10_13_laptop_high_end-perf"
+    category: "perf|mac"
+    short_name: "high"
+  }
+  builders {
     name: "buildbot/chromium.perf/linux-perf"
     name: "buildbucket/luci.chromium.ci/linux-perf"
     category: "perf"
@@ -3427,11 +3415,6 @@
     category: "linux"
   }
   builders {
-    name: "buildbot/chromium.perf.fyi/Mac 10.13 Laptop High End"
-    name: "buildbucket/luci.chromium.ci/Mac 10.13 Laptop High End"
-    category: "mac"
-  }
-  builders {
     name: "buildbot/chromium.perf.fyi/Mac Builder Perf FYI"
     name: "buildbucket/luci.chromium.ci/Mac Builder Perf FYI"
     category: "mac"
diff --git a/ios/chrome/browser/BUILD.gn b/ios/chrome/browser/BUILD.gn
index 77b29f2fa..a7bcb65f 100644
--- a/ios/chrome/browser/BUILD.gn
+++ b/ios/chrome/browser/BUILD.gn
@@ -176,6 +176,7 @@
     "//components/open_from_clipboard",
     "//components/prefs",
     "//components/rappor",
+    "//components/sessions",
     "//components/translate/core/browser",
     "//components/ukm",
     "//components/update_client",
diff --git a/ios/chrome/browser/about_flags.mm b/ios/chrome/browser/about_flags.mm
index 15067298..d08e895a 100644
--- a/ios/chrome/browser/about_flags.mm
+++ b/ios/chrome/browser/about_flags.mm
@@ -329,6 +329,9 @@
      flag_descriptions::kAutofillCacheQueryResponsesDescription,
      flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(autofill::features::kAutofillCacheQueryResponses)},
+    {"autofill-manual-fallback", flag_descriptions::kAutofillManualFallbackName,
+     flag_descriptions::kAutofillManualFallbackDescription, flags_ui::kOsIos,
+     FEATURE_VALUE_TYPE(autofill::features::kAutofillManualFallback)},
 };
 
 // Add all switches from experimental flags to |command_line|.
diff --git a/ios/chrome/browser/application_context_impl.cc b/ios/chrome/browser/application_context_impl.cc
index 776b1cd..a80ae252 100644
--- a/ios/chrome/browser/application_context_impl.cc
+++ b/ios/chrome/browser/application_context_impl.cc
@@ -29,6 +29,7 @@
 #include "components/network_time/network_time_tracker.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
+#include "components/sessions/core/session_id_generator.h"
 #include "components/translate/core/browser/translate_download_manager.h"
 #include "components/ukm/ukm_service.h"
 #include "components/update_client/configurator.h"
@@ -107,6 +108,7 @@
 
   if (local_state_) {
     local_state_->CommitPendingWrite();
+    sessions::SessionIdGenerator::GetInstance()->Shutdown();
   }
 
   if (network_context_) {
@@ -337,6 +339,8 @@
       local_state_path, local_state_task_runner_.get(), pref_registry);
   DCHECK(local_state_);
 
+  sessions::SessionIdGenerator::GetInstance()->Init(local_state_.get());
+
   net::ClientSocketPoolManager::set_max_sockets_per_proxy_server(
       net::HttpNetworkSession::NORMAL_SOCKET_POOL,
       std::max(std::min<int>(net::kDefaultMaxSocketsPerProxyServer, 99),
diff --git a/ios/chrome/browser/favicon/BUILD.gn b/ios/chrome/browser/favicon/BUILD.gn
index a83c596..d9fd081 100644
--- a/ios/chrome/browser/favicon/BUILD.gn
+++ b/ios/chrome/browser/favicon/BUILD.gn
@@ -32,10 +32,10 @@
     "//ios/chrome/browser",
     "//ios/chrome/browser/browser_state",
     "//ios/chrome/browser/history",
+    "//ios/chrome/browser/ui/favicon:favicon_ui",
     "//ios/web",
     "//skia",
     "//ui/base",
-    "//ui/gfx",
     "//url",
   ]
 }
diff --git a/ios/chrome/browser/favicon/favicon_loader.h b/ios/chrome/browser/favicon/favicon_loader.h
index d370a905..9bb98f6e 100644
--- a/ios/chrome/browser/favicon/favicon_loader.h
+++ b/ios/chrome/browser/favicon/favicon_loader.h
@@ -7,69 +7,52 @@
 
 #import <Foundation/Foundation.h>
 
-#include <memory>
-#include <vector>
-
 #include "base/macros.h"
 #include "base/task/cancelable_task_tracker.h"
-#include "components/favicon_base/favicon_types.h"
 #include "components/keyed_service/core/keyed_service.h"
 
 class GURL;
-@class UIImage;
+@class FaviconAttributes;
 
 namespace favicon {
-class FaviconService;
+class LargeIconService;
 }
 
-// A class that manages asynchronously loading favicons from the favicon
-// service and caching them, given a URL. This is predominately used by the
-// MostVisited panel, since every other display of favicons already has a
-// bitmap in the relevant data structure. There is one of these per browser
-// state to avoid re-creating favicons for every instance of the NTP.
+// A class that manages asynchronously loading favicons or fallback attributes
+// from LargeIconService and caching them, given a URL.
 class FaviconLoader : public KeyedService {
  public:
-  // Type for completion block for ImageForURL().
-  typedef void (^ImageCompletionBlock)(UIImage*);
+  // Type for completion block for FaviconForURL().
+  typedef void (^FaviconAttributesCompletionBlock)(FaviconAttributes*);
 
-  explicit FaviconLoader(favicon::FaviconService* favicon_service);
+  explicit FaviconLoader(favicon::LargeIconService* large_icon_service);
   ~FaviconLoader() override;
 
-  // Returns the UIImage for the favicon associated with |url| for any type in
-  // |types|. Ifno icon is present, will start an asynchronous load with the
-  // favicon service and returns the default favicon (thus it will never return
-  // nil). Calls |block| when the load completes with the image. If |block| is
-  // nil, the load is still performed so a future call will find it in the
-  // cache.
-  UIImage* ImageForURL(const GURL& url,
-                       const favicon_base::IconTypeSet& types,
-                       ImageCompletionBlock block);
+  // Returns the FaviconAttributes for the favicon retrieved from |url|.
+  // If no icon is in favicon_cache_, will start an asynchronous load with the
+  // favicon service and return the default favicon.
+  // Calls |block| when the load completes with a valid image/attributes.
+  // Note: If no successful favicon was retrieved by LargeIconService, it
+  // returns the default favicon.
+  FaviconAttributes* FaviconForUrl(const GURL& url,
+                                   float size,
+                                   float min_size,
+                                   FaviconAttributesCompletionBlock block);
 
   // Cancel all incomplete requests.
   void CancellAllRequests();
 
  private:
-  struct RequestData;
-
-  // Called when the favicon load request completes. Saves image into the
-  // cache. Desktop code assumes this image is in PNG format.
-  void OnFaviconAvailable(
-      std::unique_ptr<RequestData> request_data,
-      const std::vector<favicon_base::FaviconRawBitmapResult>&
-          favicon_bitmap_results);
-
-  // The FaviconService used to retrieve favicon; may be null during testing.
-  // Must outlive the FaviconLoader.
-  favicon::FaviconService* favicon_service_;
+  // The LargeIconService used to retrieve favicon.
+  favicon::LargeIconService* large_icon_service_;
 
   // Tracks tasks sent to FaviconService.
   base::CancelableTaskTracker cancelable_task_tracker_;
-
-  // Holds cached favicons. This NSCache is populated as favicons are
-  // retrieved from the FaviconService. Contents will be removed during
-  // low-memory conditions based on its inherent LRU removal algorithm. Keyed
-  // by NSString of URL spec.
-  NSCache* favicon_cache_;
+  // Holds cached favicons. This NSCache is populated as favicons or fallback
+  // attributes are retrieved from the FaviconService. Contents will be removed
+  // during low-memory conditions based on its inherent LRU removal algorithm.
+  // Keyed by NSString of URL spec.
+  NSCache<NSString*, FaviconAttributes*>* favicon_cache_;
 
   DISALLOW_COPY_AND_ASSIGN(FaviconLoader);
 };
diff --git a/ios/chrome/browser/favicon/favicon_loader.mm b/ios/chrome/browser/favicon/favicon_loader.mm
index 17c6495..734ed84 100644
--- a/ios/chrome/browser/favicon/favicon_loader.mm
+++ b/ios/chrome/browser/favicon/favicon_loader.mm
@@ -6,93 +6,81 @@
 
 #import <UIKit/UIKit.h>
 
+#include "base/mac/bind_objc_block.h"
 #import "base/mac/foundation_util.h"
-#import "base/mac/scoped_block.h"
 #include "base/strings/sys_string_conversions.h"
-#include "components/favicon/core/favicon_service.h"
+#include "components/favicon/core/fallback_url_util.h"
+#include "components/favicon/core/large_icon_service.h"
+#include "components/favicon_base/fallback_icon_style.h"
 #include "components/favicon_base/favicon_callback.h"
-#include "ui/gfx/favicon_size.h"
+#import "ios/chrome/browser/ui/favicon/favicon_attributes.h"
+#include "skia/ext/skia_utils_ios.h"
 #include "url/gurl.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
 #endif
 
-struct FaviconLoader::RequestData {
-  RequestData() {}
-  RequestData(NSString* key, FaviconLoader::ImageCompletionBlock block)
-      : key([key copy]), block(block) {}
-  ~RequestData() {}
-
-  NSString* key;
-  base::mac::ScopedBlock<FaviconLoader::ImageCompletionBlock> block;
-};
-
-FaviconLoader::FaviconLoader(favicon::FaviconService* favicon_service)
-    : favicon_service_(favicon_service),
+FaviconLoader::FaviconLoader(favicon::LargeIconService* large_icon_service)
+    : large_icon_service_(large_icon_service),
       favicon_cache_([[NSCache alloc] init]) {}
-
 FaviconLoader::~FaviconLoader() {}
 
 // TODO(pinkerton): How do we update the favicon if it's changed on the web?
 // We can possibly just rely on this class being purged or the app being killed
 // to reset it, but then how do we ensure the FaviconService is updated?
-UIImage* FaviconLoader::ImageForURL(const GURL& url,
-                                    const favicon_base::IconTypeSet& types,
-                                    ImageCompletionBlock block) {
+FaviconAttributes* FaviconLoader::FaviconForUrl(
+    const GURL& url,
+    float size,
+    float min_size,
+    FaviconAttributesCompletionBlock block) {
   NSString* key = base::SysUTF8ToNSString(url.spec());
-  id value = [favicon_cache_ objectForKey:key];
+  FaviconAttributes* value = [favicon_cache_ objectForKey:key];
   if (value) {
-    // [NSNull null] returns a singleton, so we can use it as a sentinel value
-    // and just compare pointers to validate whether the value is the sentinel
-    // or a valid UIImage.
-    if (value == [NSNull null])
-      return [UIImage imageNamed:@"default_favicon"];
-    return base::mac::ObjCCastStrict<UIImage>(value);
+    return value;
   }
 
-  // Kick off an async request for the favicon.
-  if (favicon_service_) {
-    int size = gfx::kFaviconSize * [UIScreen mainScreen].scale;
+  GURL block_url(url);
+  auto favicon_block = ^(const favicon_base::LargeIconResult& result) {
+    // GetLargeIconOrFallbackStyle() either returns a valid favicon (which can
+    // be the default favicon) or fallback attributes.
+    if (result.bitmap.is_valid()) {
+      scoped_refptr<base::RefCountedMemory> data =
+          result.bitmap.bitmap_data.get();
+      // The favicon code assumes favicons are PNG-encoded.
+      UIImage* favicon =
+          [UIImage imageWithData:[NSData dataWithBytes:data->front()
+                                                length:data->size()]];
+      FaviconAttributes* attributes =
+          [FaviconAttributes attributesWithImage:favicon];
+      [favicon_cache_ setObject:attributes forKey:key];
+      block(attributes);
+    }
+    DCHECK(result.fallback_icon_style);
+    FaviconAttributes* attributes = [FaviconAttributes
+        attributesWithMonogram:base::SysUTF16ToNSString(
+                                   favicon::GetFallbackIconText(block_url))
+                     textColor:skia::UIColorFromSkColor(
+                                   result.fallback_icon_style->text_color)
+               backgroundColor:skia::UIColorFromSkColor(
+                                   result.fallback_icon_style->background_color)
+        defaultBackgroundColor:result.fallback_icon_style->
+                               is_default_background_color];
+    [favicon_cache_ setObject:attributes forKey:key];
+    block(attributes);
+  };
 
-    std::unique_ptr<RequestData> request_data(new RequestData(key, block));
-    favicon_base::FaviconResultsCallback callback =
-        base::Bind(&FaviconLoader::OnFaviconAvailable, base::Unretained(this),
-                   base::Passed(&request_data));
-    favicon_service_->GetFaviconForPageURL(url, types, size, callback,
-                                           &cancelable_task_tracker_);
-  }
+  CGFloat favicon_size_in_pixels = [UIScreen mainScreen].scale * size;
+  CGFloat min_favicon_size = [UIScreen mainScreen].scale * min_size;
+  DCHECK(large_icon_service_);
+  large_icon_service_->GetLargeIconOrFallbackStyle(
+      url, min_favicon_size, favicon_size_in_pixels,
+      base::BindBlockArc(favicon_block), &cancelable_task_tracker_);
 
-  return [UIImage imageNamed:@"default_favicon"];
+  return [FaviconAttributes
+      attributesWithImage:[UIImage imageNamed:@"default_favicon"]];
 }
 
 void FaviconLoader::CancellAllRequests() {
   cancelable_task_tracker_.TryCancelAll();
 }
-
-void FaviconLoader::OnFaviconAvailable(
-    std::unique_ptr<RequestData> request_data,
-    const std::vector<favicon_base::FaviconRawBitmapResult>&
-        favicon_bitmap_results) {
-  DCHECK(request_data);
-  if (favicon_bitmap_results.size() < 1 ||
-      !favicon_bitmap_results[0].is_valid()) {
-    // Return early if there were no results or if it is invalid, after adding a
-    // "no favicon" entry to the cache so that we don't keep trying to fetch a
-    // missing favicon over and over.
-    [favicon_cache_ setObject:[NSNull null] forKey:[request_data->key copy]];
-    return;
-  }
-
-  // The favicon code assumes favicons are PNG-encoded.
-  NSData* image_data =
-      [NSData dataWithBytes:favicon_bitmap_results[0].bitmap_data->front()
-                     length:favicon_bitmap_results[0].bitmap_data->size()];
-  UIImage* favicon =
-      [UIImage imageWithData:image_data scale:[[UIScreen mainScreen] scale]];
-  [favicon_cache_ setObject:favicon forKey:[request_data->key copy]];
-
-  // Call the block to tell the caller this is complete.
-  if (request_data->block)
-    (request_data->block.get())(favicon);
-}
diff --git a/ios/chrome/browser/favicon/ios_chrome_favicon_loader_factory.mm b/ios/chrome/browser/favicon/ios_chrome_favicon_loader_factory.mm
index 09447f5..795f068 100644
--- a/ios/chrome/browser/favicon/ios_chrome_favicon_loader_factory.mm
+++ b/ios/chrome/browser/favicon/ios_chrome_favicon_loader_factory.mm
@@ -10,7 +10,7 @@
 #include "ios/chrome/browser/browser_state/browser_state_otr_helper.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #import "ios/chrome/browser/favicon/favicon_loader.h"
-#include "ios/chrome/browser/favicon/favicon_service_factory.h"
+#include "ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -36,7 +36,7 @@
     : BrowserStateKeyedServiceFactory(
           "FaviconLoader",
           BrowserStateDependencyManager::GetInstance()) {
-  DependsOn(ios::FaviconServiceFactory::GetInstance());
+  DependsOn(IOSChromeLargeIconServiceFactory::GetInstance());
 }
 
 IOSChromeFaviconLoaderFactory::~IOSChromeFaviconLoaderFactory() {}
@@ -47,8 +47,7 @@
   ios::ChromeBrowserState* browser_state =
       ios::ChromeBrowserState::FromBrowserState(context);
   return std::make_unique<FaviconLoader>(
-      ios::FaviconServiceFactory::GetForBrowserState(
-          browser_state, ServiceAccessType::IMPLICIT_ACCESS));
+      IOSChromeLargeIconServiceFactory::GetForBrowserState(browser_state));
 }
 
 web::BrowserState* IOSChromeFaviconLoaderFactory::GetBrowserStateToUse(
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/ios_chrome_flag_descriptions.cc
index 478c6cf..b8f81c7 100644
--- a/ios/chrome/browser/ios_chrome_flag_descriptions.cc
+++ b/ios/chrome/browser/ios_chrome_flag_descriptions.cc
@@ -56,6 +56,11 @@
     "Delay between the different fields of a form being autofilled. In "
     "milliseconds.";
 
+const char kAutofillManualFallbackName[] = "Enable autofill manual fallback";
+const char kAutofillManualFallbackDescription[] =
+    "When enabled, it shows the autofill UI with manual fallback when filling "
+    "forms.";
+
 const char kAutofillRestrictUnownedFieldsToFormlessCheckoutName[] =
     "Restrict formless form extraction";
 const char kAutofillRestrictUnownedFieldsToFormlessCheckoutDescription[] =
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.h b/ios/chrome/browser/ios_chrome_flag_descriptions.h
index 3e42adb6c..fc10a6b 100644
--- a/ios/chrome/browser/ios_chrome_flag_descriptions.h
+++ b/ios/chrome/browser/ios_chrome_flag_descriptions.h
@@ -36,6 +36,10 @@
 extern const char kAutofillIOSDelayBetweenFieldsName[];
 extern const char kAutofillIOSDelayBetweenFieldsDescription[];
 
+// Title and description for the flag to control if manual fallback is enabled.
+extern const char kAutofillManualFallbackName[];
+extern const char kAutofillManualFallbackDescription[];
+
 // Title and description for the flag to restrict extraction of formless forms
 // to checkout flows.
 extern const char kAutofillRestrictUnownedFieldsToFormlessCheckoutName[];
diff --git a/ios/chrome/browser/prefs/BUILD.gn b/ios/chrome/browser/prefs/BUILD.gn
index a487c49..4056494 100644
--- a/ios/chrome/browser/prefs/BUILD.gn
+++ b/ios/chrome/browser/prefs/BUILD.gn
@@ -48,6 +48,7 @@
     "//components/proxy_config",
     "//components/rappor",
     "//components/search_engines",
+    "//components/sessions",
     "//components/signin/core/browser",
     "//components/strings",
     "//components/sync",
diff --git a/ios/chrome/browser/prefs/browser_prefs.mm b/ios/chrome/browser/prefs/browser_prefs.mm
index 4e77dd0..b4023e1 100644
--- a/ios/chrome/browser/prefs/browser_prefs.mm
+++ b/ios/chrome/browser/prefs/browser_prefs.mm
@@ -29,6 +29,7 @@
 #include "components/proxy_config/pref_proxy_config_tracker_impl.h"
 #include "components/rappor/rappor_service_impl.h"
 #include "components/search_engines/template_url_prepopulate_data.h"
+#include "components/sessions/core/session_id_generator.h"
 #include "components/signin/core/browser/signin_pref_names.h"
 #include "components/strings/grit/components_locale_settings.h"
 #include "components/sync/base/sync_prefs.h"
@@ -68,6 +69,7 @@
   ios::NotificationPromo::RegisterPrefs(registry);
   PrefProxyConfigTrackerImpl::RegisterPrefs(registry);
   rappor::RapporServiceImpl::RegisterPrefs(registry);
+  sessions::SessionIdGenerator::RegisterPrefs(registry);
   update_client::RegisterPrefs(registry);
   variations::VariationsService::RegisterPrefs(registry);
 
diff --git a/ios/chrome/browser/sync/profile_sync_service_factory_unittest.cc b/ios/chrome/browser/sync/profile_sync_service_factory_unittest.cc
index c0f5de98..7c51c61 100644
--- a/ios/chrome/browser/sync/profile_sync_service_factory_unittest.cc
+++ b/ios/chrome/browser/sync/profile_sync_service_factory_unittest.cc
@@ -40,6 +40,10 @@
  protected:
   // Returns the collection of default datatypes.
   std::vector<syncer::ModelType> DefaultDatatypes() {
+    static_assert(41 == syncer::MODEL_TYPE_COUNT,
+                  "When adding a new type, you probably want to add it here as "
+                  "well (assuming it is already enabled).");
+
     std::vector<syncer::ModelType> datatypes;
 
     // Common types.
diff --git a/ios/chrome/browser/ui/bookmarks/BUILD.gn b/ios/chrome/browser/ui/bookmarks/BUILD.gn
index 3236c0a..eabd3b2b 100644
--- a/ios/chrome/browser/ui/bookmarks/BUILD.gn
+++ b/ios/chrome/browser/ui/bookmarks/BUILD.gn
@@ -99,6 +99,7 @@
     "//ios/chrome/browser/ui/bookmarks/cells",
     "//ios/chrome/browser/ui/colors",
     "//ios/chrome/browser/ui/commands",
+    "//ios/chrome/browser/ui/favicon:favicon_ui",
     "//ios/chrome/browser/ui/icons",
     "//ios/chrome/browser/ui/image_util",
     "//ios/chrome/browser/ui/keyboard",
diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm
index 3345337..9f3139fb 100644
--- a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm
+++ b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm
@@ -42,6 +42,8 @@
 #import "ios/chrome/browser/ui/bookmarks/cells/bookmark_table_cell_title_edit_delegate.h"
 #import "ios/chrome/browser/ui/bookmarks/cells/bookmark_table_signin_promo_cell.h"
 #import "ios/chrome/browser/ui/commands/application_commands.h"
+#import "ios/chrome/browser/ui/favicon/favicon_attributes.h"
+#import "ios/chrome/browser/ui/favicon/favicon_view.h"
 #import "ios/chrome/browser/ui/icons/chrome_icon.h"
 #import "ios/chrome/browser/ui/keyboard/UIKeyCommand+Chrome.h"
 #import "ios/chrome/browser/ui/material_components/utils.h"
@@ -1617,7 +1619,9 @@
     if (!URLCell)
       return;
     if (image)
-      URLCell.faviconView.image = image;
+      [URLCell.faviconView
+          configureWithAttributes:[FaviconAttributes
+                                      attributesWithImage:image]];
   } else {
     BookmarkTableCell* cell =
         [self.sharedState.tableView cellForRowAtIndexPath:indexPath];
diff --git a/ios/chrome/browser/ui/browser_view_controller.h b/ios/chrome/browser/ui/browser_view_controller.h
index 8ba127f8..074a4c5 100644
--- a/ios/chrome/browser/ui/browser_view_controller.h
+++ b/ios/chrome/browser/ui/browser_view_controller.h
@@ -99,10 +99,10 @@
 // Called when the user explicitly opens the tab switcher.
 - (void)userEnteredTabSwitcher;
 
-// Presents either the new tab tip or incognito tab tip in-product help bubbles
-// if the the user is in a valid state to see one of them. At most one bubble
-// will be shown. If the feature engagement tracker determines it is not valid
-// to see one of the bubbles, that bubble will not be shown.
+// Presents either in-product help bubbles if the the user is in a valid state
+// to see one of them. At most one bubble will be shown. If the feature
+// engagement tracker determines it is not valid to see one of the bubbles, that
+// bubble will not be shown.
 - (void)presentBubblesIfEligible;
 
 // Called when the browser state provided to this instance is being destroyed.
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm
index 83f9637..6c5f4bb 100644
--- a/ios/chrome/browser/ui/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -124,7 +124,8 @@
 #import "ios/chrome/browser/ui/browser_container/browser_container_view_controller.h"
 #import "ios/chrome/browser/ui/browser_view_controller_dependency_factory.h"
 #import "ios/chrome/browser/ui/browser_view_controller_helper.h"
-#import "ios/chrome/browser/ui/bubble/bubble_util.h"
+#import "ios/chrome/browser/ui/bubble/bubble_presenter.h"
+#import "ios/chrome/browser/ui/bubble/bubble_presenter_delegate.h"
 #import "ios/chrome/browser/ui/bubble/bubble_view_controller_presenter.h"
 #import "ios/chrome/browser/ui/chrome_web_view_factory.h"
 #import "ios/chrome/browser/ui/commands/application_commands.h"
@@ -414,6 +415,7 @@
 
 @interface BrowserViewController ()<ActivityServicePresentation,
                                     AppRatingPromptDelegate,
+                                    BubblePresenterDelegate,
                                     CaptivePortalDetectorTabHelperDelegate,
                                     CRWNativeContentProvider,
                                     CRWWebStateDelegate,
@@ -685,19 +687,7 @@
 // Coordinator for the popup menus.
 @property(nonatomic, strong) PopupMenuCoordinator* popupMenuCoordinator;
 
-// Used to display the bottom toolbar tip in-product help promotion bubble.
-// |nil| if the tip bubble has not yet been presented. Once the bubble is
-// dismissed, it remains allocated so that |userEngaged| remains accessible.
-@property(nonatomic, strong)
-    BubbleViewControllerPresenter* bottomToolbarTipBubblePresenter;
-// Used to display the new tab tip in-product help promotion bubble. |nil| if
-// the new tab tip bubble has not yet been presented. Once the bubble is
-// dismissed, it remains allocated so that |userEngaged| remains accessible.
-@property(nonatomic, strong)
-    BubbleViewControllerPresenter* tabTipBubblePresenter;
-// Used to display the new incognito tab tip in-product help promotion bubble.
-@property(nonatomic, strong)
-    BubbleViewControllerPresenter* incognitoTabTipBubblePresenter;
+@property(nonatomic, strong) BubblePresenter* bubblePresenter;
 
 // Primary toolbar.
 @property(nonatomic, strong) id<PrimaryToolbarCoordinator>
@@ -790,8 +780,6 @@
 // TODO(crbug.com/522721): Support size changes for all popups and modal
 // dialogs.
 - (void)dismissPopups;
-// Returns whether |tab| is scrolled to the top.
-- (BOOL)isTabScrolledToTop:(Tab*)tab;
 // Returns the footer view if one exists (e.g. the voice search bar).
 - (UIView*)footerView;
 // Returns web contents frame without including primary toolbar.
@@ -811,44 +799,6 @@
 // Dismisses the "rate this app" dialog.
 - (void)dismissRateThisAppDialog;
 
-// Bubble Views
-// ------------
-// Returns a bubble associated with an in-product help promotion if
-// it is valid to show the promotion and |nil| otherwise. |feature| is the
-// base::Feature object associated with the given promotion. |direction| is the
-// direction the bubble's arrow is pointing. |alignment| is the alignment of the
-// arrow on the button. |text| is the text displayed by the bubble. This method
-// requires that |self.browserState| is not NULL.
-- (BubbleViewControllerPresenter*)
-bubblePresenterForFeature:(const base::Feature&)feature
-                direction:(BubbleArrowDirection)direction
-                alignment:(BubbleAlignment)alignment
-                     text:(NSString*)text;
-
-// Waits to present a bubble associated with the new tab tip in-product help
-// promotion until the feature engagement tracker database is fully initialized.
-// Does not present the bubble if |tabTipBubblePresenter.userEngaged| is |YES|
-// to prevent resetting |tabTipBubblePresenter| and affecting the value of
-// |userEngaged|. Does not present the bubble if the feature engagement tracker
-// determines it is not valid to present it. This method requires that
-// |self.browserState| is not NULL.
-- (void)presentNewTabTipBubbleOnInitialized;
-// Optionally presents a bubble associated with the new tab tip in-product help
-// promotion. If the feature engagement tracker determines it is valid to show
-// the new tab tip, then it initializes |tabTipBubblePresenter| and presents
-// the bubble. If it is not valid to show the new tab tip,
-// |tabTipBubblePresenter| is set to |nil| and no bubble is shown. This method
-// requires that |self.browserState| is not NULL.
-- (void)presentNewTabTipBubble;
-// Waits to present a bubble associated with the new incognito tab tip
-// in-product help promotion until the feature engagement tracker database is
-// fully initialized. This method requires that |self.browserState| is
-// not NULL.
-- (void)presentNewIncognitoTabTipBubbleOnInitialized;
-// Presents a bubble associated with the new incognito tab tip in-product help
-// promotion. This method requires that |self.browserState| is not NULL.
-- (void)presentNewIncognitoTabTipBubble;
-
 // Find Bar UI
 // -----------
 // Update find bar with model data. If |shouldFocus| is set to YES, the text
@@ -966,9 +916,7 @@
 @synthesize tabStripCoordinator = _tabStripCoordinator;
 @synthesize tabStripView = _tabStripView;
 @synthesize popupMenuCoordinator = _popupMenuCoordinator;
-@synthesize bottomToolbarTipBubblePresenter = _bottomToolbarTipBubblePresenter;
-@synthesize tabTipBubblePresenter = _tabTipBubblePresenter;
-@synthesize incognitoTabTipBubblePresenter = _incognitoTabTipBubblePresenter;
+@synthesize bubblePresenter = _bubblePresenter;
 @synthesize primaryToolbarCoordinator = _primaryToolbarCoordinator;
 @synthesize secondaryToolbarCoordinator = _secondaryToolbarCoordinator;
 @synthesize primaryToolbarOffsetConstraint = _primaryToolbarOffsetConstraint;
@@ -1391,6 +1339,18 @@
   return NO;
 }
 
+- (BubblePresenter*)bubblePresenter {
+  if (!_bubblePresenter) {
+    _bubblePresenter =
+        [[BubblePresenter alloc] initWithBrowserState:self.browserState
+                                             delegate:self
+                                   rootViewController:self];
+    _bubblePresenter.dispatcher = self.dispatcher;
+    self.popupMenuCoordinator.bubblePresenter = _bubblePresenter;
+  }
+  return _bubblePresenter;
+}
+
 #pragma mark - Public methods
 
 - (void)setPrimary:(BOOL)primary {
@@ -1408,15 +1368,13 @@
 }
 
 - (void)userEnteredTabSwitcher {
-  if ([self.tabTipBubblePresenter isUserEngaged]) {
+  if ([self.bubblePresenter.tabTipBubblePresenter isUserEngaged]) {
     base::RecordAction(UserMetricsAction("NewTabTipTargetSelected"));
   }
 }
 
 - (void)presentBubblesIfEligible {
-  [self presentNewTabTipBubbleOnInitialized];
-  [self presentNewIncognitoTabTipBubbleOnInitialized];
-  [self presentBottomToolbarTipBubbleOnInitialized];
+  [self.bubblePresenter presentBubblesIfEligible];
 }
 
 - (void)browserStateDestroyed {
@@ -1517,8 +1475,7 @@
   }
   [_dialogPresenter cancelAllDialogs];
   [self.dispatcher hidePageInfo];
-  [self.tabTipBubblePresenter dismissAnimated:NO];
-  [self.incognitoTabTipBubblePresenter dismissAnimated:NO];
+  [self.bubblePresenter dismissBubbles];
   if (_voiceSearchController)
     _voiceSearchController->DismissMicPermissionsHelp();
 
@@ -1854,7 +1811,7 @@
   // Update the tab strip visibility.
   if (self.tabStripView) {
     [self showTabStripView:self.tabStripView];
-    self.tabStripView.hidden = ![self canShowTabStrip];
+    [self.tabStripCoordinator hideTabStrip:![self canShowTabStrip]];
     _fakeStatusBarView.hidden = ![self canShowTabStrip];
     [self addConstraintsToPrimaryToolbar];
   }
@@ -2354,8 +2311,7 @@
     self.popupMenuCoordinator = [[PopupMenuCoordinator alloc]
         initWithBaseViewController:self
                       browserState:self.browserState];
-    self.popupMenuCoordinator.incognitoTabTipPresenter =
-        self.incognitoTabTipBubblePresenter;
+    self.popupMenuCoordinator.bubblePresenter = self.bubblePresenter;
     self.popupMenuCoordinator.dispatcher = _dispatcher;
     self.popupMenuCoordinator.webStateList = [_model webStateList];
     self.popupMenuCoordinator.UIUpdater = _toolbarCoordinatorAdaptor;
@@ -2597,21 +2553,7 @@
     [self.dispatcher dismissToolsMenu];
     [_tabHistoryCoordinator dismissHistoryPopup];
   }
-  [self.tabTipBubblePresenter dismissAnimated:NO];
-  [self.incognitoTabTipBubblePresenter dismissAnimated:NO];
-}
-
-- (BOOL)isTabScrolledToTop:(Tab*)tab {
-  CGPoint scrollOffset =
-      tab.webState->GetWebViewProxy().scrollViewProxy.contentOffset;
-
-  // If there is a native controller, use the native controller's scroll offset.
-  id nativeController = [self nativeControllerForTab:tab];
-  if ([nativeController conformsToProtocol:@protocol(CRWNativeContent)] &&
-      [nativeController respondsToSelector:@selector(scrollOffset)]) {
-    scrollOffset = [nativeController scrollOffset];
-  }
-  return CGPointEqualToPoint(scrollOffset, CGPointZero);
+  [self.bubblePresenter dismissBubbles];
 }
 
 - (UIView*)footerView {
@@ -2719,265 +2661,6 @@
   }
 }
 
-#pragma mark - Private Methods: Bubble views
-
-- (BubbleViewControllerPresenter*)
-bubblePresenterForFeature:(const base::Feature&)feature
-                direction:(BubbleArrowDirection)direction
-                alignment:(BubbleAlignment)alignment
-                     text:(NSString*)text {
-  DCHECK(self.browserState);
-  if (!feature_engagement::TrackerFactory::GetForBrowserState(self.browserState)
-           ->ShouldTriggerHelpUI(feature)) {
-    return nil;
-  }
-  // Capture |weakSelf| instead of the feature engagement tracker object
-  // because |weakSelf| will safely become |nil| if it is deallocated, whereas
-  // the feature engagement tracker will remain pointing to invalid memory if
-  // its owner (the ChromeBrowserState) is deallocated.
-  __weak BrowserViewController* weakSelf = self;
-  void (^dismissalCallback)(void) = ^{
-    BrowserViewController* strongSelf = weakSelf;
-    if (strongSelf) {
-      feature_engagement::TrackerFactory::GetForBrowserState(
-          strongSelf.browserState)
-          ->Dismissed(feature);
-    }
-  };
-
-  BubbleViewControllerPresenter* bubbleViewControllerPresenter =
-      [[BubbleViewControllerPresenter alloc] initWithText:text
-                                           arrowDirection:direction
-                                                alignment:alignment
-                                        dismissalCallback:dismissalCallback];
-
-  return bubbleViewControllerPresenter;
-}
-
-// Waits to present a bubble associated with the bottom toolbar tip in-product
-// help promotion until the feature engagement tracker database is fully
-// initialized. This method requires that |self.browserState| is not NULL.
-- (void)presentBottomToolbarTipBubbleOnInitialized {
-  DCHECK(self.browserState);
-  // If the tip bubble has already been presented and the user is still
-  // considered engaged, it can't be overwritten or set to |nil| or else it will
-  // reset the |userEngaged| property. Once the user is not engaged, the bubble
-  // can be safely overwritten or set to |nil|.
-  if (!self.bottomToolbarTipBubblePresenter.isUserEngaged) {
-    __weak BrowserViewController* weakSelf = self;
-    void (^onInitializedBlock)(bool) = ^(bool successfullyLoaded) {
-      if (!successfullyLoaded)
-        return;
-      [weakSelf presentBottomToolbarTipBubble];
-    };
-
-    // Because the new tab tip occurs on startup, the feature engagement
-    // tracker's database is not guaranteed to be loaded by this time. For the
-    // bubble to appear properly, a callback is used to guarantee the event data
-    // is loaded before the check to see if the promotion should be displayed.
-    feature_engagement::TrackerFactory::GetForBrowserState(self.browserState)
-        ->AddOnInitializedCallback(base::BindBlockArc(onInitializedBlock));
-  }
-}
-
-// Presents a bubble associated with the bottom toolbar tip in-product help
-// promotion. This method requires that |self.browserState| is not NULL.
-- (void)presentBottomToolbarTipBubble {
-  if (!IsSplitToolbarMode())
-    return;
-
-  DCHECK(self.browserState);
-  // If the BVC is not visible, do not present the bubble.
-  if (!self.viewVisible)
-    return;
-  // Do not present the bubble if there is no current tab.
-  Tab* currentTab = [self.tabModel currentTab];
-  if (!currentTab)
-    return;
-
-  // Do not present the bubble if the tab is not scrolled to the top.
-  if (![self isTabScrolledToTop:currentTab])
-    return;
-
-  BubbleArrowDirection arrowDirection = BubbleArrowDirectionDown;
-  NSString* text = l10n_util::GetNSStringWithFixup(
-      IDS_IOS_BOTTOM_TOOLBAR_IPH_PROMOTION_TEXT);
-  UILayoutGuide* guide =
-      [NamedGuide guideWithName:kSearchButtonGuide view:self.view];
-  DCHECK(guide);
-  CGPoint anchorPoint =
-      bubble_util::AnchorPoint(guide.layoutFrame, arrowDirection);
-  CGPoint tipAnchor = [guide.owningView convertPoint:anchorPoint
-                                              toView:guide.owningView.window];
-
-  // If the feature engagement tracker does not consider it valid to display
-  // the new tab tip, then end early to prevent the potential reassignment
-  // of the existing |bottomToolbarTipBubblePresenter| to nil.
-  BubbleViewControllerPresenter* presenter = [self
-      bubblePresenterForFeature:feature_engagement::kIPHBottomToolbarTipFeature
-                      direction:arrowDirection
-                      alignment:BubbleAlignmentCenter
-                           text:text];
-  if (!presenter)
-    return;
-
-  self.bottomToolbarTipBubblePresenter = presenter;
-
-  [self.bottomToolbarTipBubblePresenter presentInViewController:self
-                                                           view:self.view
-                                                    anchorPoint:tipAnchor];
-}
-
-- (void)presentNewTabTipBubbleOnInitialized {
-  DCHECK(self.browserState);
-  // If the tab tip bubble has already been presented and the user is still
-  // considered engaged, it can't be overwritten or set to |nil| or else it will
-  // reset the |userEngaged| property. Once the user is not engaged, the bubble
-  // can be safely overwritten or set to |nil|.
-  if (!self.tabTipBubblePresenter.isUserEngaged) {
-    __weak BrowserViewController* weakSelf = self;
-    void (^onInitializedBlock)(bool) = ^(bool successfullyLoaded) {
-      if (!successfullyLoaded)
-        return;
-      [weakSelf presentNewTabTipBubble];
-    };
-
-    // Because the new tab tip occurs on startup, the feature engagement
-    // tracker's database is not guaranteed to be loaded by this time. For the
-    // bubble to appear properly, a callback is used to guarantee the event data
-    // is loaded before the check to see if the promotion should be displayed.
-    feature_engagement::TrackerFactory::GetForBrowserState(self.browserState)
-        ->AddOnInitializedCallback(base::BindBlockArc(onInitializedBlock));
-  }
-}
-
-- (void)presentNewTabTipBubble {
-  DCHECK(self.browserState);
-  // If the BVC is not visible, do not present the bubble.
-  if (!self.viewVisible)
-    return;
-  // Do not present the bubble if there is no current tab or if the current tab
-  // is the NTP.
-  Tab* currentTab = [self.tabModel currentTab];
-  if (!currentTab)
-    return;
-  if (currentTab.webState->GetVisibleURL() == kChromeUINewTabURL)
-    return;
-
-  // Do not present the bubble if the tab is not scrolled to the top.
-  if (![self isTabScrolledToTop:currentTab])
-    return;
-
-  BubbleArrowDirection arrowDirection =
-      (IsUIRefreshPhase1Enabled() && IsSplitToolbarMode())
-          ? BubbleArrowDirectionDown
-          : BubbleArrowDirectionUp;
-  NSString* text =
-      l10n_util::GetNSStringWithFixup(IDS_IOS_NEW_TAB_IPH_PROMOTION_TEXT);
-  CGPoint tabSwitcherAnchor;
-  if (IsIPadIdiom()) {
-    tabSwitcherAnchor = [self.tabStripCoordinator
-        anchorPointForTabSwitcherButton:arrowDirection];
-  } else {
-    UILayoutGuide* guide =
-        [NamedGuide guideWithName:kTabSwitcherGuide view:self.view];
-    DCHECK(guide);
-    CGPoint anchorPoint =
-        bubble_util::AnchorPoint(guide.layoutFrame, arrowDirection);
-    tabSwitcherAnchor = [guide.owningView convertPoint:anchorPoint
-                                                toView:guide.owningView.window];
-  }
-
-  // If the feature engagement tracker does not consider it valid to display
-  // the new tab tip, then end early to prevent the potential reassignment
-  // of the existing |tabTipBubblePresenter| to nil.
-  BubbleViewControllerPresenter* presenter =
-      [self bubblePresenterForFeature:feature_engagement::kIPHNewTabTipFeature
-                            direction:arrowDirection
-                            alignment:BubbleAlignmentTrailing
-                                 text:text];
-  if (!presenter)
-    return;
-
-  self.tabTipBubblePresenter = presenter;
-
-  [self.tabTipBubblePresenter presentInViewController:self
-                                                 view:self.view
-                                          anchorPoint:tabSwitcherAnchor];
-}
-
-- (void)presentNewIncognitoTabTipBubbleOnInitialized {
-  DCHECK(self.browserState);
-  // Do not override |incognitoTabtipBubblePresenter| or set it to nil if the
-  // user is still considered engaged.
-  if (!self.incognitoTabTipBubblePresenter.isUserEngaged) {
-    __weak BrowserViewController* weakSelf = self;
-    void (^onInitializedBlock)(bool) = ^(bool successfullyLoaded) {
-      if (!successfullyLoaded)
-        return;
-      [weakSelf presentNewIncognitoTabTipBubble];
-    };
-
-    // Use a callback in case the new incognito tab tip should be shown on
-    // startup. This ensures that the tracker's database will be fully loaded
-    // before checking if the promotion should be displayed.
-    feature_engagement::TrackerFactory::GetForBrowserState(self.browserState)
-        ->AddOnInitializedCallback(base::BindBlockArc(onInitializedBlock));
-  }
-}
-
-- (void)presentNewIncognitoTabTipBubble {
-  DCHECK(self.browserState);
-  // If the BVC is not visible, do not present the bubble.
-  if (!self.viewVisible)
-    return;
-
-  // Do not present the bubble if there is no current tab.
-  Tab* currentTab = [self.tabModel currentTab];
-  if (!currentTab)
-    return;
-
-  // Do not present the bubble if the tab is not scrolled to the top.
-  if (![self isTabScrolledToTop:currentTab])
-    return;
-
-  BubbleArrowDirection arrowDirection =
-      (IsUIRefreshPhase1Enabled() && IsSplitToolbarMode())
-          ? BubbleArrowDirectionDown
-          : BubbleArrowDirectionUp;
-  NSString* text = l10n_util::GetNSStringWithFixup(
-      IDS_IOS_NEW_INCOGNITO_TAB_IPH_PROMOTION_TEXT);
-  CGPoint toolsButtonAnchor;
-  UILayoutGuide* guide =
-      [NamedGuide guideWithName:kToolsMenuGuide view:self.view];
-  DCHECK(guide);
-  CGPoint anchorPoint =
-      bubble_util::AnchorPoint(guide.layoutFrame, arrowDirection);
-  toolsButtonAnchor = [guide.owningView convertPoint:anchorPoint
-                                              toView:guide.owningView.window];
-
-  // If the feature engagement tracker does not consider it valid to display
-  // the incognito tab tip, then end early to prevent the potential reassignment
-  // of the existing |incognitoTabTipBubblePresenter| to nil.
-  BubbleViewControllerPresenter* presenter =
-      [self bubblePresenterForFeature:feature_engagement::
-                                          kIPHNewIncognitoTabTipFeature
-                            direction:arrowDirection
-                            alignment:BubbleAlignmentTrailing
-                                 text:text];
-  if (!presenter)
-    return;
-
-  self.incognitoTabTipBubblePresenter = presenter;
-  self.popupMenuCoordinator.incognitoTabTipPresenter = presenter;
-
-  [self.incognitoTabTipBubblePresenter
-      presentInViewController:self
-                         view:self.view
-                  anchorPoint:toolsButtonAnchor];
-  [self.dispatcher triggerToolsMenuButtonAnimation];
-}
-
 #pragma mark - Private Methods: Find Bar UI
 
 - (void)hideFindBarWithAnimation:(BOOL)animate {
@@ -3422,6 +3105,35 @@
 
 #pragma mark - ** Protocol Implementations and Helpers **
 
+#pragma mark - BubblePresenterDelegate
+
+- (web::WebState*)currentWebStateForBubblePresenter:
+    (BubblePresenter*)bubblePresenter {
+  DCHECK(bubblePresenter == self.bubblePresenter);
+  return self.currentWebState;
+}
+
+- (BOOL)rootViewVisibleForBubblePresenter:(BubblePresenter*)bubblePresenter {
+  DCHECK(bubblePresenter == self.bubblePresenter);
+  return self.viewVisible;
+}
+
+- (BOOL)isTabScrolledToTopForBubblePresenter:(BubblePresenter*)bubblePresenter {
+  DCHECK(bubblePresenter == self.bubblePresenter);
+  CGPoint scrollOffset =
+      self.currentWebState->GetWebViewProxy().scrollViewProxy.contentOffset;
+
+  // If there is a native controller, use the native controller's scroll offset.
+  id nativeController =
+      [self nativeControllerForTab:[self.tabModel currentTab]];
+  if ([nativeController conformsToProtocol:@protocol(CRWNativeContent)] &&
+      [nativeController respondsToSelector:@selector(scrollOffset)]) {
+    scrollOffset = [nativeController scrollOffset];
+  }
+
+  return CGPointEqualToPoint(scrollOffset, CGPointZero);
+}
+
 #pragma mark - SnapshotGeneratorDelegate methods
 
 - (BOOL)canTakeSnapshotForWebState:(web::WebState*)webState {
@@ -4774,9 +4486,11 @@
 
   [configuration setUserAgentType:self.userAgentType];
 
-  if (self.incognitoTabTipBubblePresenter.triggerFollowUpAction) {
+  if (self.bubblePresenter.incognitoTabTipBubblePresenter
+          .triggerFollowUpAction) {
     [configuration setHighlightNewIncognitoTabCell:YES];
-    [self.incognitoTabTipBubblePresenter setTriggerFollowUpAction:NO];
+    self.bubblePresenter.incognitoTabTipBubblePresenter.triggerFollowUpAction =
+        NO;
   }
 
   return configuration;
@@ -5167,7 +4881,7 @@
 
   switch (type) {
     case PopupMenuCommandTypeToolsMenu:
-      if (self.incognitoTabTipBubblePresenter.isUserEngaged) {
+      if (self.bubblePresenter.incognitoTabTipBubblePresenter.isUserEngaged) {
         base::RecordAction(
             UserMetricsAction("NewIncognitoTabTipTargetSelected"));
       }
diff --git a/ios/chrome/browser/ui/bubble/BUILD.gn b/ios/chrome/browser/ui/bubble/BUILD.gn
index c62cf399..1567515 100644
--- a/ios/chrome/browser/ui/bubble/BUILD.gn
+++ b/ios/chrome/browser/ui/bubble/BUILD.gn
@@ -5,11 +5,13 @@
 source_set("bubble") {
   configs += [ "//build/config/compiler:enable_arc" ]
   sources = [
+    "bubble_presenter.h",
+    "bubble_presenter.mm",
+    "bubble_presenter_delegate.h",
     "bubble_util.h",
     "bubble_util.mm",
     "bubble_view.h",
     "bubble_view.mm",
-    "bubble_view_anchor_point_provider.h",
     "bubble_view_controller.h",
     "bubble_view_controller.mm",
     "bubble_view_controller_presenter.h",
@@ -18,10 +20,19 @@
   deps = [
     "//base",
     "//base:i18n",
+    "//components/feature_engagement/public",
+    "//ios/chrome/app/strings",
+    "//ios/chrome/browser",
+    "//ios/chrome/browser/browser_state",
+    "//ios/chrome/browser/feature_engagement",
     "//ios/chrome/browser/ui",
     "//ios/chrome/browser/ui/colors",
+    "//ios/chrome/browser/ui/commands",
+    "//ios/chrome/browser/ui/util",
     "//ios/chrome/common",
     "//ios/third_party/material_components_ios",
+    "//net",
+    "//ui/base",
   ]
   libs = [ "UIKit.framework" ]
 }
diff --git a/ios/chrome/browser/ui/bubble/bubble_presenter.h b/ios/chrome/browser/ui/bubble/bubble_presenter.h
new file mode 100644
index 0000000..f294a203
--- /dev/null
+++ b/ios/chrome/browser/ui/bubble/bubble_presenter.h
@@ -0,0 +1,53 @@
+// 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 IOS_CHROME_BROWSER_UI_BUBBLE_BUBBLE_PRESENTER_H_
+#define IOS_CHROME_BROWSER_UI_BUBBLE_BUBBLE_PRESENTER_H_
+
+#import <UIKit/UIKit.h>
+
+namespace ios {
+class ChromeBrowserState;
+}
+
+@protocol BubblePresenterDelegate;
+@class BubbleViewControllerPresenter;
+@protocol ToolbarCommands;
+
+// Object handling the presentation of the different bubbles tips. The class is
+// holding all the bubble presenters.
+@interface BubblePresenter : NSObject
+
+// Initializes a BubblePresenter whose bubbles are presented on the
+// |rootViewController|.
+- (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState
+                            delegate:(id<BubblePresenterDelegate>)delegate
+                  rootViewController:(UIViewController*)rootViewController
+    NS_DESIGNATED_INITIALIZER;
+
+- (instancetype)init NS_UNAVAILABLE;
+
+// Used to display the new tab tip in-product help promotion bubble. |nil| if
+// the new tab tip bubble has not yet been presented. Once the bubble is
+// dismissed, it remains allocated so that |userEngaged| remains accessible.
+@property(nonatomic, strong, readonly)
+    BubbleViewControllerPresenter* tabTipBubblePresenter;
+// Used to display the new incognito tab tip in-product help promotion bubble.
+@property(nonatomic, strong, readonly)
+    BubbleViewControllerPresenter* incognitoTabTipBubblePresenter;
+
+@property(nonatomic, weak) id<ToolbarCommands> dispatcher;
+
+// Presents either in-product help bubbles if the the user is in a valid state
+// to see one of them. At most one bubble will be shown. If the feature
+// engagement tracker determines it is not valid to see one of the bubbles, that
+// bubble will not be shown.
+- (void)presentBubblesIfEligible;
+
+// Dismisses all bubbles.
+- (void)dismissBubbles;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_BUBBLE_BUBBLE_PRESENTER_H_
diff --git a/ios/chrome/browser/ui/bubble/bubble_presenter.mm b/ios/chrome/browser/ui/bubble/bubble_presenter.mm
new file mode 100644
index 0000000..810d5f871
--- /dev/null
+++ b/ios/chrome/browser/ui/bubble/bubble_presenter.mm
@@ -0,0 +1,311 @@
+// 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.
+
+#import "ios/chrome/browser/ui/bubble/bubble_presenter.h"
+
+#include "base/mac/bind_objc_block.h"
+#include "components/feature_engagement/public/feature_constants.h"
+#include "components/feature_engagement/public/tracker.h"
+#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
+#include "ios/chrome/browser/chrome_url_constants.h"
+#include "ios/chrome/browser/feature_engagement/tracker_factory.h"
+#include "ios/chrome/browser/feature_engagement/tracker_util.h"
+#import "ios/chrome/browser/ui/bubble/bubble_presenter_delegate.h"
+#import "ios/chrome/browser/ui/bubble/bubble_util.h"
+#import "ios/chrome/browser/ui/bubble/bubble_view_controller_presenter.h"
+#import "ios/chrome/browser/ui/commands/toolbar_commands.h"
+#import "ios/chrome/browser/ui/uikit_ui_util.h"
+#import "ios/chrome/browser/ui/util/named_guide.h"
+#import "ios/chrome/browser/ui/util/named_guide_util.h"
+#include "ios/chrome/grit/ios_strings.h"
+#import "ios/web/public/web_state/ui/crw_web_view_proxy.h"
+#import "ios/web/public/web_state/ui/crw_web_view_scroll_view_proxy.h"
+#import "ios/web/public/web_state/web_state.h"
+#include "ui/base/l10n/l10n_util.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+@interface BubblePresenter ()
+
+// Used to display the bottom toolbar tip in-product help promotion bubble.
+// |nil| if the tip bubble has not yet been presented. Once the bubble is
+// dismissed, it remains allocated so that |userEngaged| remains accessible.
+@property(nonatomic, strong)
+    BubbleViewControllerPresenter* bottomToolbarTipBubblePresenter;
+@property(nonatomic, strong, readwrite)
+    BubbleViewControllerPresenter* tabTipBubblePresenter;
+@property(nonatomic, strong, readwrite)
+    BubbleViewControllerPresenter* incognitoTabTipBubblePresenter;
+
+@property(nonatomic, assign) ios::ChromeBrowserState* browserState;
+@property(nonatomic, weak) id<BubblePresenterDelegate> delegate;
+@property(nonatomic, weak) UIViewController* rootViewController;
+
+@end
+
+@implementation BubblePresenter
+
+@synthesize bottomToolbarTipBubblePresenter = _bottomToolbarTipBubblePresenter;
+@synthesize tabTipBubblePresenter = _tabTipBubblePresenter;
+@synthesize incognitoTabTipBubblePresenter = _incognitoTabTipBubblePresenter;
+@synthesize browserState = _browserState;
+@synthesize delegate = _delegate;
+@synthesize dispatcher = _dispatcher;
+@synthesize rootViewController = _rootViewController;
+
+#pragma mark - Public
+
+- (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState
+                            delegate:(id<BubblePresenterDelegate>)delegate
+                  rootViewController:(UIViewController*)rootViewController {
+  self = [super init];
+  if (self) {
+    _browserState = browserState;
+    _delegate = delegate;
+    _rootViewController = rootViewController;
+  }
+  return self;
+}
+
+- (void)presentBubblesIfEligible {
+  DCHECK(self.browserState);
+  // Waits to present the bubbles until the feature engagement tracker database
+  // is fully initialized. This method requires that |self.browserState| is not
+  // NULL.
+  __weak BubblePresenter* weakSelf = self;
+  void (^onInitializedBlock)(bool) = ^(bool successfullyLoaded) {
+    if (!successfullyLoaded)
+      return;
+    [weakSelf presentBubbles];
+  };
+
+  // Because the new tab tip occurs on startup, the feature engagement
+  // tracker's database is not guaranteed to be loaded by this time. For the
+  // bubble to appear properly, a callback is used to guarantee the event data
+  // is loaded before the check to see if the promotion should be displayed.
+  feature_engagement::TrackerFactory::GetForBrowserState(self.browserState)
+      ->AddOnInitializedCallback(base::BindBlockArc(onInitializedBlock));
+}
+
+- (void)dismissBubbles {
+  [self.tabTipBubblePresenter dismissAnimated:NO];
+  [self.incognitoTabTipBubblePresenter dismissAnimated:NO];
+  [self.bottomToolbarTipBubblePresenter dismissAnimated:NO];
+}
+
+#pragma mark - Private
+
+- (void)presentBubbles {
+  // If the tip bubble has already been presented and the user is still
+  // considered engaged, it can't be overwritten or set to |nil| or else it will
+  // reset the |userEngaged| property. Once the user is not engaged, the bubble
+  // can be safely overwritten or set to |nil|.
+  if (!self.tabTipBubblePresenter.isUserEngaged)
+    [self presentNewTabTipBubble];
+  if (!self.incognitoTabTipBubblePresenter.isUserEngaged)
+    [self presentNewIncognitoTabTipBubble];
+  if (!self.bottomToolbarTipBubblePresenter.isUserEngaged)
+    [self presentBottomToolbarTipBubble];
+}
+
+// Presents and returns a bubble view controller for the |feature| with an arrow
+// |direction|, an arrow |alignment| and a |text| on an |anchorPoint|.
+- (BubbleViewControllerPresenter*)
+presentBubbleForFeature:(const base::Feature&)feature
+              direction:(BubbleArrowDirection)direction
+              alignment:(BubbleAlignment)alignment
+                   text:(NSString*)text
+            anchorPoint:(CGPoint)anchorPoint {
+  BubbleViewControllerPresenter* presenter =
+      [self bubblePresenterForFeature:feature
+                            direction:direction
+                            alignment:alignment
+                                 text:text];
+
+  [presenter presentInViewController:self.rootViewController
+                                view:self.rootViewController.view
+                         anchorPoint:anchorPoint];
+
+  return presenter;
+}
+
+// Presents a bubble associated with the bottom toolbar tip in-product help
+// promotion. This method requires that |self.browserState| is not NULL.
+- (void)presentBottomToolbarTipBubble {
+  if (!IsSplitToolbarMode())
+    return;
+
+  if (![self canPresentBubble])
+    return;
+
+  BubbleArrowDirection arrowDirection = BubbleArrowDirectionDown;
+  NSString* text = l10n_util::GetNSStringWithFixup(
+      IDS_IOS_BOTTOM_TOOLBAR_IPH_PROMOTION_TEXT);
+  CGPoint searchButtonAnchor =
+      [self anchorPointToGuide:kSearchButtonGuide direction:arrowDirection];
+
+  // If the feature engagement tracker does not consider it valid to display
+  // the new tab tip, then end early to prevent the potential reassignment
+  // of the existing |bottomToolbarTipBubblePresenter| to nil.
+  BubbleViewControllerPresenter* presenter = [self
+      presentBubbleForFeature:feature_engagement::kIPHBottomToolbarTipFeature
+                    direction:arrowDirection
+                    alignment:BubbleAlignmentCenter
+                         text:text
+                  anchorPoint:searchButtonAnchor];
+  if (presenter)
+    self.bottomToolbarTipBubblePresenter = presenter;
+}
+
+// Optionally presents a bubble associated with the new tab tip in-product help
+// promotion. If the feature engagement tracker determines it is valid to show
+// the new tab tip, then it initializes |tabTipBubblePresenter| and presents
+// the bubble. If it is not valid to show the new tab tip,
+// |tabTipBubblePresenter| is set to |nil| and no bubble is shown. This method
+// requires that |self.browserState| is not NULL.
+- (void)presentNewTabTipBubble {
+  if (![self canPresentBubble])
+    return;
+
+  // Do not present the new tab tips on NTP.
+  if (![self.delegate currentWebStateForBubblePresenter:self] ||
+      [self.delegate currentWebStateForBubblePresenter:self]->GetVisibleURL() ==
+          kChromeUINewTabURL)
+    return;
+
+  BubbleArrowDirection arrowDirection =
+      (IsUIRefreshPhase1Enabled() && IsSplitToolbarMode())
+          ? BubbleArrowDirectionDown
+          : BubbleArrowDirectionUp;
+  NSString* text =
+      l10n_util::GetNSStringWithFixup(IDS_IOS_NEW_TAB_IPH_PROMOTION_TEXT);
+  CGPoint tabSwitcherAnchor;
+  if (IsIPadIdiom()) {
+    tabSwitcherAnchor = [self anchorPointToGuide:kTabStripTabSwitcherGuide
+                                       direction:arrowDirection];
+  } else {
+    tabSwitcherAnchor =
+        [self anchorPointToGuide:kTabSwitcherGuide direction:arrowDirection];
+  }
+
+  // If the feature engagement tracker does not consider it valid to display
+  // the new tab tip, then end early to prevent the potential reassignment
+  // of the existing |tabTipBubblePresenter| to nil.
+  BubbleViewControllerPresenter* presenter =
+      [self presentBubbleForFeature:feature_engagement::kIPHNewTabTipFeature
+                          direction:arrowDirection
+                          alignment:BubbleAlignmentTrailing
+                               text:text
+                        anchorPoint:tabSwitcherAnchor];
+  if (presenter)
+    self.tabTipBubblePresenter = presenter;
+}
+
+// Presents a bubble associated with the new incognito tab tip in-product help
+// promotion. This method requires that |self.browserState| is not NULL.
+- (void)presentNewIncognitoTabTipBubble {
+  if (![self canPresentBubble])
+    return;
+
+  BubbleArrowDirection arrowDirection =
+      (IsUIRefreshPhase1Enabled() && IsSplitToolbarMode())
+          ? BubbleArrowDirectionDown
+          : BubbleArrowDirectionUp;
+  NSString* text = l10n_util::GetNSStringWithFixup(
+      IDS_IOS_NEW_INCOGNITO_TAB_IPH_PROMOTION_TEXT);
+
+  CGPoint toolsButtonAnchor =
+      [self anchorPointToGuide:kToolsMenuGuide direction:arrowDirection];
+
+  // If the feature engagement tracker does not consider it valid to display
+  // the incognito tab tip, then end early to prevent the potential reassignment
+  // of the existing |incognitoTabTipBubblePresenter| to nil.
+  BubbleViewControllerPresenter* presenter = [self
+      presentBubbleForFeature:feature_engagement::kIPHNewIncognitoTabTipFeature
+                    direction:arrowDirection
+                    alignment:BubbleAlignmentTrailing
+                         text:text
+                  anchorPoint:toolsButtonAnchor];
+  if (presenter)
+    self.incognitoTabTipBubblePresenter = presenter;
+
+  [self.dispatcher triggerToolsMenuButtonAnimation];
+}
+
+#pragma mark - Private Utils
+
+// Returns the anchor point for a bubble with an |arrowDirection| pointing to a
+// |guideName|. The point is in the window coordinates.
+- (CGPoint)anchorPointToGuide:(GuideName*)guideName
+                    direction:(BubbleArrowDirection)arrowDirection {
+  UILayoutGuide* guide =
+      [NamedGuide guideWithName:guideName view:self.rootViewController.view];
+  DCHECK(guide);
+  CGPoint anchorPoint =
+      bubble_util::AnchorPoint(guide.layoutFrame, arrowDirection);
+  return [guide.owningView convertPoint:anchorPoint
+                                 toView:guide.owningView.window];
+}
+
+// Returns whether the tab can present a bubble tip.
+- (BOOL)canPresentBubble {
+  DCHECK(self.browserState);
+  // If the BVC is not visible, do not present the bubble.
+  if (![self.delegate rootViewVisibleForBubblePresenter:self])
+    return NO;
+  // Do not present the bubble if there is no current tab.
+  web::WebState* currentWebState =
+      [self.delegate currentWebStateForBubblePresenter:self];
+  if (!currentWebState)
+    return NO;
+
+  // Do not present the bubble if the tab is not scrolled to the top.
+  if (![self.delegate isTabScrolledToTopForBubblePresenter:self])
+    return NO;
+
+  return YES;
+}
+
+// Returns a bubble associated with an in-product help promotion if
+// it is valid to show the promotion and |nil| otherwise. |feature| is the
+// base::Feature object associated with the given promotion. |direction| is the
+// direction the bubble's arrow is pointing. |alignment| is the alignment of the
+// arrow on the button. |text| is the text displayed by the bubble. This method
+// requires that |self.browserState| is not NULL.
+- (BubbleViewControllerPresenter*)
+bubblePresenterForFeature:(const base::Feature&)feature
+                direction:(BubbleArrowDirection)direction
+                alignment:(BubbleAlignment)alignment
+                     text:(NSString*)text {
+  DCHECK(self.browserState);
+  if (!feature_engagement::TrackerFactory::GetForBrowserState(self.browserState)
+           ->ShouldTriggerHelpUI(feature)) {
+    return nil;
+  }
+  // Capture |weakSelf| instead of the feature engagement tracker object
+  // because |weakSelf| will safely become |nil| if it is deallocated, whereas
+  // the feature engagement tracker will remain pointing to invalid memory if
+  // its owner (the ChromeBrowserState) is deallocated.
+  __weak BubblePresenter* weakSelf = self;
+  void (^dismissalCallback)(void) = ^{
+    BubblePresenter* strongSelf = weakSelf;
+    if (strongSelf) {
+      feature_engagement::TrackerFactory::GetForBrowserState(
+          strongSelf.browserState)
+          ->Dismissed(feature);
+    }
+  };
+
+  BubbleViewControllerPresenter* bubbleViewControllerPresenter =
+      [[BubbleViewControllerPresenter alloc] initWithText:text
+                                           arrowDirection:direction
+                                                alignment:alignment
+                                        dismissalCallback:dismissalCallback];
+
+  return bubbleViewControllerPresenter;
+}
+
+@end
diff --git a/ios/chrome/browser/ui/bubble/bubble_presenter_delegate.h b/ios/chrome/browser/ui/bubble/bubble_presenter_delegate.h
new file mode 100644
index 0000000..7ced841
--- /dev/null
+++ b/ios/chrome/browser/ui/bubble/bubble_presenter_delegate.h
@@ -0,0 +1,27 @@
+// 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 IOS_CHROME_BROWSER_UI_BUBBLE_BUBBLE_PRESENTER_DELEGATE_H_
+#define IOS_CHROME_BROWSER_UI_BUBBLE_BUBBLE_PRESENTER_DELEGATE_H_
+
+namespace web {
+class WebState;
+}
+
+@class BubblePresenter;
+
+// Delegate for the BubblePresenter.
+@protocol BubblePresenterDelegate
+
+// Returns the currently used WebState.
+- (web::WebState*)currentWebStateForBubblePresenter:
+    (BubblePresenter*)bubblePresenter;
+// Whether the root view is visible.
+- (BOOL)rootViewVisibleForBubblePresenter:(BubblePresenter*)bubblePresenter;
+// Scroll offset for the current tab.
+- (BOOL)isTabScrolledToTopForBubblePresenter:(BubblePresenter*)bubblePresenter;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_BUBBLE_BUBBLE_PRESENTER_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/bubble/bubble_view_anchor_point_provider.h b/ios/chrome/browser/ui/bubble/bubble_view_anchor_point_provider.h
deleted file mode 100644
index ef75bb51..0000000
--- a/ios/chrome/browser/ui/bubble/bubble_view_anchor_point_provider.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_CHROME_BROWSER_UI_BUBBLE_BUBBLE_VIEW_ANCHOR_POINT_PROVIDER_H_
-#define IOS_CHROME_BROWSER_UI_BUBBLE_BUBBLE_VIEW_ANCHOR_POINT_PROVIDER_H_
-
-#import "ios/chrome/browser/ui/bubble/bubble_view.h"
-
-// An interface for accessing the anchor points of toolbar elements.
-// Points must be in window-coordinates.
-@protocol BubbleViewAnchorPointProvider
-
-// Returns either the top-middle or bottom-middle of the tab switcher button
-// based on |direction|. Point is in window-coordinates.
-- (CGPoint)anchorPointForTabSwitcherButton:(BubbleArrowDirection)direction;
-
-@end
-
-#endif  // IOS_CHROME_BROWSER_UI_BUBBLE_BUBBLE_VIEW_ANCHOR_POINT_PROVIDER_H_
diff --git a/ios/chrome/browser/ui/history/history_entry_item.mm b/ios/chrome/browser/ui/history/history_entry_item.mm
index eba2bea..2dfa8775 100644
--- a/ios/chrome/browser/ui/history/history_entry_item.mm
+++ b/ios/chrome/browser/ui/history/history_entry_item.mm
@@ -41,7 +41,7 @@
   cell.URLLabel.text = self.detailText;
   cell.metadataLabel.text = self.timeText;
   cell.metadataLabel.hidden = ([self.timeText length] == 0);
-  cell.faviconView.backgroundColor = styler.tableViewBackgroundColor;
+  cell.faviconContainerView.backgroundColor = styler.tableViewBackgroundColor;
   cell.titleLabel.backgroundColor = styler.tableViewBackgroundColor;
   cell.URLLabel.backgroundColor = styler.tableViewBackgroundColor;
   cell.metadataLabel.backgroundColor = styler.tableViewBackgroundColor;
diff --git a/ios/chrome/browser/ui/ntp/recent_tabs/views/BUILD.gn b/ios/chrome/browser/ui/ntp/recent_tabs/views/BUILD.gn
index b93c20b..cc359142 100644
--- a/ios/chrome/browser/ui/ntp/recent_tabs/views/BUILD.gn
+++ b/ios/chrome/browser/ui/ntp/recent_tabs/views/BUILD.gn
@@ -39,6 +39,7 @@
     "//ios/chrome/browser/ui",
     "//ios/chrome/browser/ui/commands",
     "//ios/chrome/browser/ui/fancy_ui",
+    "//ios/chrome/browser/ui/favicon:favicon_ui",
     "//ios/chrome/browser/ui/material_components",
     "//ios/chrome/browser/ui/settings/sync_utils",
     "//ios/chrome/browser/ui/tab_switcher:utils",
diff --git a/ios/chrome/browser/ui/ntp/recent_tabs/views/session_tab_data_view.mm b/ios/chrome/browser/ui/ntp/recent_tabs/views/session_tab_data_view.mm
index 352b597..3c3f8ceb 100644
--- a/ios/chrome/browser/ui/ntp/recent_tabs/views/session_tab_data_view.mm
+++ b/ios/chrome/browser/ui/ntp/recent_tabs/views/session_tab_data_view.mm
@@ -9,6 +9,8 @@
 #include "components/grit/components_scaled_resources.h"
 #import "ios/chrome/browser/favicon/favicon_loader.h"
 #include "ios/chrome/browser/favicon/ios_chrome_favicon_loader_factory.h"
+#import "ios/chrome/browser/ui/favicon/favicon_attributes.h"
+#import "ios/chrome/browser/ui/favicon/favicon_view.h"
 #include "ios/chrome/browser/ui/ntp/recent_tabs/synced_sessions.h"
 #import "ios/chrome/browser/ui/ntp/recent_tabs/views/views_utils.h"
 #include "ios/chrome/browser/ui/rtl_geometry.h"
@@ -29,7 +31,7 @@
 }  // namespace
 
 @interface SessionTabDataView () {
-  UIImageView* _favicon;
+  FaviconViewNew* _favicon;
   UILabel* _label;
 }
 @end
@@ -39,7 +41,7 @@
 - (instancetype)initWithFrame:(CGRect)aRect {
   self = [super initWithFrame:aRect];
   if (self) {
-    _favicon = [[UIImageView alloc] initWithImage:nil];
+    _favicon = [[FaviconViewNew alloc] init];
     [_favicon setTranslatesAutoresizingMaskIntoConstraints:NO];
 
     _label = [[UILabel alloc] initWithFrame:CGRectZero];
@@ -104,8 +106,8 @@
   DCHECK(browserState);
   [_label setText:text];
   self.accessibilityLabel = [_label accessibilityLabel];
-  TabSwitcherGetFavicon(url, browserState, ^(UIImage* newIcon) {
-    [_favicon setImage:newIcon];
+  TabSwitcherGetFavicon(url, browserState, ^(FaviconAttributes* attributes) {
+    [_favicon configureWithAttributes:attributes];
   });
 }
 
@@ -132,8 +134,7 @@
     }
     case sessions::TabRestoreService::WINDOW: {
       // We only handle the TAB type.
-      [_label setText:@"Window type - NOTIMPLEMENTED"];
-      [_favicon setImage:[UIImage imageNamed:@"tools_bookmark"]];
+      NOTREACHED() << "TabRestoreService WINDOW session type is invalid.";
       break;
     }
   }
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h
index 7c4afa8..6a7ddfc7 100644
--- a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h
+++ b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h
@@ -9,7 +9,7 @@
 
 #import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h"
 
-@class BubbleViewControllerPresenter;
+@class BubblePresenter;
 @class CommandDispatcher;
 @protocol PopupMenuUIUpdating;
 class WebStateList;
@@ -24,8 +24,7 @@
 // UI updater.
 @property(nonatomic, weak) id<PopupMenuUIUpdating> UIUpdater;
 // Bubble view presenter for the incognito tip.
-@property(nonatomic, weak)
-    BubbleViewControllerPresenter* incognitoTabTipPresenter;
+@property(nonatomic, weak) BubblePresenter* bubblePresenter;
 
 // Returns whether this coordinator is showing a popup menu.
 - (BOOL)isShowingPopupMenu;
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
index cecd924..3b4634fa 100644
--- a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
+++ b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
@@ -12,6 +12,7 @@
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/feature_engagement/tracker_factory.h"
 #include "ios/chrome/browser/reading_list/reading_list_model_factory.h"
+#import "ios/chrome/browser/ui/bubble/bubble_presenter.h"
 #import "ios/chrome/browser/ui/bubble/bubble_view_controller_presenter.h"
 #import "ios/chrome/browser/ui/commands/browser_commands.h"
 #import "ios/chrome/browser/ui/commands/command_dispatcher.h"
@@ -55,7 +56,7 @@
 @synthesize requestStartTime = _requestStartTime;
 @synthesize UIUpdater = _UIUpdater;
 @synthesize webStateList = _webStateList;
-@synthesize incognitoTabTipPresenter = _incognitoTabTipPresenter;
+@synthesize bubblePresenter = _bubblePresenter;
 
 #pragma mark - ChromeCoordinator
 
@@ -179,8 +180,10 @@
   BOOL triggerNewIncognitoTabTip = NO;
   if (type == PopupMenuTypeToolsMenu) {
     triggerNewIncognitoTabTip =
-        self.incognitoTabTipPresenter.triggerFollowUpAction;
-    self.incognitoTabTipPresenter.triggerFollowUpAction = NO;
+        self.bubblePresenter.incognitoTabTipBubblePresenter
+            .triggerFollowUpAction;
+    self.bubblePresenter.incognitoTabTipBubblePresenter.triggerFollowUpAction =
+        NO;
   }
 
   self.mediator = [[PopupMenuMediator alloc]
diff --git a/ios/chrome/browser/ui/recent_tabs/BUILD.gn b/ios/chrome/browser/ui/recent_tabs/BUILD.gn
index 8c9fffc..4edf267 100644
--- a/ios/chrome/browser/ui/recent_tabs/BUILD.gn
+++ b/ios/chrome/browser/ui/recent_tabs/BUILD.gn
@@ -57,6 +57,7 @@
     "//ios/chrome/browser/ui/authentication:authentication_ui",
     "//ios/chrome/browser/ui/commands",
     "//ios/chrome/browser/ui/context_menu",
+    "//ios/chrome/browser/ui/favicon:favicon_ui",
     "//ios/chrome/browser/ui/ntp/recent_tabs",
     "//ios/chrome/browser/ui/settings/sync_utils",
     "//ios/chrome/browser/ui/signin_interaction/public",
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_image_data_source.h b/ios/chrome/browser/ui/recent_tabs/recent_tabs_image_data_source.h
index d3aa0ec..c71eff46e 100644
--- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_image_data_source.h
+++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_image_data_source.h
@@ -8,18 +8,20 @@
 #import <UIKit/UIKit.h>
 
 class GURL;
+@class FaviconAttributes;
 
 // Protocol that the recent tabs UI uses to synchronously and asynchronously
 // get images.
 @protocol RecentTabsImageDataSource
-// Requests the receiver to provide a favicon image for |URL|. A non-nil image
-// is synchronously returned for immediate use. |completion| is called
-// asynchronously with an updated image if appropriate. For example, a default
-// image may be returned synchronously and the actual favicon returned
-// asynchronously. In another example, the image returned synchronously may be
-// the actual favicon, so there is no need to call the completion block.
-- (UIImage*)faviconForURL:(const GURL&)URL
-               completion:(void (^)(UIImage*))completion;
+// Requests the receiver to provide a favicon image for |URL|. A
+// FaviconAttributes instance with non-nil properties is synchronously returned
+// for immediate use. |completion| is called asynchronously with a
+// FaviconAttribues instance if appropriate. For example, a default image may be
+// returned synchronously and the actual favicon returned asynchronously. In
+// another example, the image returned synchronously may be the actual favicon,
+// so there is no need to call the completion block.
+- (FaviconAttributes*)faviconForURL:(const GURL&)URL
+                         completion:(void (^)(FaviconAttributes*))completion;
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_RECENT_TABS_RECENT_TABS_IMAGE_DATA_SOURCE_H_
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_mediator.mm b/ios/chrome/browser/ui/recent_tabs/recent_tabs_mediator.mm
index 5d6f6591..fe43811c 100644
--- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_mediator.mm
+++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_mediator.mm
@@ -23,6 +23,13 @@
 #error "This file requires ARC support."
 #endif
 
+namespace {
+// Desired width and height of favicon.
+const CGFloat kFaviconWidthHeight = 24;
+// Minimum favicon size to retrieve.
+const CGFloat kFaviconMinWidthHeight = 16;
+}  // namespace
+
 @interface RecentTabsMediator () {
   std::unique_ptr<synced_sessions::SyncedSessionsObserverBridge>
       _syncedSessionsObserver;
@@ -107,19 +114,18 @@
 
 #pragma mark - RecentTabsImageDataSource
 
-- (UIImage*)faviconForURL:(const GURL&)URL
-               completion:(void (^)(UIImage*))completion {
+- (FaviconAttributes*)faviconForURL:(const GURL&)URL
+                         completion:(void (^)(FaviconAttributes*))completion {
   FaviconLoader* faviconLoader =
       IOSChromeFaviconLoaderFactory::GetForBrowserState(self.browserState);
-  favicon_base::IconTypeSet faviconTypes = {
-      favicon_base::IconType::kFavicon, favicon_base::IconType::kTouchIcon,
-      favicon_base::IconType::kTouchPrecomposedIcon};
-  UIImage* cachedFavicon =
-      faviconLoader->ImageForURL(URL, faviconTypes, ^(UIImage* favicon) {
-        DCHECK(favicon);
-        completion(favicon);
+  FaviconAttributes* cachedAttributes = faviconLoader->FaviconForUrl(
+      URL, kFaviconMinWidthHeight, kFaviconWidthHeight,
+      ^(FaviconAttributes* attributes) {
+        completion(attributes);
       });
-  return cachedFavicon;
+  DCHECK(cachedAttributes);
+
+  return cachedAttributes;
 }
 
 #pragma mark - Private
diff --git a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
index af98659..cb2aca3b 100644
--- a/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
+++ b/ios/chrome/browser/ui/recent_tabs/recent_tabs_table_view_controller.mm
@@ -26,6 +26,8 @@
 #include "ios/chrome/browser/ui/commands/application_commands.h"
 #import "ios/chrome/browser/ui/commands/show_signin_command.h"
 #import "ios/chrome/browser/ui/context_menu/context_menu_coordinator.h"
+#import "ios/chrome/browser/ui/favicon/favicon_attributes.h"
+#import "ios/chrome/browser/ui/favicon/favicon_view.h"
 #import "ios/chrome/browser/ui/ntp/recent_tabs/legacy_recent_tabs_table_view_controller_delegate.h"
 #import "ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_constants.h"
 #import "ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_handset_view_controller.h"
@@ -665,17 +667,17 @@
   TableViewURLCell* URLCell = base::mac::ObjCCastStrict<TableViewURLCell>(cell);
 
   NSString* itemIdentifier = URLItem.uniqueIdentifier;
-  UIImage* cachedFavicon = [self.imageDataSource
+  FaviconAttributes* cachedAttributes = [self.imageDataSource
       faviconForURL:URLItem.URL
-         completion:^(UIImage* favicon) {
+         completion:^(FaviconAttributes* attributes) {
            // Only set favicon if the cell hasn't been reused.
            if ([URLCell.cellUniqueIdentifier isEqualToString:itemIdentifier]) {
-             DCHECK(favicon);
-             URLCell.faviconView.image = favicon;
+             DCHECK(attributes);
+             [URLCell.faviconView configureWithAttributes:attributes];
            }
          }];
-  DCHECK(cachedFavicon);
-  URLCell.faviconView.image = cachedFavicon;
+  DCHECK(cachedAttributes);
+  [URLCell.faviconView configureWithAttributes:cachedAttributes];
 }
 
 #pragma mark - Distant Sessions helpers
diff --git a/ios/chrome/browser/ui/tab_switcher/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/BUILD.gn
index 72a2cbae..33981595 100644
--- a/ios/chrome/browser/ui/tab_switcher/BUILD.gn
+++ b/ios/chrome/browser/ui/tab_switcher/BUILD.gn
@@ -82,6 +82,7 @@
     "//ios/chrome/browser/ui/authentication:authentication_ui",
     "//ios/chrome/browser/ui/colors",
     "//ios/chrome/browser/ui/commands",
+    "//ios/chrome/browser/ui/favicon:favicon_ui",
     "//ios/chrome/browser/ui/image_util",
     "//ios/chrome/browser/ui/keyboard",
     "//ios/chrome/browser/ui/material_components",
@@ -140,6 +141,7 @@
     "//ios/chrome/browser/favicon",
     "//ios/chrome/browser/sync",
     "//ios/chrome/browser/ui",
+    "//ios/chrome/browser/ui/favicon:favicon_ui",
     "//ui/base",
   ]
 }
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.mm b/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.mm
index 42bb468b..ffdfa1f 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_cell.mm
@@ -7,6 +7,7 @@
 #include "components/favicon/ios/web_favicon_driver.h"
 #import "ios/chrome/browser/tabs/tab.h"
 #import "ios/chrome/browser/ui/fade_truncated_label.h"
+#import "ios/chrome/browser/ui/favicon/favicon_attributes.h"
 #import "ios/chrome/browser/ui/image_util/image_util.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_button.h"
 #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_cache.h"
@@ -422,30 +423,33 @@
 
 - (void)setSessionGURL:(GURL const&)gurl
       withBrowserState:(ios::ChromeBrowserState*)browserState {
-  TabSwitcherFaviconGetterCompletionBlock block = ^(UIImage* favicon) {
-    UIColor* imageDominantColor =
-        DominantColorForImage(gfx::Image(favicon), 1.0);
-    MDCPalette* dominantPalette =
-        [MDCPalette paletteGeneratedFromColor:imageDominantColor];
-    UIColor* backgroundColor = dominantPalette.tint300;
-    UIColor* textColor =
-        [MDFTextAccessibility textColorOnBackgroundColor:backgroundColor
-                                         targetTextAlpha:kTitleLabelTextAlpha
-                                                    font:[_titleLabel font]];
-    UIColor* iconColor =
-        [MDFTextAccessibility textColorOnBackgroundColor:backgroundColor
-                                         targetTextAlpha:kNewTabIconAlpha
-                                                    font:[_titleLabel font]];
-    [_raisedButton setBackgroundColor:backgroundColor];
-    [_titleLabel setTextColor:textColor];
-    [_newTabIcon setTintColor:iconColor];
-    [_newTabIcon setAlpha:1.0];
-    [_favicon setImage:favicon];
-    [UIView animateWithDuration:0.2
-                     animations:^{
-                       [_raisedButton setAlpha:1.0];
-                     }];
-  };
+  TabSwitcherFaviconGetterCompletionBlock block =
+      ^(FaviconAttributes* attributes) {
+        if (attributes.faviconImage) {
+          UIColor* imageDominantColor =
+              DominantColorForImage(gfx::Image(attributes.faviconImage), 1.0);
+          MDCPalette* dominantPalette =
+              [MDCPalette paletteGeneratedFromColor:imageDominantColor];
+          UIColor* backgroundColor = dominantPalette.tint300;
+          UIColor* textColor = [MDFTextAccessibility
+              textColorOnBackgroundColor:backgroundColor
+                         targetTextAlpha:kTitleLabelTextAlpha
+                                    font:[_titleLabel font]];
+          UIColor* iconColor = [MDFTextAccessibility
+              textColorOnBackgroundColor:backgroundColor
+                         targetTextAlpha:kNewTabIconAlpha
+                                    font:[_titleLabel font]];
+          [_raisedButton setBackgroundColor:backgroundColor];
+          [_titleLabel setTextColor:textColor];
+          [_newTabIcon setTintColor:iconColor];
+          [_newTabIcon setAlpha:1.0];
+          [_favicon setImage:attributes.faviconImage];
+          [UIView animateWithDuration:0.2
+                           animations:^{
+                             [_raisedButton setAlpha:1.0];
+                           }];
+        }
+      };
   GURL gurlCopy = gurl;
   _faviconObtainer = [NSBlockOperation blockOperationWithBlock:^{
     TabSwitcherGetFavicon(gurlCopy, browserState, block);
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_utils.h b/ios/chrome/browser/ui/tab_switcher/tab_switcher_utils.h
index a183686f..88489917 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_utils.h
+++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_utils.h
@@ -8,13 +8,14 @@
 #include <vector>
 
 class GURL;
+@class FaviconAttributes;
 @class UIImage;
 
 namespace ios {
 class ChromeBrowserState;
 }  // namespace ios
 
-typedef void (^TabSwitcherFaviconGetterCompletionBlock)(UIImage*);
+typedef void (^TabSwitcherFaviconGetterCompletionBlock)(FaviconAttributes*);
 
 // Favicon for |url|, calls |block| when loaded.
 void TabSwitcherGetFavicon(GURL const& url,
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_utils.mm b/ios/chrome/browser/ui/tab_switcher/tab_switcher_utils.mm
index caf9e05..4be1b61 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_utils.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_utils.mm
@@ -14,6 +14,7 @@
 #import "ios/chrome/browser/favicon/favicon_loader.h"
 #include "ios/chrome/browser/favicon/ios_chrome_favicon_loader_factory.h"
 #include "ios/chrome/browser/sync/profile_sync_service_factory.h"
+#import "ios/chrome/browser/ui/favicon/favicon_attributes.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
 #include "ios/chrome/grit/ios_theme_resources.h"
 
@@ -59,6 +60,11 @@
   return SUBSTITUTION;
 }
 
+// Desired width and height of favicon.
+const CGFloat kfaviconWidthHeight = 24;
+// Minimum favicon pixel size to retrieve.
+const CGFloat kfaviconMinWidthHeight = 16;
+
 }  // namespace
 
 void TabSwitcherGetFavicon(GURL const& url,
@@ -81,13 +87,13 @@
       dispatch_async(dispatch_get_main_queue(), ^{
         // |UIImage initWithData:| may return nil.
         if (image) {
-          block(image);
+          block([FaviconAttributes attributesWithImage:image]);
         } else {
-          block(DefaultFaviconImage());
+          block([FaviconAttributes attributesWithImage:DefaultFaviconImage()]);
         }
       });
     });
-    block(DefaultFaviconImage());
+    block([FaviconAttributes attributesWithImage:DefaultFaviconImage()]);
     return;
   }
 
@@ -95,17 +101,14 @@
   FaviconLoader* loader =
       IOSChromeFaviconLoaderFactory::GetForBrowserState(browser_state);
   if (loader) {
-    UIImage* image = loader->ImageForURL(
-        url,
-        {favicon_base::IconType::kFavicon, favicon_base::IconType::kTouchIcon,
-         favicon_base::IconType::kTouchPrecomposedIcon},
-        block);
-    DCHECK(image);
-    block(image);
+    FaviconAttributes* attr = loader->FaviconForUrl(url, kfaviconMinWidthHeight,
+                                                    kfaviconWidthHeight, block);
+    DCHECK(attr);
+    block(attr);
     return;
   }
   // Finally returns a default image.
-  block(DefaultFaviconImage());
+  block([FaviconAttributes attributesWithImage:DefaultFaviconImage()]);
 }
 
 void TabSwitcherMinimalReplacementOperations(std::vector<size_t> const& initial,
diff --git a/ios/chrome/browser/ui/table_view/cells/BUILD.gn b/ios/chrome/browser/ui/table_view/cells/BUILD.gn
index 3927a15..7c94a7d 100644
--- a/ios/chrome/browser/ui/table_view/cells/BUILD.gn
+++ b/ios/chrome/browser/ui/table_view/cells/BUILD.gn
@@ -35,6 +35,7 @@
     "//ios/chrome/browser/ui:ui_util",
     "//ios/chrome/browser/ui/authentication:authentication_ui",
     "//ios/chrome/browser/ui/colors:colors",
+    "//ios/chrome/browser/ui/favicon:favicon_ui",
     "//ios/chrome/browser/ui/list_model",
     "//ios/chrome/browser/ui/table_view:styler",
     "//ios/chrome/browser/ui/util:constraints_ui",
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_url_item.h b/ios/chrome/browser/ui/table_view/cells/table_view_url_item.h
index e09d7132..f7c073a2 100644
--- a/ios/chrome/browser/ui/table_view/cells/table_view_url_item.h
+++ b/ios/chrome/browser/ui/table_view/cells/table_view_url_item.h
@@ -10,6 +10,7 @@
 #import "ios/chrome/browser/ui/table_view/cells/table_view_item.h"
 
 class GURL;
+@class FaviconViewNew;
 
 // TableViewURLItem contains the model data for a TableViewURLCell.
 @interface TableViewURLItem : TableViewItem
@@ -30,7 +31,7 @@
 
 // The imageview that is displayed on the leading edge of the cell.  This
 // contains a favicon composited on top of an off-white background.
-@property(nonatomic, readonly, strong) UIImageView* faviconView;
+@property(nonatomic, readonly, strong) FaviconViewNew* faviconView;
 
 // Container View for the faviconView.
 @property(nonatomic, readonly, strong) UIImageView* faviconContainerView;
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_url_item.mm b/ios/chrome/browser/ui/table_view/cells/table_view_url_item.mm
index dfc320ce..5f6174b9 100644
--- a/ios/chrome/browser/ui/table_view/cells/table_view_url_item.mm
+++ b/ios/chrome/browser/ui/table_view/cells/table_view_url_item.mm
@@ -6,6 +6,7 @@
 
 #include "base/mac/foundation_util.h"
 #include "base/strings/sys_string_conversions.h"
+#import "ios/chrome/browser/ui/favicon/favicon_view.h"
 #import "ios/chrome/browser/ui/table_view/cells/table_view_cells_constants.h"
 #import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h"
 #import "ios/chrome/browser/ui/util/constraints_ui_util.h"
@@ -53,7 +54,6 @@
   cell.metadataLabel.hidden = ([self.metadata length] == 0);
 
   cell.cellUniqueIdentifier = self.uniqueIdentifier;
-  cell.faviconView.backgroundColor = styler.tableViewBackgroundColor;
   cell.faviconContainerView.backgroundColor = styler.tableViewBackgroundColor;
   cell.titleLabel.backgroundColor = styler.tableViewBackgroundColor;
   cell.URLLabel.backgroundColor = styler.tableViewBackgroundColor;
@@ -81,7 +81,7 @@
     _faviconContainerView = [[UIImageView alloc]
         initWithImage:[UIImage
                           imageNamed:@"table_view_cell_favicon_background"]];
-    _faviconView = [[UIImageView alloc] init];
+    _faviconView = [[FaviconViewNew alloc] init];
     _faviconView.contentMode = UIViewContentModeScaleAspectFit;
     _faviconView.clipsToBounds = YES;
     [_faviconContainerView addSubview:_faviconView];
@@ -165,7 +165,7 @@
 
 - (void)prepareForReuse {
   [super prepareForReuse];
-  self.faviconView.image = nil;
+  [self.faviconView configureWithAttributes:nil];
 }
 
 @end
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_url_item_unittest.mm b/ios/chrome/browser/ui/table_view/cells/table_view_url_item_unittest.mm
index 50d11240..2cf5d992 100644
--- a/ios/chrome/browser/ui/table_view/cells/table_view_url_item_unittest.mm
+++ b/ios/chrome/browser/ui/table_view/cells/table_view_url_item_unittest.mm
@@ -86,7 +86,7 @@
   UIColor* testColor = [UIColor redColor];
   styler.tableViewBackgroundColor = testColor;
   [item configureCell:cell withStyler:styler];
-  EXPECT_NSEQ(testColor, cell.faviconView.backgroundColor);
+  EXPECT_NSEQ(testColor, cell.faviconContainerView.backgroundColor);
   EXPECT_NSEQ(testColor, cell.titleLabel.backgroundColor);
   EXPECT_NSEQ(testColor, cell.URLLabel.backgroundColor);
   EXPECT_NSEQ(testColor, cell.metadataLabel.backgroundColor);
diff --git a/ios/chrome/browser/ui/tabs/tab_strip_controller.h b/ios/chrome/browser/ui/tabs/tab_strip_controller.h
index 2a1d664b..27481d3 100644
--- a/ios/chrome/browser/ui/tabs/tab_strip_controller.h
+++ b/ios/chrome/browser/ui/tabs/tab_strip_controller.h
@@ -7,7 +7,6 @@
 
 #import <UIKit/UIKit.h>
 
-#import "ios/chrome/browser/ui/bubble/bubble_view_anchor_point_provider.h"
 #import "ios/chrome/browser/ui/tabs/requirements/tab_strip_constants.h"
 
 @protocol ApplicationCommands;
@@ -19,7 +18,7 @@
 // display in sync with the TabModel.  This controller is only instantiated on
 // tablet.  The tab strip view itself is a subclass of UIScrollView, which
 // manages scroll offsets and scroll animations.
-@interface TabStripController : NSObject<BubbleViewAnchorPointProvider>
+@interface TabStripController : NSObject
 
 @property(nonatomic, assign) BOOL highlightsSelectedTab;
 @property(nonatomic, readonly, retain) UIView* view;
@@ -43,6 +42,9 @@
 
 - (instancetype)init NS_UNAVAILABLE;
 
+// Hides or shows the tab strip.
+- (void)hideTabStrip:(BOOL)hidden;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_TABS_TAB_STRIP_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/tabs/tab_strip_controller.mm b/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
index c8119f6..7a0ed249 100644
--- a/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
+++ b/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
@@ -27,7 +27,6 @@
 #import "ios/chrome/browser/tabs/tab_model_observer.h"
 #import "ios/chrome/browser/ui/bubble/bubble_util.h"
 #import "ios/chrome/browser/ui/bubble/bubble_view.h"
-#import "ios/chrome/browser/ui/bubble/bubble_view_anchor_point_provider.h"
 #import "ios/chrome/browser/ui/commands/application_commands.h"
 #import "ios/chrome/browser/ui/commands/browser_commands.h"
 #import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
@@ -517,6 +516,17 @@
   [_tabModel removeObserver:self];
 }
 
+- (void)hideTabStrip:(BOOL)hidden {
+  self.view.hidden = hidden;
+  if (!hidden) {
+    NamedGuide* tabSwitcherGuide =
+        [NamedGuide guideWithName:kTabStripTabSwitcherGuide view:self.view];
+    tabSwitcherGuide.constrainedView = _tabSwitcherButton;
+  }
+}
+
+#pragma mark - Private
+
 - (void)initializeTabArrayFromTabModel {
   DCHECK(_tabModel);
   WebStateList* webStateList = _tabModel.webStateList;
@@ -738,17 +748,6 @@
 }
 
 #pragma mark -
-#pragma mark BubbleViewAnchorPointProvider methods
-
-- (CGPoint)anchorPointForTabSwitcherButton:(BubbleArrowDirection)direction {
-  CGPoint anchorPoint =
-      bubble_util::AnchorPoint(_tabSwitcherButton.imageView.frame, direction);
-  return [_tabSwitcherButton.imageView.superview
-      convertPoint:anchorPoint
-            toView:_tabSwitcherButton.imageView.window];
-}
-
-#pragma mark -
 #pragma mark Tab Drag and Drop methods
 
 - (void)beginDrag:(UILongPressGestureRecognizer*)gesture {
@@ -1179,9 +1178,6 @@
 - (void)handleTabSwitcherLongPress:(UILongPressGestureRecognizer*)gesture {
   if (gesture.state != UIGestureRecognizerStateBegan)
     return;
-  NamedGuide* tabSwitcherGuide =
-      [NamedGuide guideWithName:kTabStripTabSwitcherGuide view:self.view];
-  tabSwitcherGuide.constrainedView = _tabSwitcherButton;
   [self.dispatcher showTabStripTabGridButtonPopup];
 }
 
diff --git a/ios/chrome/browser/ui/tabs/tab_strip_legacy_coordinator.h b/ios/chrome/browser/ui/tabs/tab_strip_legacy_coordinator.h
index 6861f6b0..1c3b9c0 100644
--- a/ios/chrome/browser/ui/tabs/tab_strip_legacy_coordinator.h
+++ b/ios/chrome/browser/ui/tabs/tab_strip_legacy_coordinator.h
@@ -7,7 +7,6 @@
 
 #import <UIKit/UIKit.h>
 
-#import "ios/chrome/browser/ui/bubble/bubble_view_anchor_point_provider.h"
 #import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h"
 #import "ios/chrome/browser/ui/tabs/requirements/tab_strip_highlighting.h"
 
@@ -23,8 +22,7 @@
 
 // A legacy coordinator that presents the public interface for the tablet tab
 // strip feature.
-@interface TabStripLegacyCoordinator
-    : ChromeCoordinator<BubbleViewAnchorPointProvider, TabStripHighlighting>
+@interface TabStripLegacyCoordinator : ChromeCoordinator<TabStripHighlighting>
 
 // BrowserState for this coordinator.
 @property(nonatomic, assign) ios::ChromeBrowserState* browserState;
@@ -47,6 +45,9 @@
 // controller transition animations.
 - (UIView<TabStripFoldAnimation>*)placeholderView;
 
+// Hides or shows the TabStrip.
+- (void)hideTabStrip:(BOOL)hidden;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_TABS_TAB_STRIP_LEGACY_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/tabs/tab_strip_legacy_coordinator.mm b/ios/chrome/browser/ui/tabs/tab_strip_legacy_coordinator.mm
index ddb77a6..0ff1b6f 100644
--- a/ios/chrome/browser/ui/tabs/tab_strip_legacy_coordinator.mm
+++ b/ios/chrome/browser/ui/tabs/tab_strip_legacy_coordinator.mm
@@ -62,6 +62,10 @@
   return [self.tabStripController placeholderView];
 }
 
+- (void)hideTabStrip:(BOOL)hidden {
+  [self.tabStripController hideTabStrip:hidden];
+}
+
 #pragma mark - ChromeCoordinator
 
 - (void)start {
@@ -89,10 +93,4 @@
   self.presentationProvider = nil;
 }
 
-#pragma mark - BubbleViewAnchorPointProvider methods
-
-- (CGPoint)anchorPointForTabSwitcherButton:(BubbleArrowDirection)direction {
-  return [self.tabStripController anchorPointForTabSwitcherButton:direction];
-}
-
 @end
diff --git a/ios/chrome/browser/ui/toolbar/buttons/toolbar_constants.mm b/ios/chrome/browser/ui/toolbar/buttons/toolbar_constants.mm
index 371bb4c..a2d9c64f 100644
--- a/ios/chrome/browser/ui/toolbar/buttons/toolbar_constants.mm
+++ b/ios/chrome/browser/ui/toolbar/buttons/toolbar_constants.mm
@@ -70,7 +70,7 @@
 const CGFloat kToolbarHeight = 56;
 const CGFloat kTopToolbarUnsplitMargin = 2;
 const CGFloat kAdaptiveToolbarHeight = 48;
-const CGFloat kToolbarHeightFullscreen = 20;
+const CGFloat kToolbarHeightFullscreen = 30;
 
 NSString* const kToolbarToolsMenuButtonIdentifier =
     @"kToolbarToolsMenuButtonIdentifier";
diff --git a/media/DEPS b/media/DEPS
index 7a61488a..bf3b007 100644
--- a/media/DEPS
+++ b/media/DEPS
@@ -28,10 +28,5 @@
 specific_include_rules = {
   "audio_manager_unittest.cc": [
     "+chromeos/dbus"
-  ],
-  # TODO(https://crbug.com/844508): Remove this dependency once the
-  # AudioOutputDevice shared memory refactor is done.
-  "audio_output_device_unittest.cc": [
-    "+mojo/public/cpp/system/platform_handle.h"
   ]
 }
diff --git a/media/audio/BUILD.gn b/media/audio/BUILD.gn
index 8754161..b3a0085 100644
--- a/media/audio/BUILD.gn
+++ b/media/audio/BUILD.gn
@@ -406,12 +406,6 @@
     "//base",
     "//base/test:test_support",
     "//media:test_support",
-
-    # TODO(https://crbug.com/844508): Mojo is used in the
-    # audio_output_device_unittest.cc for conversion between shared memory
-    # types. Remove this dependency once the AudioOutputDevice shared memory
-    # refactor is done.
-    "//mojo/public/cpp/system:system",
     "//testing/gmock",
     "//testing/gtest",
     "//url",
diff --git a/media/audio/audio_device_thread.cc b/media/audio/audio_device_thread.cc
index 719ebea..4f7f7061 100644
--- a/media/audio/audio_device_thread.cc
+++ b/media/audio/audio_device_thread.cc
@@ -14,19 +14,13 @@
 // AudioDeviceThread::Callback implementation
 
 AudioDeviceThread::Callback::Callback(const AudioParameters& audio_parameters,
-                                      base::SharedMemoryHandle memory,
-                                      bool read_only_memory,
                                       uint32_t segment_length,
                                       uint32_t total_segments)
     : audio_parameters_(audio_parameters),
       memory_length_(
           base::CheckMul(segment_length, total_segments).ValueOrDie()),
       total_segments_(total_segments),
-      segment_length_(segment_length),
-      // CHECK that the shared memory is large enough. The memory allocated
-      // must be at least as large as expected.
-      shared_memory_((CHECK(memory_length_ <= memory.GetSize()), memory),
-                     read_only_memory) {
+      segment_length_(segment_length) {
   CHECK_GT(total_segments_, 0u);
   thread_checker_.DetachFromThread();
 }
@@ -39,9 +33,7 @@
   // another thread before we get here.
   DCHECK(thread_checker_.CalledOnValidThread())
       << "Thread checker was attached on the wrong thread";
-  DCHECK(!shared_memory_.memory());
   MapSharedMemory();
-  CHECK(shared_memory_.memory());
 }
 
 // AudioDeviceThread implementation
diff --git a/media/audio/audio_device_thread.h b/media/audio/audio_device_thread.h
index f5aa297..188647c 100644
--- a/media/audio/audio_device_thread.h
+++ b/media/audio/audio_device_thread.h
@@ -30,16 +30,14 @@
   class Callback {
    public:
     Callback(const AudioParameters& audio_parameters,
-             base::SharedMemoryHandle memory,
-             bool read_only_memory,
              uint32_t segment_length,
              uint32_t total_segments);
 
     // One time initialization for the callback object on the audio thread.
     void InitializeOnAudioThread();
 
-    // Derived implementations must call shared_memory_.Map appropriately
-    // before Process can be called.
+    // Derived implementations must map shared memory appropriately before
+    // Process can be called.
     virtual void MapSharedMemory() = 0;
 
     // Called whenever we receive notifications about pending input data.
@@ -57,8 +55,6 @@
     const uint32_t total_segments_;
     const uint32_t segment_length_;
 
-    base::SharedMemory shared_memory_;
-
     // Detached in constructor and attached in InitializeOnAudioThread() which
     // is called on the audio device thread. Sub-classes can then use it for
     // various thread checking purposes.
diff --git a/media/audio/audio_input_device.cc b/media/audio/audio_input_device.cc
index facb4655..cc799ed8 100644
--- a/media/audio/audio_input_device.cc
+++ b/media/audio/audio_input_device.cc
@@ -54,7 +54,7 @@
     : public AudioDeviceThread::Callback {
  public:
   AudioThreadCallback(const AudioParameters& audio_parameters,
-                      base::SharedMemoryHandle memory,
+                      base::ReadOnlySharedMemoryRegion shared_memory_region,
                       uint32_t total_segments,
                       CaptureCallback* capture_callback,
                       base::RepeatingClosure got_data_callback);
@@ -66,6 +66,8 @@
   void Process(uint32_t pending_data) override;
 
  private:
+  base::ReadOnlySharedMemoryRegion shared_memory_region_;
+  base::ReadOnlySharedMemoryMapping shared_memory_mapping_;
   const base::TimeTicks start_time_;
   bool no_callbacks_received_;
   size_t current_segment_id_;
@@ -190,18 +192,19 @@
     ipc_->SetOutputDeviceForAec(output_device_id);
 }
 
-void AudioInputDevice::OnStreamCreated(base::SharedMemoryHandle handle,
-                                       base::SyncSocket::Handle socket_handle,
-                                       bool initially_muted) {
+void AudioInputDevice::OnStreamCreated(
+    base::ReadOnlySharedMemoryRegion shared_memory_region,
+    base::SyncSocket::Handle socket_handle,
+    bool initially_muted) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   TRACE_EVENT0("audio", "AudioInputDevice::OnStreamCreated");
-  DCHECK(base::SharedMemory::IsHandleValid(handle));
+  DCHECK(shared_memory_region.IsValid());
 #if defined(OS_WIN)
   DCHECK(socket_handle);
 #else
   DCHECK_GE(socket_handle, 0);
 #endif
-  DCHECK_GT(handle.GetSize(), 0u);
+  DCHECK_GT(shared_memory_region.GetSize(), 0u);
 
   if (state_ != CREATING_STREAM)
     return;
@@ -239,7 +242,8 @@
 
   // Unretained is safe since |alive_checker_| outlives |audio_callback_|.
   audio_callback_ = std::make_unique<AudioInputDevice::AudioThreadCallback>(
-      audio_parameters_, handle, kRequestedSharedMemoryCount, callback_,
+      audio_parameters_, std::move(shared_memory_region),
+      kRequestedSharedMemoryCount, callback_,
       base::BindRepeating(&AliveChecker::NotifyAlive,
                           base::Unretained(alive_checker_.get())));
   audio_thread_ = std::make_unique<AudioDeviceThread>(
@@ -318,16 +322,15 @@
 // AudioInputDevice::AudioThreadCallback
 AudioInputDevice::AudioThreadCallback::AudioThreadCallback(
     const AudioParameters& audio_parameters,
-    base::SharedMemoryHandle memory,
+    base::ReadOnlySharedMemoryRegion shared_memory_region,
     uint32_t total_segments,
     CaptureCallback* capture_callback,
     base::RepeatingClosure got_data_callback_)
     : AudioDeviceThread::Callback(
           audio_parameters,
-          memory,
-          /*read only*/ true,
           ComputeAudioInputBufferSize(audio_parameters, 1u),
           total_segments),
+      shared_memory_region_(std::move(shared_memory_region)),
       start_time_(base::TimeTicks::Now()),
       no_callbacks_received_(true),
       current_segment_id_(0u),
@@ -336,7 +339,11 @@
       got_data_callback_interval_in_frames_(kGotDataCallbackIntervalSeconds *
                                             audio_parameters.sample_rate()),
       frames_since_last_got_data_callback_(0),
-      got_data_callback_(std::move(got_data_callback_)) {}
+      got_data_callback_(std::move(got_data_callback_)) {
+  // CHECK that the shared memory is large enough. The memory allocated must
+  // be at least as large as expected.
+  CHECK_LE(memory_length_, shared_memory_region_.GetSize());
+}
 
 AudioInputDevice::AudioThreadCallback::~AudioThreadCallback() {
   UMA_HISTOGRAM_LONG_TIMES("Media.Audio.Capture.InputStreamDuration",
@@ -344,10 +351,11 @@
 }
 
 void AudioInputDevice::AudioThreadCallback::MapSharedMemory() {
-  shared_memory_.Map(memory_length_);
+  shared_memory_mapping_ = shared_memory_region_.MapAt(0, memory_length_);
 
   // Create vector of audio buses by wrapping existing blocks of memory.
-  const uint8_t* ptr = static_cast<const uint8_t*>(shared_memory_.memory());
+  const uint8_t* ptr =
+      static_cast<const uint8_t*>(shared_memory_mapping_.memory());
   for (uint32_t i = 0; i < total_segments_; ++i) {
     const media::AudioInputBuffer* buffer =
         reinterpret_cast<const media::AudioInputBuffer*>(ptr);
@@ -375,7 +383,8 @@
   // The shared memory represents parameters, size of the data buffer and the
   // actual data buffer containing audio data. Map the memory into this
   // structure and parse out parameters and the data area.
-  const uint8_t* ptr = static_cast<const uint8_t*>(shared_memory_.memory());
+  const uint8_t* ptr =
+      static_cast<const uint8_t*>(shared_memory_mapping_.memory());
   ptr += current_segment_id_ * segment_length_;
   const AudioInputBuffer* buffer =
       reinterpret_cast<const AudioInputBuffer*>(ptr);
diff --git a/media/audio/audio_input_device.h b/media/audio/audio_input_device.h
index bc6bfb4..07ffe2e3 100644
--- a/media/audio/audio_input_device.h
+++ b/media/audio/audio_input_device.h
@@ -50,7 +50,7 @@
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
-#include "base/memory/shared_memory.h"
+#include "base/memory/read_only_shared_memory_region.h"
 #include "base/optional.h"
 #include "base/sequence_checker.h"
 #include "base/time/time.h"
@@ -95,7 +95,7 @@
   ~AudioInputDevice() override;
 
   // AudioInputIPCDelegate implementation.
-  void OnStreamCreated(base::SharedMemoryHandle handle,
+  void OnStreamCreated(base::ReadOnlySharedMemoryRegion shared_memory_region,
                        base::SyncSocket::Handle socket_handle,
                        bool initially_muted) override;
   void OnError() override;
diff --git a/media/audio/audio_input_device_unittest.cc b/media/audio/audio_input_device_unittest.cc
index ad5c30e..54fd2e27 100644
--- a/media/audio/audio_input_device_unittest.cc
+++ b/media/audio/audio_input_device_unittest.cc
@@ -16,11 +16,11 @@
 #include "testing/gtest/include/gtest/gtest.h"
 
 using base::CancelableSyncSocket;
-using base::SharedMemory;
 using base::SyncSocket;
 using testing::_;
 using testing::DoAll;
 using testing::Invoke;
+using testing::InvokeWithoutArgs;
 
 namespace media {
 
@@ -91,32 +91,28 @@
   device->Stop();
 }
 
-ACTION_P3(ReportOnStreamCreated, device, handle, socket) {
-  static_cast<AudioInputIPCDelegate*>(device)->OnStreamCreated(handle, socket,
-                                                               false);
-}
-
 TEST(AudioInputDeviceTest, CreateStream) {
   AudioParameters params(AudioParameters::AUDIO_PCM_LOW_LATENCY,
                          CHANNEL_LAYOUT_STEREO, 48000, 480);
-  SharedMemory shared_memory;
+  base::MappedReadOnlyRegion shared_memory;
   CancelableSyncSocket browser_socket;
   CancelableSyncSocket renderer_socket;
 
   const uint32_t memory_size =
       media::ComputeAudioInputBufferSize(params, kMemorySegmentCount);
 
-  ASSERT_TRUE(shared_memory.CreateAndMapAnonymous(memory_size));
-  memset(shared_memory.memory(), 0xff, memory_size);
+  shared_memory = base::ReadOnlySharedMemoryRegion::Create(memory_size);
+  ASSERT_TRUE(shared_memory.IsValid());
+  memset(shared_memory.mapping.memory(), 0xff, memory_size);
 
   ASSERT_TRUE(
       CancelableSyncSocket::CreatePair(&browser_socket, &renderer_socket));
   SyncSocket::TransitDescriptor audio_device_socket_descriptor;
   ASSERT_TRUE(renderer_socket.PrepareTransitDescriptor(
       base::GetCurrentProcessHandle(), &audio_device_socket_descriptor));
-  base::SharedMemoryHandle duplicated_memory_handle =
-      shared_memory.handle().Duplicate();
-  ASSERT_TRUE(duplicated_memory_handle.IsValid());
+  base::ReadOnlySharedMemoryRegion duplicated_shared_memory_region =
+      shared_memory.region.Duplicate();
+  ASSERT_TRUE(duplicated_shared_memory_region.IsValid());
 
   base::test::ScopedTaskEnvironment ste;
   MockCaptureCallback callback;
@@ -126,16 +122,19 @@
   device->Initialize(params, &callback);
 
   EXPECT_CALL(*input_ipc, CreateStream(_, _, _, _))
-      .WillOnce(ReportOnStreamCreated(
-          device.get(), duplicated_memory_handle,
-          SyncSocket::UnwrapHandle(audio_device_socket_descriptor)));
+      .WillOnce(InvokeWithoutArgs([&]() {
+        static_cast<AudioInputIPCDelegate*>(device.get())
+            ->OnStreamCreated(
+                std::move(duplicated_shared_memory_region),
+                SyncSocket::UnwrapHandle(audio_device_socket_descriptor),
+                false);
+      }));
   EXPECT_CALL(*input_ipc, RecordStream());
 
   EXPECT_CALL(callback, OnCaptureStarted());
   device->Start();
   EXPECT_CALL(*input_ipc, CloseStream());
   device->Stop();
-  duplicated_memory_handle.Close();
 }
 
 }  // namespace media.
diff --git a/media/audio/audio_input_ipc.h b/media/audio/audio_input_ipc.h
index 231b7e0..66b9895 100644
--- a/media/audio/audio_input_ipc.h
+++ b/media/audio/audio_input_ipc.h
@@ -7,7 +7,7 @@
 
 #include <stdint.h>
 
-#include "base/memory/shared_memory.h"
+#include "base/memory/read_only_shared_memory_region.h"
 #include "base/sync_socket.h"
 #include "media/base/audio_parameters.h"
 #include "media/base/media_export.h"
@@ -22,9 +22,10 @@
   // Called when an AudioInputController has been created.
   // See media/mojo/interfaces/audio_data_pipe.mojom for documentation of
   // |handle| and |socket_handle|.
-  virtual void OnStreamCreated(base::SharedMemoryHandle handle,
-                               base::SyncSocket::Handle socket_handle,
-                               bool initially_muted) = 0;
+  virtual void OnStreamCreated(
+      base::ReadOnlySharedMemoryRegion shared_memory_region,
+      base::SyncSocket::Handle socket_handle,
+      bool initially_muted) = 0;
 
   // Called when state of an audio stream has changed.
   virtual void OnError() = 0;
diff --git a/media/audio/audio_output_device.cc b/media/audio/audio_output_device.cc
index 575a345..6f9c7b5 100644
--- a/media/audio/audio_output_device.cc
+++ b/media/audio/audio_output_device.cc
@@ -31,7 +31,7 @@
     : public AudioDeviceThread::Callback {
  public:
   AudioThreadCallback(const AudioParameters& audio_parameters,
-                      base::SharedMemoryHandle memory,
+                      base::UnsafeSharedMemoryRegion shared_memory_region,
                       AudioRendererSink::RenderCallback* render_callback);
   ~AudioThreadCallback() override;
 
@@ -51,6 +51,8 @@
   void InitializePlayStartTime();
 
  private:
+  base::UnsafeSharedMemoryRegion shared_memory_region_;
+  base::WritableSharedMemoryMapping shared_memory_mapping_;
   const base::TimeTicks start_time_;
   // If set, this is used to record the startup duration UMA stat.
   base::Optional<base::TimeTicks> first_play_start_time_;
@@ -357,19 +359,20 @@
   }
 }
 
-void AudioOutputDevice::OnStreamCreated(base::SharedMemoryHandle handle,
-                                        base::SyncSocket::Handle socket_handle,
-                                        bool playing_automatically) {
+void AudioOutputDevice::OnStreamCreated(
+    base::UnsafeSharedMemoryRegion shared_memory_region,
+    base::SyncSocket::Handle socket_handle,
+    bool playing_automatically) {
   TRACE_EVENT0("audio", "AudioOutputDevice::OnStreamCreated")
 
   DCHECK(io_task_runner_->BelongsToCurrentThread());
-  DCHECK(base::SharedMemory::IsHandleValid(handle));
+  DCHECK(shared_memory_region.IsValid());
 #if defined(OS_WIN)
   DCHECK(socket_handle);
 #else
   DCHECK_GE(socket_handle, 0);
 #endif
-  DCHECK_GT(handle.GetSize(), 0u);
+  DCHECK_GT(shared_memory_region.GetSize(), 0u);
 
   if (state_ != STREAM_CREATION_REQUESTED)
     return;
@@ -395,7 +398,7 @@
     DCHECK(!audio_callback_);
 
     audio_callback_.reset(new AudioOutputDevice::AudioThreadCallback(
-        audio_parameters_, handle, callback_));
+        audio_parameters_, std::move(shared_memory_region), callback_));
     if (playing_automatically)
       audio_callback_->InitializePlayStartTime();
     audio_thread_.reset(new AudioDeviceThread(
@@ -429,18 +432,21 @@
 
 AudioOutputDevice::AudioThreadCallback::AudioThreadCallback(
     const AudioParameters& audio_parameters,
-    base::SharedMemoryHandle memory,
+    base::UnsafeSharedMemoryRegion shared_memory_region,
     AudioRendererSink::RenderCallback* render_callback)
     : AudioDeviceThread::Callback(
           audio_parameters,
-          memory,
-          /*read only*/ false,
           ComputeAudioOutputBufferSize(audio_parameters),
           /*segment count*/ 1),
+      shared_memory_region_(std::move(shared_memory_region)),
       start_time_(base::TimeTicks::Now()),
       first_play_start_time_(base::nullopt),
       render_callback_(render_callback),
-      callback_num_(0) {}
+      callback_num_(0) {
+  // CHECK that the shared memory is large enough. The memory allocated must be
+  // at least as large as expected.
+  CHECK(memory_length_ <= shared_memory_region_.GetSize());
+}
 
 AudioOutputDevice::AudioThreadCallback::~AudioThreadCallback() {
   UMA_HISTOGRAM_LONG_TIMES("Media.Audio.Render.OutputStreamDuration",
@@ -449,10 +455,11 @@
 
 void AudioOutputDevice::AudioThreadCallback::MapSharedMemory() {
   CHECK_EQ(total_segments_, 1u);
-  CHECK(shared_memory_.Map(memory_length_));
+  shared_memory_mapping_ = shared_memory_region_.MapAt(0, memory_length_);
+  CHECK(shared_memory_mapping_.IsValid());
 
   AudioOutputBuffer* buffer =
-      reinterpret_cast<AudioOutputBuffer*>(shared_memory_.memory());
+      reinterpret_cast<AudioOutputBuffer*>(shared_memory_mapping_.memory());
   output_bus_ = AudioBus::WrapMemory(audio_parameters_, buffer->audio);
   output_bus_->set_is_bitstream_format(audio_parameters_.IsBitstreamFormat());
 }
@@ -463,7 +470,7 @@
 
   // Read and reset the number of frames skipped.
   AudioOutputBuffer* buffer =
-      reinterpret_cast<AudioOutputBuffer*>(shared_memory_.memory());
+      reinterpret_cast<AudioOutputBuffer*>(shared_memory_mapping_.memory());
   uint32_t frames_skipped = buffer->params.frames_skipped;
   buffer->params.frames_skipped = 0;
 
diff --git a/media/audio/audio_output_device.h b/media/audio/audio_output_device.h
index 43f95ae..dcb489c6 100644
--- a/media/audio/audio_output_device.h
+++ b/media/audio/audio_output_device.h
@@ -67,7 +67,7 @@
 
 #include "base/bind.h"
 #include "base/macros.h"
-#include "base/memory/shared_memory.h"
+#include "base/memory/unsafe_shared_memory_region.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/time/time.h"
 #include "media/audio/audio_device_thread.h"
@@ -116,7 +116,7 @@
   void OnDeviceAuthorized(OutputDeviceStatus device_status,
                           const media::AudioParameters& output_params,
                           const std::string& matched_device_id) override;
-  void OnStreamCreated(base::SharedMemoryHandle handle,
+  void OnStreamCreated(base::UnsafeSharedMemoryRegion shared_memory_region,
                        base::SyncSocket::Handle socket_handle,
                        bool play_automatically) override;
   void OnIPCClosed() override;
diff --git a/media/audio/audio_output_device_unittest.cc b/media/audio/audio_output_device_unittest.cc
index 1c8dc65..e9d5de3 100644
--- a/media/audio/audio_output_device_unittest.cc
+++ b/media/audio/audio_output_device_unittest.cc
@@ -13,7 +13,8 @@
 #include "base/callback.h"
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
-#include "base/memory/shared_memory.h"
+#include "base/memory/shared_memory_mapping.h"
+#include "base/memory/unsafe_shared_memory_region.h"
 #include "base/single_thread_task_runner.h"
 #include "base/sync_socket.h"
 #include "base/task_runner.h"
@@ -21,12 +22,12 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
 #include "media/audio/audio_sync_reader.h"
-#include "mojo/public/cpp/system/platform_handle.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 using base::CancelableSyncSocket;
-using base::SharedMemory;
+using base::UnsafeSharedMemoryRegion;
+using base::WritableSharedMemoryMapping;
 using base::SyncSocket;
 using testing::_;
 using testing::DoAll;
@@ -85,25 +86,6 @@
   MOCK_METHOD1(SetVolume, void(double volume));
 };
 
-// Converts a new-style shared memory region to a old-style shared memory
-// handle using a mojo::ScopedSharedBufferHandle that supports both types.
-// TODO(https://crbug.com/844508): get rid of this when AudioOutputDevice shared
-// memory refactor is done.
-base::SharedMemoryHandle ToSharedMemoryHandle(
-    base::UnsafeSharedMemoryRegion region) {
-  mojo::ScopedSharedBufferHandle buffer_handle =
-      mojo::WrapUnsafeSharedMemoryRegion(std::move(region));
-  base::SharedMemoryHandle memory_handle;
-  mojo::UnwrappedSharedMemoryHandleProtection protection;
-  size_t memory_length = 0;
-  auto result = mojo::UnwrapSharedMemoryHandle(
-      std::move(buffer_handle), &memory_handle, &memory_length, &protection);
-  DCHECK_EQ(result, MOJO_RESULT_OK);
-  DCHECK_EQ(protection,
-            mojo::UnwrappedSharedMemoryHandleProtection::kReadWrite);
-  return memory_handle;
-}
-
 }  // namespace.
 
 class AudioOutputDeviceTest : public testing::Test {
@@ -131,7 +113,8 @@
  private:
   int CalculateMemorySize();
 
-  SharedMemory shared_memory_;
+  UnsafeSharedMemoryRegion shared_memory_region_;
+  WritableSharedMemoryMapping shared_memory_mapping_;
   CancelableSyncSocket browser_socket_;
   CancelableSyncSocket renderer_socket_;
 
@@ -207,8 +190,11 @@
   const uint32_t kMemorySize =
       ComputeAudioOutputBufferSize(default_audio_parameters_);
 
-  ASSERT_TRUE(shared_memory_.CreateAndMapAnonymous(kMemorySize));
-  memset(shared_memory_.memory(), 0xff, kMemorySize);
+  shared_memory_region_ = base::UnsafeSharedMemoryRegion::Create(kMemorySize);
+  ASSERT_TRUE(shared_memory_region_.IsValid());
+  shared_memory_mapping_ = shared_memory_region_.Map();
+  ASSERT_TRUE(shared_memory_mapping_.IsValid());
+  memset(shared_memory_mapping_.memory(), 0xff, kMemorySize);
 
   ASSERT_TRUE(CancelableSyncSocket::CreatePair(&browser_socket_,
                                                &renderer_socket_));
@@ -219,14 +205,12 @@
   SyncSocket::TransitDescriptor audio_device_socket_descriptor;
   ASSERT_TRUE(renderer_socket_.PrepareTransitDescriptor(
       base::GetCurrentProcessHandle(), &audio_device_socket_descriptor));
-  base::SharedMemoryHandle duplicated_memory_handle =
-      shared_memory_.handle().Duplicate();
-  ASSERT_TRUE(duplicated_memory_handle.IsValid());
+  base::UnsafeSharedMemoryRegion duplicated_memory_region =
+      shared_memory_region_.Duplicate();
+  ASSERT_TRUE(duplicated_memory_region.IsValid());
 
-  // TODO(erikchen): This appears to leak the SharedMemoryHandle.
-  // https://crbug.com/640840.
   audio_device_->OnStreamCreated(
-      duplicated_memory_handle,
+      std::move(duplicated_memory_region),
       SyncSocket::UnwrapHandle(audio_device_socket_descriptor),
       /*playing_automatically*/ false);
   task_env_.FastForwardBy(base::TimeDelta());
@@ -412,9 +396,9 @@
   Mock::VerifyAndClear(ipc);
   audio_device->OnDeviceAuthorized(OUTPUT_DEVICE_STATUS_OK, params,
                                    kDefaultDeviceId);
-  audio_device->OnStreamCreated(
-      ToSharedMemoryHandle(env.reader->TakeSharedMemoryRegion()),
-      env.renderer_socket.Release(), /*playing_automatically*/ false);
+  audio_device->OnStreamCreated(env.reader->TakeSharedMemoryRegion(),
+                                env.renderer_socket.Release(),
+                                /*playing_automatically*/ false);
 
   task_env_.RunUntilIdle();
   // At this point, the callback thread should be running. Send some data over
@@ -473,9 +457,9 @@
   Mock::VerifyAndClear(ipc);
   audio_device->OnDeviceAuthorized(OUTPUT_DEVICE_STATUS_OK, params,
                                    kNonDefaultDeviceId);
-  audio_device->OnStreamCreated(
-      ToSharedMemoryHandle(env.reader->TakeSharedMemoryRegion()),
-      env.renderer_socket.Release(), /*playing_automatically*/ false);
+  audio_device->OnStreamCreated(env.reader->TakeSharedMemoryRegion(),
+                                env.renderer_socket.Release(),
+                                /*playing_automatically*/ false);
 
   audio_device->Stop();
   EXPECT_CALL(*ipc, CloseStream());
@@ -509,9 +493,9 @@
   Mock::VerifyAndClear(ipc);
   audio_device->OnDeviceAuthorized(OUTPUT_DEVICE_STATUS_OK, params,
                                    kNonDefaultDeviceId);
-  audio_device->OnStreamCreated(
-      ToSharedMemoryHandle(env.reader->TakeSharedMemoryRegion()),
-      env.renderer_socket.Release(), /*playing_automatically*/ false);
+  audio_device->OnStreamCreated(env.reader->TakeSharedMemoryRegion(),
+                                env.renderer_socket.Release(),
+                                /*playing_automatically*/ false);
 
   task_env_.RunUntilIdle();
   // At this point, the callback thread should be running. Send some data over
diff --git a/media/audio/audio_output_ipc.h b/media/audio/audio_output_ipc.h
index 897f782..d287ac0c 100644
--- a/media/audio/audio_output_ipc.h
+++ b/media/audio/audio_output_ipc.h
@@ -7,7 +7,7 @@
 
 #include <string>
 
-#include "base/memory/shared_memory.h"
+#include "base/memory/unsafe_shared_memory_region.h"
 #include "base/sync_socket.h"
 #include "media/base/audio_parameters.h"
 #include "media/base/media_export.h"
@@ -35,9 +35,10 @@
   // |handle| and |socket_handle|. |playing_automatically| indicates if the
   // AudioOutputIPCDelegate is playing right away due to an earlier call to
   // Play();
-  virtual void OnStreamCreated(base::SharedMemoryHandle handle,
-                               base::SyncSocket::Handle socket_handle,
-                               bool playing_automatically) = 0;
+  virtual void OnStreamCreated(
+      base::UnsafeSharedMemoryRegion shared_memory_region,
+      base::SyncSocket::Handle socket_handle,
+      bool playing_automatically) = 0;
 
   // Called when the AudioOutputIPC object is going away and/or when the IPC
   // channel has been closed and no more ipc requests can be made.
diff --git a/media/base/audio_bus.cc b/media/base/audio_bus.cc
index c21c6c9..0c61d5f 100644
--- a/media/base/audio_bus.cc
+++ b/media/base/audio_bus.cc
@@ -148,12 +148,22 @@
                                        static_cast<float*>(data)));
 }
 
+std::unique_ptr<const AudioBus> AudioBus::WrapReadOnlyMemory(int channels,
+                                                             int frames,
+                                                             const void* data) {
+  // Note: const_cast is generally dangerous but is used in this case since
+  // AudioBus accomodates both read-only and read/write use cases. A const
+  // AudioBus object is returned to ensure no one accidentally writes to the
+  // read-only data.
+  return WrapMemory(channels, frames, const_cast<void*>(data));
+}
+
 std::unique_ptr<const AudioBus> AudioBus::WrapReadOnlyMemory(
     const AudioParameters& params,
     const void* data) {
   // Note: const_cast is generally dangerous but is used in this case since
   // AudioBus accomodates both read-only and read/write use cases. A const
-  // AudioBus object is returned to ensure noone accidentally writes to the
+  // AudioBus object is returned to ensure no one accidentally writes to the
   // read-only data.
   return WrapMemory(params, const_cast<void*>(data));
 }
diff --git a/media/base/audio_bus.h b/media/base/audio_bus.h
index 5e55b5c..7726302 100644
--- a/media/base/audio_bus.h
+++ b/media/base/audio_bus.h
@@ -56,6 +56,9 @@
                                               void* data);
   static std::unique_ptr<AudioBus> WrapMemory(const AudioParameters& params,
                                               void* data);
+  static std::unique_ptr<const AudioBus> WrapReadOnlyMemory(int channels,
+                                                            int frames,
+                                                            const void* data);
   static std::unique_ptr<const AudioBus> WrapReadOnlyMemory(
       const AudioParameters& params,
       const void* data);
diff --git a/ppapi/nacl_irt/ppapi_dispatcher.cc b/ppapi/nacl_irt/ppapi_dispatcher.cc
index 6045526..b1ec3a9 100644
--- a/ppapi/nacl_irt/ppapi_dispatcher.cc
+++ b/ppapi/nacl_irt/ppapi_dispatcher.cc
@@ -80,6 +80,20 @@
   return base::SharedMemoryHandle();
 }
 
+base::UnsafeSharedMemoryRegion
+PpapiDispatcher::ShareUnsafeSharedMemoryRegionWithRemote(
+    const base::UnsafeSharedMemoryRegion& region,
+    base::ProcessId remote_pid) {
+  return base::UnsafeSharedMemoryRegion();
+}
+
+base::ReadOnlySharedMemoryRegion
+PpapiDispatcher::ShareReadOnlySharedMemoryRegionWithRemote(
+    const base::ReadOnlySharedMemoryRegion& region,
+    base::ProcessId remote_pid) {
+  return base::ReadOnlySharedMemoryRegion();
+}
+
 std::set<PP_Instance>* PpapiDispatcher::GetGloballySeenInstanceIDSet() {
   return &instances_;
 }
diff --git a/ppapi/nacl_irt/ppapi_dispatcher.h b/ppapi/nacl_irt/ppapi_dispatcher.h
index 953db41..03eac07 100644
--- a/ppapi/nacl_irt/ppapi_dispatcher.h
+++ b/ppapi/nacl_irt/ppapi_dispatcher.h
@@ -64,6 +64,12 @@
   base::SharedMemoryHandle ShareSharedMemoryHandleWithRemote(
       const base::SharedMemoryHandle& handle,
       base::ProcessId remote_pid) override;
+  base::UnsafeSharedMemoryRegion ShareUnsafeSharedMemoryRegionWithRemote(
+      const base::UnsafeSharedMemoryRegion& region,
+      base::ProcessId remote_pid) override;
+  base::ReadOnlySharedMemoryRegion ShareReadOnlySharedMemoryRegionWithRemote(
+      const base::ReadOnlySharedMemoryRegion& region,
+      base::ProcessId remote_pid) override;
   std::set<PP_Instance>* GetGloballySeenInstanceIDSet() override;
   uint32_t Register(proxy::PluginDispatcher* plugin_dispatcher) override;
   void Unregister(uint32_t plugin_dispatcher_id) override;
diff --git a/ppapi/proxy/audio_input_resource.cc b/ppapi/proxy/audio_input_resource.cc
index 59b78bfd..60db9b8 100644
--- a/ppapi/proxy/audio_input_resource.cc
+++ b/ppapi/proxy/audio_input_resource.cc
@@ -163,12 +163,13 @@
     CHECK(socket_handle != base::SyncSocket::kInvalidHandle);
 
     SerializedHandle serialized_shared_memory_handle =
-        params.TakeHandleOfTypeAtIndex(1, SerializedHandle::SHARED_MEMORY);
+        params.TakeHandleOfTypeAtIndex(1,
+                                       SerializedHandle::SHARED_MEMORY_REGION);
     CHECK(serialized_shared_memory_handle.IsHandleValid());
 
     open_state_ = OPENED;
-    SetStreamInfo(serialized_shared_memory_handle.shmem(),
-                  serialized_shared_memory_handle.size(),
+    SetStreamInfo(base::ReadOnlySharedMemoryRegion::Deserialize(
+                      serialized_shared_memory_handle.TakeSharedMemoryRegion()),
                   socket_handle);
   } else {
     capturing_ = false;
@@ -180,13 +181,10 @@
 }
 
 void AudioInputResource::SetStreamInfo(
-    base::SharedMemoryHandle shared_memory_handle,
-    size_t shared_memory_size,
+    base::ReadOnlySharedMemoryRegion shared_memory_region,
     base::SyncSocket::Handle socket_handle) {
   socket_.reset(new base::CancelableSyncSocket(socket_handle));
-  shared_memory_.reset(
-      new base::SharedMemory(shared_memory_handle, /*read_only*/ true));
-  DCHECK(!shared_memory_->memory());
+  DCHECK(!shared_memory_mapping_.IsValid());
 
   // Ensure that the allocated memory is enough for the audio bus and buffer
   // parameters. Note that there might be slightly more allocated memory as
@@ -195,16 +193,18 @@
   // Example: DCHECK_GE(8208, 8192 + 16) for |sample_frame_count_| = 2048.
   shared_memory_size_ = media::ComputeAudioInputBufferSize(
       kAudioInputChannels, sample_frame_count_, 1u);
-  DCHECK_GE(shared_memory_size, shared_memory_size_);
+  DCHECK_GE(shared_memory_region.GetSize(), shared_memory_size_);
 
   // If we fail to map the shared memory into the caller's address space we
   // might as well fail here since nothing will work if this is the case.
-  CHECK(shared_memory_->Map(shared_memory_size_));
+  shared_memory_mapping_ = shared_memory_region.MapAt(0, shared_memory_size_);
+  CHECK(shared_memory_mapping_.IsValid());
 
   // Create a new audio bus and wrap the audio data section in shared memory.
-  media::AudioInputBuffer* buffer =
-      static_cast<media::AudioInputBuffer*>(shared_memory_->memory());
-  audio_bus_ = media::AudioBus::WrapMemory(
+  const media::AudioInputBuffer* buffer =
+      static_cast<const media::AudioInputBuffer*>(
+          shared_memory_mapping_.memory());
+  audio_bus_ = media::AudioBus::WrapReadOnlyMemory(
       kAudioInputChannels, sample_frame_count_, buffer->audio);
 
   // Create an extra integer audio buffer for user audio data callbacks.
@@ -227,7 +227,7 @@
 void AudioInputResource::StartThread() {
   // Don't start the thread unless all our state is set up correctly.
   if ((!audio_input_callback_0_3_ && !audio_input_callback_) ||
-      !socket_.get() || !capturing_ || !shared_memory_->memory() ||
+      !socket_.get() || !capturing_ || !shared_memory_mapping_.memory() ||
       !audio_bus_.get() || !client_buffer_.get()) {
     return;
   }
@@ -250,8 +250,9 @@
 void AudioInputResource::Run() {
   // The shared memory represents AudioInputBufferParameters and the actual data
   // buffer stored as an audio bus.
-  media::AudioInputBuffer* buffer =
-      static_cast<media::AudioInputBuffer*>(shared_memory_->memory());
+  const media::AudioInputBuffer* buffer =
+      static_cast<const media::AudioInputBuffer*>(
+          shared_memory_mapping_.memory());
   const uint32_t audio_bus_size_bytes =
       base::checked_cast<uint32_t>(shared_memory_size_ -
                                    sizeof(media::AudioInputBufferParameters));
diff --git a/ppapi/proxy/audio_input_resource.h b/ppapi/proxy/audio_input_resource.h
index 809c0dbe..5c35ac7 100644
--- a/ppapi/proxy/audio_input_resource.h
+++ b/ppapi/proxy/audio_input_resource.h
@@ -12,8 +12,8 @@
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
+#include "base/memory/read_only_shared_memory_region.h"
 #include "base/memory/ref_counted.h"
-#include "base/memory/shared_memory.h"
 #include "base/sync_socket.h"
 #include "base/threading/simple_thread.h"
 #include "ppapi/proxy/device_enumeration_resource_helper.h"
@@ -77,8 +77,7 @@
 
   // Sets the shared memory and socket handles. This will automatically start
   // capture if we're currently set to capture.
-  void SetStreamInfo(base::SharedMemoryHandle shared_memory_handle,
-                     size_t shared_memory_size,
+  void SetStreamInfo(base::ReadOnlySharedMemoryRegion shared_memory_region,
                      base::SyncSocket::Handle socket_handle);
 
   // Starts execution of the audio input thread.
@@ -110,7 +109,7 @@
   // Sample buffer in shared memory. This pointer is created in
   // SetStreamInfo(). The memory is only mapped when the audio thread is
   // created.
-  std::unique_ptr<base::SharedMemory> shared_memory_;
+  base::ReadOnlySharedMemoryMapping shared_memory_mapping_;
 
   // The size of the sample buffer in bytes.
   size_t shared_memory_size_;
@@ -140,7 +139,7 @@
   size_t bytes_per_second_;
 
   // AudioBus for shuttling data across the shared memory.
-  std::unique_ptr<media::AudioBus> audio_bus_;
+  std::unique_ptr<const media::AudioBus> audio_bus_;
   int sample_frame_count_;
 
   // Internal buffer for client's integer audio data.
diff --git a/ppapi/proxy/audio_output_resource.cc b/ppapi/proxy/audio_output_resource.cc
index 16956ce..d8a85cd 100644
--- a/ppapi/proxy/audio_output_resource.cc
+++ b/ppapi/proxy/audio_output_resource.cc
@@ -147,12 +147,14 @@
     CHECK(socket_handle != base::SyncSocket::kInvalidHandle);
 
     SerializedHandle serialized_shared_memory_handle =
-        params.TakeHandleOfTypeAtIndex(1, SerializedHandle::SHARED_MEMORY);
+        params.TakeHandleOfTypeAtIndex(1,
+                                       SerializedHandle::SHARED_MEMORY_REGION);
     CHECK(serialized_shared_memory_handle.IsHandleValid());
 
     open_state_ = OPENED;
-    SetStreamInfo(serialized_shared_memory_handle.shmem(),
-                  serialized_shared_memory_handle.size(), socket_handle);
+    SetStreamInfo(base::UnsafeSharedMemoryRegion::Deserialize(
+                      serialized_shared_memory_handle.TakeSharedMemoryRegion()),
+                  socket_handle);
   } else {
     playing_ = false;
   }
@@ -163,12 +165,9 @@
 }
 
 void AudioOutputResource::SetStreamInfo(
-    base::SharedMemoryHandle shared_memory_handle,
-    size_t shared_memory_size,
+    base::UnsafeSharedMemoryRegion shared_memory_region,
     base::SyncSocket::Handle socket_handle) {
   socket_.reset(new base::CancelableSyncSocket(socket_handle));
-  shared_memory_.reset(new base::SharedMemory(shared_memory_handle, false));
-  DCHECK(!shared_memory_->memory());
 
   // Ensure that the allocated memory is enough for the audio bus and buffer
   // parameters. Note that there might be slightly more allocated memory as
@@ -177,15 +176,16 @@
   // Example: DCHECK_GE(8208, 8192 + 16) for |sample_frame_count_| = 2048.
   shared_memory_size_ = media::ComputeAudioOutputBufferSize(
       kAudioOutputChannels, sample_frame_count_);
-  DCHECK_GE(shared_memory_size, shared_memory_size_);
+  DCHECK_GE(shared_memory_region.GetSize(), shared_memory_size_);
 
   // If we fail to map the shared memory into the caller's address space we
   // might as well fail here since nothing will work if this is the case.
-  CHECK(shared_memory_->Map(shared_memory_size_));
+  shared_memory_mapping_ = shared_memory_region.MapAt(0, shared_memory_size_);
+  CHECK(shared_memory_mapping_.IsValid());
 
   // Create a new audio bus and wrap the audio data section in shared memory.
   media::AudioOutputBuffer* buffer =
-      static_cast<media::AudioOutputBuffer*>(shared_memory_->memory());
+      static_cast<media::AudioOutputBuffer*>(shared_memory_mapping_.memory());
   audio_bus_ = media::AudioBus::WrapMemory(kAudioOutputChannels,
                                            sample_frame_count_, buffer->audio);
 
@@ -197,14 +197,15 @@
 
 void AudioOutputResource::StartThread() {
   // Don't start the thread unless all our state is set up correctly.
-  if (!audio_output_callback_ || !socket_.get() || !shared_memory_->memory() ||
-      !audio_bus_.get() || !client_buffer_.get() || bytes_per_second_ == 0)
+  if (!audio_output_callback_ || !socket_.get() ||
+      !shared_memory_mapping_.memory() || !audio_bus_.get() ||
+      !client_buffer_.get() || bytes_per_second_ == 0)
     return;
 
   // Clear contents of shm buffer before starting audio thread. This will
   // prevent a burst of static if for some reason the audio thread doesn't
   // start up quickly enough.
-  memset(shared_memory_->memory(), 0, shared_memory_size_);
+  memset(shared_memory_mapping_.memory(), 0, shared_memory_size_);
   memset(client_buffer_.get(), 0, client_buffer_size_bytes_);
 
   DCHECK(!audio_output_thread_.get());
@@ -227,7 +228,7 @@
   // The shared memory represents AudioOutputBufferParameters and the actual
   // data buffer stored as an audio bus.
   media::AudioOutputBuffer* buffer =
-      static_cast<media::AudioOutputBuffer*>(shared_memory_->memory());
+      static_cast<media::AudioOutputBuffer*>(shared_memory_mapping_.memory());
 
   // This is a constantly increasing counter that is used to verify on the
   // browser side that buffers are in sync.
diff --git a/ppapi/proxy/audio_output_resource.h b/ppapi/proxy/audio_output_resource.h
index ee654e1..3dc96ff4 100644
--- a/ppapi/proxy/audio_output_resource.h
+++ b/ppapi/proxy/audio_output_resource.h
@@ -13,7 +13,7 @@
 #include "base/compiler_specific.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
-#include "base/memory/shared_memory.h"
+#include "base/memory/unsafe_shared_memory_region.h"
 #include "base/sync_socket.h"
 #include "base/threading/simple_thread.h"
 #include "ppapi/c/ppb_audio_config.h"
@@ -72,8 +72,7 @@
   void OnPluginMsgOpenReply(const ResourceMessageReplyParams& params);
 
   // Sets the shared memory and socket handles.
-  void SetStreamInfo(base::SharedMemoryHandle shared_memory_handle,
-                     size_t shared_memory_size,
+  void SetStreamInfo(base::UnsafeSharedMemoryRegion shared_memory_region,
                      base::SyncSocket::Handle socket_handle);
 
   // Starts execution of the audio output thread.
@@ -104,7 +103,7 @@
   // Sample buffer in shared memory. This pointer is created in
   // SetStreamInfo(). The memory is only mapped when the audio thread is
   // created.
-  std::unique_ptr<base::SharedMemory> shared_memory_;
+  base::WritableSharedMemoryMapping shared_memory_mapping_;
 
   // The size of the sample buffer in bytes.
   size_t shared_memory_size_;
diff --git a/ppapi/proxy/plugin_dispatcher_unittest.cc b/ppapi/proxy/plugin_dispatcher_unittest.cc
index 2e3f058..1d7f203 100644
--- a/ppapi/proxy/plugin_dispatcher_unittest.cc
+++ b/ppapi/proxy/plugin_dispatcher_unittest.cc
@@ -73,10 +73,9 @@
   EXPECT_FALSE(HasTargetProxy(API_ID_PPB_AUDIO));
   PpapiMsg_PPBAudio_NotifyAudioStreamCreated audio_msg(
       API_ID_PPB_AUDIO, HostResource(), 0,
+      ppapi::proxy::SerializedHandle(ppapi::proxy::SerializedHandle::SOCKET),
       ppapi::proxy::SerializedHandle(
-          ppapi::proxy::SerializedHandle::SOCKET),
-      ppapi::proxy::SerializedHandle(
-          ppapi::proxy::SerializedHandle::SHARED_MEMORY));
+          ppapi::proxy::SerializedHandle::SHARED_MEMORY_REGION));
   plugin_dispatcher()->OnMessageReceived(audio_msg);
   EXPECT_TRUE(HasTargetProxy(API_ID_PPB_AUDIO));
 }
diff --git a/ppapi/proxy/ppapi_proxy_test.cc b/ppapi/proxy/ppapi_proxy_test.cc
index 587d0de3..bdb0173c 100644
--- a/ppapi/proxy/ppapi_proxy_test.cc
+++ b/ppapi/proxy/ppapi_proxy_test.cc
@@ -261,6 +261,20 @@
   return base::SharedMemory::DuplicateHandle(handle);
 }
 
+base::UnsafeSharedMemoryRegion PluginProxyTestHarness::PluginDelegateMock::
+    ShareUnsafeSharedMemoryRegionWithRemote(
+        const base::UnsafeSharedMemoryRegion& region,
+        base::ProcessId /* remote_pid */) {
+  return region.Duplicate();
+}
+
+base::ReadOnlySharedMemoryRegion PluginProxyTestHarness::PluginDelegateMock::
+    ShareReadOnlySharedMemoryRegionWithRemote(
+        const base::ReadOnlySharedMemoryRegion& region,
+        base::ProcessId /* remote_pid */) {
+  return region.Duplicate();
+}
+
 std::set<PP_Instance>*
 PluginProxyTestHarness::PluginDelegateMock::GetGloballySeenInstanceIDSet() {
   return &instance_id_set_;
@@ -498,6 +512,20 @@
   return base::SharedMemory::DuplicateHandle(handle);
 }
 
+base::UnsafeSharedMemoryRegion
+HostProxyTestHarness::DelegateMock::ShareUnsafeSharedMemoryRegionWithRemote(
+    const base::UnsafeSharedMemoryRegion& region,
+    base::ProcessId /*remote_pid*/) {
+  return region.Duplicate();
+}
+
+base::ReadOnlySharedMemoryRegion
+HostProxyTestHarness::DelegateMock::ShareReadOnlySharedMemoryRegionWithRemote(
+    const base::ReadOnlySharedMemoryRegion& region,
+    base::ProcessId /*remote_pid*/) {
+  return region.Duplicate();
+}
+
 // HostProxyTest ---------------------------------------------------------------
 
 HostProxyTest::HostProxyTest() : HostProxyTestHarness(SINGLETON_GLOBALS) {
diff --git a/ppapi/proxy/ppapi_proxy_test.h b/ppapi/proxy/ppapi_proxy_test.h
index fdb373c..01ac6a7 100644
--- a/ppapi/proxy/ppapi_proxy_test.h
+++ b/ppapi/proxy/ppapi_proxy_test.h
@@ -2,6 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#ifndef PPAPI_PROXY_PPAPI_PROXY_TEST_H_
+#define PPAPI_PROXY_PPAPI_PROXY_TEST_H_
+
 #include <stdint.h>
 
 #include <map>
@@ -147,6 +150,12 @@
     base::SharedMemoryHandle ShareSharedMemoryHandleWithRemote(
         const base::SharedMemoryHandle& handle,
         base::ProcessId remote_pid) override;
+    base::UnsafeSharedMemoryRegion ShareUnsafeSharedMemoryRegionWithRemote(
+        const base::UnsafeSharedMemoryRegion& region,
+        base::ProcessId remote_pid) override;
+    base::ReadOnlySharedMemoryRegion ShareReadOnlySharedMemoryRegionWithRemote(
+        const base::ReadOnlySharedMemoryRegion& region,
+        base::ProcessId remote_pid) override;
 
     // PluginDispatcher::PluginDelegate implementation.
     std::set<PP_Instance>* GetGloballySeenInstanceIDSet() override;
@@ -290,6 +299,12 @@
     base::SharedMemoryHandle ShareSharedMemoryHandleWithRemote(
         const base::SharedMemoryHandle& handle,
         base::ProcessId remote_pid) override;
+    base::UnsafeSharedMemoryRegion ShareUnsafeSharedMemoryRegionWithRemote(
+        const base::UnsafeSharedMemoryRegion& region,
+        base::ProcessId remote_pid) override;
+    base::ReadOnlySharedMemoryRegion ShareReadOnlySharedMemoryRegionWithRemote(
+        const base::ReadOnlySharedMemoryRegion& region,
+        base::ProcessId remote_pid) override;
 
    private:
     base::SingleThreadTaskRunner* ipc_task_runner_;  // Weak
@@ -383,3 +398,5 @@
 
 }  // namespace proxy
 }  // namespace ppapi
+
+#endif  // PPAPI_PROXY_PPAPI_PROXY_TEST_H_
diff --git a/ppapi/proxy/ppb_audio_proxy.cc b/ppapi/proxy/ppb_audio_proxy.cc
index 0682dc0..26f7bf2 100644
--- a/ppapi/proxy/ppb_audio_proxy.cc
+++ b/ppapi/proxy/ppb_audio_proxy.cc
@@ -52,8 +52,7 @@
   int32_t Open(PP_Resource config_id,
                scoped_refptr<TrackedCallback> create_callback) override;
   int32_t GetSyncSocket(int* sync_socket) override;
-  int32_t GetSharedMemory(base::SharedMemory** shm,
-                          uint32_t* shm_size) override;
+  int32_t GetSharedMemory(base::UnsafeSharedMemoryRegion** shm) override;
 
  private:
   // Owning reference to the current config object. This isn't actually used,
@@ -125,7 +124,7 @@
   return PP_ERROR_NOTSUPPORTED;  // Don't proxy the trusted interface.
 }
 
-int32_t Audio::GetSharedMemory(base::SharedMemory** shm, uint32_t* shm_size) {
+int32_t Audio::GetSharedMemory(base::UnsafeSharedMemoryRegion** shm) {
   return PP_ERROR_NOTSUPPORTED;  // Don't proxy the trusted interface.
 }
 
@@ -249,14 +248,12 @@
     const HostResource& resource) {
   IPC::PlatformFileForTransit socket_handle =
       IPC::InvalidPlatformFileForTransit();
-  base::SharedMemoryHandle shared_memory;
-  uint32_t audio_buffer_length = 0;
+  base::UnsafeSharedMemoryRegion shared_memory_region;
 
   int32_t result_code = result;
   if (result_code == PP_OK) {
     result_code = GetAudioConnectedHandles(resource, &socket_handle,
-                                           &shared_memory,
-                                           &audio_buffer_length);
+                                           &shared_memory_region);
   }
 
   // Send all the values, even on error. This simplifies some of our cleanup
@@ -265,16 +262,18 @@
   // us, as long as the remote side always closes the handles it receives
   // (in OnMsgNotifyAudioStreamCreated), even in the failure case.
   SerializedHandle fd_wrapper(SerializedHandle::SOCKET, socket_handle);
-  SerializedHandle handle_wrapper(shared_memory, audio_buffer_length);
+  SerializedHandle handle_wrapper(
+      base::UnsafeSharedMemoryRegion::TakeHandleForSerialization(
+          std::move(shared_memory_region)));
   dispatcher()->Send(new PpapiMsg_PPBAudio_NotifyAudioStreamCreated(
-      API_ID_PPB_AUDIO, resource, result_code, fd_wrapper, handle_wrapper));
+      API_ID_PPB_AUDIO, resource, result_code, std::move(fd_wrapper),
+      std::move(handle_wrapper)));
 }
 
 int32_t PPB_Audio_Proxy::GetAudioConnectedHandles(
     const HostResource& resource,
     IPC::PlatformFileForTransit* foreign_socket_handle,
-    base::SharedMemoryHandle* foreign_shared_memory_handle,
-    uint32_t* shared_memory_length) {
+    base::UnsafeSharedMemoryRegion* foreign_shared_memory_region) {
   // Get the audio interface which will give us the handles.
   EnterHostFromHostResource<PPB_Audio_API> enter(resource);
   if (enter.failed())
@@ -293,16 +292,16 @@
     return PP_ERROR_FAILED;
 
   // Get the shared memory for the buffer.
-  base::SharedMemory* shared_memory;
-  result =
-      enter.object()->GetSharedMemory(&shared_memory, shared_memory_length);
+  base::UnsafeSharedMemoryRegion* shared_memory_region;
+  result = enter.object()->GetSharedMemory(&shared_memory_region);
   if (result != PP_OK)
     return result;
 
-  // shared_memory_handle doesn't belong to us: don't close it.
-  *foreign_shared_memory_handle =
-      dispatcher()->ShareSharedMemoryHandleWithRemote(shared_memory->handle());
-  if (!base::SharedMemory::IsHandleValid(*foreign_shared_memory_handle))
+  // shared_memory_region doesn't belong to us: don't close it.
+  *foreign_shared_memory_region =
+      dispatcher()->ShareUnsafeSharedMemoryRegionWithRemote(
+          *shared_memory_region);
+  if (!foreign_shared_memory_region->IsValid())
     return PP_ERROR_FAILED;
 
   return PP_OK;
@@ -316,23 +315,26 @@
     SerializedHandle socket_handle,
     SerializedHandle handle) {
   CHECK(socket_handle.is_socket());
-  CHECK(handle.is_shmem());
+  CHECK(handle.is_shmem_region());
   EnterPluginFromHostResource<PPB_Audio_API> enter(audio_id);
   if (enter.failed() || result_code != PP_OK) {
     // The caller may still have given us these handles in the failure case.
-    // The easiest way to clean these up is to just put them in the objects
-    // and then close them. This failure case is not performance critical.
+    // The easiest way to clean socket handle up is to just put them in the
+    // SyncSocket object and then close it. The shared memory region will be
+    // cleaned up automatically. This failure case is not performance critical.
     base::SyncSocket temp_socket(
         IPC::PlatformFileForTransitToPlatformFile(socket_handle.descriptor()));
-    base::SharedMemory temp_mem(handle.shmem(), false);
   } else {
     EnterResourceNoLock<PPB_AudioConfig_API> config(
         static_cast<Audio*>(enter.object())->GetCurrentConfig(), true);
-    static_cast<Audio*>(enter.object())->SetStreamInfo(
-        enter.resource()->pp_instance(), handle.shmem(), handle.size(),
-        IPC::PlatformFileForTransitToPlatformFile(socket_handle.descriptor()),
-        config.object()->GetSampleRate(),
-        config.object()->GetSampleFrameCount());
+    static_cast<Audio*>(enter.object())
+        ->SetStreamInfo(enter.resource()->pp_instance(),
+                        base::UnsafeSharedMemoryRegion::Deserialize(
+                            handle.TakeSharedMemoryRegion()),
+                        IPC::PlatformFileForTransitToPlatformFile(
+                            socket_handle.descriptor()),
+                        config.object()->GetSampleRate(),
+                        config.object()->GetSampleFrameCount());
   }
 }
 
diff --git a/ppapi/proxy/ppb_audio_proxy.h b/ppapi/proxy/ppb_audio_proxy.h
index b4d3091..2082c7e 100644
--- a/ppapi/proxy/ppb_audio_proxy.h
+++ b/ppapi/proxy/ppb_audio_proxy.h
@@ -10,7 +10,7 @@
 #include <utility>
 
 #include "base/macros.h"
-#include "base/memory/shared_memory.h"
+#include "base/memory/unsafe_shared_memory_region.h"
 #include "base/sync_socket.h"
 #include "ipc/ipc_platform_file.h"
 #include "ppapi/c/pp_instance.h"
@@ -76,8 +76,7 @@
   int32_t GetAudioConnectedHandles(
       const ppapi::HostResource& resource,
       IPC::PlatformFileForTransit* foreign_socket_handle,
-      base::SharedMemoryHandle* foreign_shared_memory_handle,
-      uint32_t* shared_memory_length);
+      base::UnsafeSharedMemoryRegion* foreign_shared_memory_region);
 
   ProxyCompletionCallbackFactory<PPB_Audio_Proxy> callback_factory_;
 
diff --git a/ppapi/proxy/proxy_channel.cc b/ppapi/proxy/proxy_channel.cc
index 7a4c0aa0f..6aa566f 100644
--- a/ppapi/proxy/proxy_channel.cc
+++ b/ppapi/proxy/proxy_channel.cc
@@ -77,6 +77,27 @@
   return delegate_->ShareSharedMemoryHandleWithRemote(handle, peer_pid_);
 }
 
+base::UnsafeSharedMemoryRegion
+ProxyChannel::ShareUnsafeSharedMemoryRegionWithRemote(
+    const base::UnsafeSharedMemoryRegion& region) {
+  if (!channel_.get())
+    return base::UnsafeSharedMemoryRegion();
+
+  DCHECK(peer_pid_ != base::kNullProcessId);
+  return delegate_->ShareUnsafeSharedMemoryRegionWithRemote(region, peer_pid_);
+}
+
+base::ReadOnlySharedMemoryRegion
+ProxyChannel::ShareReadOnlySharedMemoryRegionWithRemote(
+    const base::ReadOnlySharedMemoryRegion& region) {
+  if (!channel_.get())
+    return base::ReadOnlySharedMemoryRegion();
+
+  DCHECK(peer_pid_ != base::kNullProcessId);
+  return delegate_->ShareReadOnlySharedMemoryRegionWithRemote(region,
+                                                              peer_pid_);
+}
+
 bool ProxyChannel::Send(IPC::Message* msg) {
   if (test_sink_)
     return test_sink_->Send(msg);
diff --git a/ppapi/proxy/proxy_channel.h b/ppapi/proxy/proxy_channel.h
index 8a6af71e..ca41f58 100644
--- a/ppapi/proxy/proxy_channel.h
+++ b/ppapi/proxy/proxy_channel.h
@@ -9,7 +9,9 @@
 
 #include "base/files/scoped_file.h"
 #include "base/macros.h"
+#include "base/memory/read_only_shared_memory_region.h"
 #include "base/memory/shared_memory.h"
+#include "base/memory/unsafe_shared_memory_region.h"
 #include "base/process/process.h"
 #include "build/build_config.h"
 #include "ipc/ipc_listener.h"
@@ -63,6 +65,14 @@
     virtual base::SharedMemoryHandle ShareSharedMemoryHandleWithRemote(
         const base::SharedMemoryHandle& handle,
         base::ProcessId remote_pid) = 0;
+    virtual base::UnsafeSharedMemoryRegion
+    ShareUnsafeSharedMemoryRegionWithRemote(
+        const base::UnsafeSharedMemoryRegion& region,
+        base::ProcessId remote_pid) = 0;
+    virtual base::ReadOnlySharedMemoryRegion
+    ShareReadOnlySharedMemoryRegionWithRemote(
+        const base::ReadOnlySharedMemoryRegion& region,
+        base::ProcessId remote_pid) = 0;
   };
 
   ~ProxyChannel() override;
@@ -90,6 +100,10 @@
   // is not closed by this operation.
   base::SharedMemoryHandle ShareSharedMemoryHandleWithRemote(
       const base::SharedMemoryHandle& handle);
+  base::UnsafeSharedMemoryRegion ShareUnsafeSharedMemoryRegionWithRemote(
+      const base::UnsafeSharedMemoryRegion& region);
+  base::ReadOnlySharedMemoryRegion ShareReadOnlySharedMemoryRegionWithRemote(
+      const base::ReadOnlySharedMemoryRegion& region);
 
   // IPC::Sender implementation.
   bool Send(IPC::Message* msg) override;
diff --git a/ppapi/shared_impl/ppb_audio_shared.cc b/ppapi/shared_impl/ppb_audio_shared.cc
index 636f2ee..710a251 100644
--- a/ppapi/shared_impl/ppb_audio_shared.cc
+++ b/ppapi/shared_impl/ppb_audio_shared.cc
@@ -96,21 +96,20 @@
 
 void PPB_Audio_Shared::SetStreamInfo(
     PP_Instance instance,
-    base::SharedMemoryHandle shared_memory_handle,
-    size_t shared_memory_size,
+    base::UnsafeSharedMemoryRegion shared_memory_region,
     base::SyncSocket::Handle socket_handle,
     PP_AudioSampleRate sample_rate,
     int sample_frame_count) {
   socket_.reset(new base::CancelableSyncSocket(socket_handle));
-  shared_memory_.reset(new base::SharedMemory(shared_memory_handle, false));
   shared_memory_size_ = media::ComputeAudioOutputBufferSize(
       kAudioOutputChannels, sample_frame_count);
-  DCHECK_GE(shared_memory_size, shared_memory_size_);
+  DCHECK_GE(shared_memory_region.GetSize(), shared_memory_size_);
   bytes_per_second_ =
       kAudioOutputChannels * (kBitsPerAudioOutputSample / 8) * sample_rate;
   buffer_index_ = 0;
 
-  if (!shared_memory_->Map(shared_memory_size_)) {
+  shared_memory_ = shared_memory_region.MapAt(0, shared_memory_size_);
+  if (!shared_memory_.IsValid()) {
     PpapiGlobals::Get()->LogWithSource(
         instance,
         PP_LOGLEVEL_WARNING,
@@ -118,7 +117,7 @@
         "Failed to map shared memory for PPB_Audio_Shared.");
   } else {
     media::AudioOutputBuffer* buffer =
-        reinterpret_cast<media::AudioOutputBuffer*>(shared_memory_->memory());
+        reinterpret_cast<media::AudioOutputBuffer*>(shared_memory_.memory());
     audio_bus_ = media::AudioBus::WrapMemory(kAudioOutputChannels,
                                              sample_frame_count, buffer->audio);
     // Setup integer audio buffer for user audio data.
@@ -133,13 +132,13 @@
 void PPB_Audio_Shared::StartThread() {
   // Don't start the thread unless all our state is set up correctly.
   if (!playing_ || !callback_.IsValid() || !socket_.get() ||
-      !shared_memory_->memory() || !audio_bus_.get() || !client_buffer_.get() ||
+      !shared_memory_.memory() || !audio_bus_.get() || !client_buffer_.get() ||
       bytes_per_second_ == 0)
     return;
   // Clear contents of shm buffer before starting audio thread. This will
   // prevent a burst of static if for some reason the audio thread doesn't
   // start up quickly enough.
-  memset(shared_memory_->memory(), 0, shared_memory_size_);
+  memset(shared_memory_.memory(), 0, shared_memory_size_);
   memset(client_buffer_.get(), 0, client_buffer_size_bytes_);
 
   if (g_nacl_mode) {
@@ -227,7 +226,7 @@
     {
       TRACE_EVENT0("audio", "PPB_Audio_Shared::FireRenderCallback");
       media::AudioOutputBuffer* buffer =
-          reinterpret_cast<media::AudioOutputBuffer*>(shared_memory_->memory());
+          reinterpret_cast<media::AudioOutputBuffer*>(shared_memory_.memory());
       base::TimeDelta delay =
           base::TimeDelta::FromMicroseconds(buffer->params.delay_us);
 
diff --git a/ppapi/shared_impl/ppb_audio_shared.h b/ppapi/shared_impl/ppb_audio_shared.h
index 7f7995b..657336f 100644
--- a/ppapi/shared_impl/ppb_audio_shared.h
+++ b/ppapi/shared_impl/ppb_audio_shared.h
@@ -11,7 +11,7 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "base/memory/shared_memory.h"
+#include "base/memory/unsafe_shared_memory_region.h"
 #include "base/sync_socket.h"
 #include "base/threading/simple_thread.h"
 #include "media/base/audio_bus.h"
@@ -76,8 +76,7 @@
   // Sets the shared memory and socket handles. This will automatically start
   // playback if we're currently set to play.
   void SetStreamInfo(PP_Instance instance,
-                     base::SharedMemoryHandle shared_memory_handle,
-                     size_t shared_memory_size,
+                     base::UnsafeSharedMemoryRegion shared_memory_region,
                      base::SyncSocket::Handle socket_handle,
                      PP_AudioSampleRate sample_rate,
                      int sample_frame_count);
@@ -117,7 +116,7 @@
   // Sample buffer in shared memory. This pointer is created in
   // StreamCreated(). The memory is only mapped when the audio thread is
   // created.
-  std::unique_ptr<base::SharedMemory> shared_memory_;
+  base::WritableSharedMemoryMapping shared_memory_;
 
   // The size of the sample buffer in bytes.
   size_t shared_memory_size_;
diff --git a/ppapi/thunk/ppb_audio_api.h b/ppapi/thunk/ppb_audio_api.h
index e73f0618..58d3d42 100644
--- a/ppapi/thunk/ppb_audio_api.h
+++ b/ppapi/thunk/ppb_audio_api.h
@@ -13,7 +13,7 @@
 #include "ppapi/thunk/ppapi_thunk_export.h"
 
 namespace base {
-class SharedMemory;
+class UnsafeSharedMemoryRegion;
 }  // namespace base
 
 namespace ppapi {
@@ -35,8 +35,7 @@
       PP_Resource config_id,
       scoped_refptr<TrackedCallback> create_callback) = 0;
   virtual int32_t GetSyncSocket(int* sync_socket) = 0;
-  virtual int32_t GetSharedMemory(base::SharedMemory** shm,
-                                  uint32_t* shm_size) = 0;
+  virtual int32_t GetSharedMemory(base::UnsafeSharedMemoryRegion** shm) = 0;
 };
 
 }  // namespace thunk
diff --git a/services/audio/public/cpp/input_ipc.cc b/services/audio/public/cpp/input_ipc.cc
index f6be400..8b84cd2 100644
--- a/services/audio/public/cpp/input_ipc.cc
+++ b/services/audio/public/cpp/input_ipc.cc
@@ -84,14 +84,13 @@
   auto result =
       mojo::UnwrapPlatformFile(std::move(data_pipe->socket), &socket_handle);
   DCHECK_EQ(result, MOJO_RESULT_OK);
-  base::SharedMemoryHandle memory_handle;
-  mojo::UnwrappedSharedMemoryHandleProtection protection;
-  result = mojo::UnwrapSharedMemoryHandle(std::move(data_pipe->shared_memory),
-                                          &memory_handle, nullptr, &protection);
-  DCHECK_EQ(result, MOJO_RESULT_OK);
-  DCHECK_EQ(protection, mojo::UnwrappedSharedMemoryHandleProtection::kReadOnly);
+  base::ReadOnlySharedMemoryRegion shared_memory_region =
+      mojo::UnwrapReadOnlySharedMemoryRegion(
+          std::move(data_pipe->shared_memory));
+  DCHECK(shared_memory_region.IsValid());
 
-  delegate_->OnStreamCreated(memory_handle, socket_handle, initially_muted);
+  delegate_->OnStreamCreated(std::move(shared_memory_region), socket_handle,
+                             initially_muted);
 }
 
 void InputIPC::RecordStream() {
diff --git a/services/audio/public/cpp/input_ipc_unittest.cc b/services/audio/public/cpp/input_ipc_unittest.cc
index 55d3a76f..634bc8c 100644
--- a/services/audio/public/cpp/input_ipc_unittest.cc
+++ b/services/audio/public/cpp/input_ipc_unittest.cc
@@ -62,7 +62,8 @@
     auto h = mojo::SharedBufferHandle::Create(kShMemSize);
     std::move(created_callback)
         .Run({base::in_place,
-              h->Clone(mojo::SharedBufferHandle::AccessMode::READ_ONLY),
+              mojo::WrapReadOnlySharedMemoryRegion(
+                  base::ReadOnlySharedMemoryRegion::Create(kShMemSize).region),
               mojo::WrapPlatformFile(socket1.Release())},
              initially_muted_, base::UnguessableToken::Create());
   }
@@ -111,11 +112,9 @@
   MockDelegate() {}
   ~MockDelegate() override {}
 
-  void OnStreamCreated(base::SharedMemoryHandle mem_handle,
+  void OnStreamCreated(base::ReadOnlySharedMemoryRegion mem_handle,
                        base::SyncSocket::Handle socket_handle,
                        bool initially_muted) override {
-    base::SharedMemory sh_mem(
-        mem_handle, /*read_only*/ true);  // Releases the shared memory handle.
     base::SyncSocket socket(socket_handle);  // Releases the socket descriptor.
     GotOnStreamCreated(initially_muted);
   }
diff --git a/services/data_decoder/data_decoder_service.cc b/services/data_decoder/data_decoder_service.cc
index a8bb2a5..a9d954c 100644
--- a/services/data_decoder/data_decoder_service.cc
+++ b/services/data_decoder/data_decoder_service.cc
@@ -4,6 +4,8 @@
 
 #include "services/data_decoder/data_decoder_service.h"
 
+#include <memory>
+
 #include "base/macros.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
@@ -16,32 +18,7 @@
 
 namespace data_decoder {
 
-namespace {
-
-void OnImageDecoderRequest(
-    service_manager::ServiceContextRefFactory* ref_factory,
-    mojom::ImageDecoderRequest request) {
-  mojo::MakeStrongBinding(
-      std::make_unique<ImageDecoderImpl>(ref_factory->CreateRef()),
-      std::move(request));
-}
-
-void OnJsonParserRequest(service_manager::ServiceContextRefFactory* ref_factory,
-                         mojom::JsonParserRequest request) {
-  mojo::MakeStrongBinding(
-      std::make_unique<JsonParserImpl>(ref_factory->CreateRef()),
-      std::move(request));
-}
-
-void OnXmlParserRequest(service_manager::ServiceContextRefFactory* ref_factory,
-                        mojom::XmlParserRequest request) {
-  mojo::MakeStrongBinding(std::make_unique<XmlParser>(ref_factory->CreateRef()),
-                          std::move(request));
-}
-
-}  // namespace
-
-DataDecoderService::DataDecoderService() : weak_factory_(this) {}
+DataDecoderService::DataDecoderService() = default;
 
 DataDecoderService::~DataDecoderService() = default;
 
@@ -51,13 +28,15 @@
 }
 
 void DataDecoderService::OnStart() {
-  ref_factory_.reset(new service_manager::ServiceContextRefFactory(
-      base::BindRepeating(&DataDecoderService::MaybeRequestQuitDelayed,
-                          weak_factory_.GetWeakPtr())));
-  registry_.AddInterface(
-      base::Bind(&OnImageDecoderRequest, ref_factory_.get()));
-  registry_.AddInterface(base::Bind(&OnJsonParserRequest, ref_factory_.get()));
-  registry_.AddInterface(base::Bind(&OnXmlParserRequest, ref_factory_.get()));
+  constexpr int kMaxServiceIdleTimeInSeconds = 5;
+  keepalive_ = std::make_unique<service_manager::ServiceKeepalive>(
+      context(), base::TimeDelta::FromSeconds(kMaxServiceIdleTimeInSeconds));
+  registry_.AddInterface(base::BindRepeating(
+      &DataDecoderService::BindImageDecoder, base::Unretained(this)));
+  registry_.AddInterface(base::BindRepeating(
+      &DataDecoderService::BindJsonParser, base::Unretained(this)));
+  registry_.AddInterface(base::BindRepeating(&DataDecoderService::BindXmlParser,
+                                             base::Unretained(this)));
 }
 
 void DataDecoderService::OnBindInterface(
@@ -67,18 +46,21 @@
   registry_.BindInterface(interface_name, std::move(interface_pipe));
 }
 
-void DataDecoderService::MaybeRequestQuitDelayed() {
-  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
-      FROM_HERE,
-      base::Bind(&DataDecoderService::MaybeRequestQuit,
-                 weak_factory_.GetWeakPtr()),
-      base::TimeDelta::FromSeconds(5));
+void DataDecoderService::BindImageDecoder(mojom::ImageDecoderRequest request) {
+  mojo::MakeStrongBinding(
+      std::make_unique<ImageDecoderImpl>(keepalive_->CreateRef()),
+      std::move(request));
 }
 
-void DataDecoderService::MaybeRequestQuit() {
-  DCHECK(ref_factory_);
-  if (ref_factory_->HasNoRefs())
-    context()->CreateQuitClosure().Run();
+void DataDecoderService::BindJsonParser(mojom::JsonParserRequest request) {
+  mojo::MakeStrongBinding(
+      std::make_unique<JsonParserImpl>(keepalive_->CreateRef()),
+      std::move(request));
+}
+
+void DataDecoderService::BindXmlParser(mojom::XmlParserRequest request) {
+  mojo::MakeStrongBinding(std::make_unique<XmlParser>(keepalive_->CreateRef()),
+                          std::move(request));
 }
 
 }  // namespace data_decoder
diff --git a/services/data_decoder/data_decoder_service.h b/services/data_decoder/data_decoder_service.h
index 9e419e05..bee6e7a 100644
--- a/services/data_decoder/data_decoder_service.h
+++ b/services/data_decoder/data_decoder_service.h
@@ -7,12 +7,13 @@
 
 #include <memory>
 
-#include "base/callback.h"
 #include "base/macros.h"
-#include "base/memory/weak_ptr.h"
+#include "services/data_decoder/public/mojom/image_decoder.mojom.h"
+#include "services/data_decoder/public/mojom/json_parser.mojom.h"
+#include "services/data_decoder/public/mojom/xml_parser.mojom.h"
 #include "services/service_manager/public/cpp/binder_registry.h"
 #include "services/service_manager/public/cpp/service.h"
-#include "services/service_manager/public/cpp/service_context_ref.h"
+#include "services/service_manager/public/cpp/service_keepalive.h"
 
 namespace data_decoder {
 
@@ -31,12 +32,12 @@
                        mojo::ScopedMessagePipeHandle interface_pipe) override;
 
  private:
-  void MaybeRequestQuitDelayed();
-  void MaybeRequestQuit();
+  void BindImageDecoder(mojom::ImageDecoderRequest request);
+  void BindJsonParser(mojom::JsonParserRequest request);
+  void BindXmlParser(mojom::XmlParserRequest request);
 
-  std::unique_ptr<service_manager::ServiceContextRefFactory> ref_factory_;
   service_manager::BinderRegistry registry_;
-  base::WeakPtrFactory<DataDecoderService> weak_factory_;
+  std::unique_ptr<service_manager::ServiceKeepalive> keepalive_;
 
   DISALLOW_COPY_AND_ASSIGN(DataDecoderService);
 };
diff --git a/services/data_decoder/public/cpp/test_data_decoder_service.cc b/services/data_decoder/public/cpp/test_data_decoder_service.cc
index f5a9569..c62ced3 100644
--- a/services/data_decoder/public/cpp/test_data_decoder_service.cc
+++ b/services/data_decoder/public/cpp/test_data_decoder_service.cc
@@ -18,9 +18,9 @@
 
 CrashyDataDecoderService::CrashyDataDecoderService(bool crash_json,
                                                    bool crash_image)
-    : real_service_(DataDecoderService::Create()),
-      crash_json_(crash_json),
-      crash_image_(crash_image) {}
+    : CrashyDataDecoderService(DataDecoderService::Create(),
+                               crash_json,
+                               crash_image) {}
 
 CrashyDataDecoderService::~CrashyDataDecoderService() = default;
 
@@ -76,4 +76,13 @@
   json_parser_binding_.reset();
 }
 
-}  // namespace data_decoder
\ No newline at end of file
+CrashyDataDecoderService::CrashyDataDecoderService(
+    std::unique_ptr<service_manager::Service> real_service,
+    bool crash_json,
+    bool crash_image)
+    : ForwardingService(real_service.get()),
+      real_service_(std::move(real_service)),
+      crash_json_(crash_json),
+      crash_image_(crash_image) {}
+
+}  // namespace data_decoder
diff --git a/services/data_decoder/public/cpp/test_data_decoder_service.h b/services/data_decoder/public/cpp/test_data_decoder_service.h
index 6a8b9d2..3b8e153 100644
--- a/services/data_decoder/public/cpp/test_data_decoder_service.h
+++ b/services/data_decoder/public/cpp/test_data_decoder_service.h
@@ -43,14 +43,14 @@
 // a call is made on an interface.
 // Can be used with a TestConnectorFactory to simulate crashes in the service
 // while processing a call.
-class CrashyDataDecoderService : public service_manager::Service,
+class CrashyDataDecoderService : public service_manager::ForwardingService,
                                  public mojom::ImageDecoder,
                                  public mojom::JsonParser {
  public:
   CrashyDataDecoderService(bool crash_json, bool crash_image);
   ~CrashyDataDecoderService() override;
 
-  // service_manager::Service:
+  // service_manager::ForwardingService:
   void OnStart() override;
   void OnBindInterface(const service_manager::BindSourceInfo& source_info,
                        const std::string& interface_name,
@@ -72,6 +72,11 @@
   void Parse(const std::string& json, ParseCallback callback) override;
 
  private:
+  CrashyDataDecoderService(
+      std::unique_ptr<service_manager::Service> real_service,
+      bool crash_json,
+      bool crash_image);
+
   std::unique_ptr<mojo::Binding<mojom::ImageDecoder>> image_decoder_binding_;
   std::unique_ptr<mojo::Binding<mojom::JsonParser>> json_parser_binding_;
 
diff --git a/services/identity/public/cpp/identity_manager.cc b/services/identity/public/cpp/identity_manager.cc
index 6c21ab3..5b991ff8 100644
--- a/services/identity/public/cpp/identity_manager.cc
+++ b/services/identity/public/cpp/identity_manager.cc
@@ -21,6 +21,7 @@
       ->set_diagnostics_client(this);
 #endif
   token_service_->AddDiagnosticsObserver(this);
+  token_service_->set_diagnostics_client(this);
 }
 
 IdentityManager::~IdentityManager() {
@@ -30,6 +31,7 @@
       ->set_diagnostics_client(nullptr);
 #endif
   token_service_->RemoveDiagnosticsObserver(this);
+  token_service_->set_diagnostics_client(nullptr);
 }
 
 AccountInfo IdentityManager::GetPrimaryAccountInfo() {
@@ -179,6 +181,27 @@
   }
 }
 
+void IdentityManager::WillFireOnRefreshTokenAvailable(
+    const std::string& account_id,
+    bool is_valid) {
+  AccountInfo account_info =
+      account_tracker_service_->GetAccountInfo(account_id);
+  DCHECK(!account_info.IsEmpty());
+  for (auto& observer : observer_list_) {
+    observer.OnRefreshTokenUpdatedForAccount(account_info, is_valid);
+  }
+}
+
+void IdentityManager::WillFireOnRefreshTokenRevoked(
+    const std::string& account_id) {
+  AccountInfo account_info =
+      account_tracker_service_->GetAccountInfo(account_id);
+  DCHECK(!account_info.IsEmpty());
+  for (auto& observer : observer_list_) {
+    observer.OnRefreshTokenRemovedForAccount(account_info);
+  }
+}
+
 void IdentityManager::OnAccessTokenRequested(
     const std::string& account_id,
     const std::string& consumer_id,
diff --git a/services/identity/public/cpp/identity_manager.h b/services/identity/public/cpp/identity_manager.h
index 43c164b9..60aa33b7 100644
--- a/services/identity/public/cpp/identity_manager.h
+++ b/services/identity/public/cpp/identity_manager.h
@@ -50,6 +50,7 @@
 #if !defined(OS_CHROMEOS)
                         public SigninManager::DiagnosticsClient,
 #endif
+                        public ProfileOAuth2TokenService::DiagnosticsClient,
                         public OAuth2TokenService::DiagnosticsObserver {
  public:
   class Observer {
@@ -71,6 +72,25 @@
 
     // TODO(blundell): Eventually we might need a callback for failure to log in
     // to the primary account.
+
+    // Called when a new refresh token is associated with |account_info|.
+    // |is_valid| indicates whether the new refresh token is valid.
+    // NOTE: On a signin event, the ordering of this callback wrt the
+    // OnPrimaryAccountSet() callback is undefined. If you as a client are
+    // interested in both callbacks, PrimaryAccountAccessTokenFetcher will
+    // likely meet your needs. Otherwise, if this lack of ordering is
+    // problematic for your use case, please contact blundell@chromium.org.
+    virtual void OnRefreshTokenUpdatedForAccount(
+        const AccountInfo& account_info,
+        bool is_valid) {}
+
+    // Called when the refresh token previously associated with |account_info|
+    // has been removed.
+    // NOTE: On a signout event, the ordering of this callback wrt the
+    // OnPrimaryAccountCleared() callback is undefined.If this lack of ordering
+    // is problematic for your use case, please contact blundell@chromium.org.
+    virtual void OnRefreshTokenRemovedForAccount(
+        const AccountInfo& account_info) {}
   };
 
   // Observer interface for classes that want to monitor status of various
@@ -166,6 +186,11 @@
   void GoogleSigninSucceeded(const AccountInfo& account_info) override;
   void GoogleSignedOut(const AccountInfo& account_info) override;
 
+  // ProfileOAuth2TokenService::DiagnosticsClient:
+  void WillFireOnRefreshTokenAvailable(const std::string& account_id,
+                                       bool is_valid) override;
+  void WillFireOnRefreshTokenRevoked(const std::string& account_id) override;
+
 #if !defined(OS_CHROMEOS)
   // SigninManager::DiagnosticsClient:
   // Override these to update |primary_account_info_| before any observers of
diff --git a/services/identity/public/cpp/identity_manager_unittest.cc b/services/identity/public/cpp/identity_manager_unittest.cc
index 950f3504..4db14d5 100644
--- a/services/identity/public/cpp/identity_manager_unittest.cc
+++ b/services/identity/public/cpp/identity_manager_unittest.cc
@@ -24,7 +24,9 @@
 #endif  // OS_CHROMEOS
 
 const char kTestGaiaId[] = "dummyId";
+const char kTestGaiaId2[] = "dummyId2";
 const char kTestEmail[] = "me@gmail.com";
+const char kTestEmail2[] = "me2@gmail.com";
 
 #if defined(OS_CHROMEOS)
 const char kTestEmailWithPeriod[] = "m.e@gmail.com";
@@ -126,6 +128,78 @@
   AccountInfo primary_account_from_signout_callback_;
 };
 
+// Class that observes updates from both ProfileOAuth2TokenService and
+// IdentityManager and verifies thereby that IdentityManager receives updates
+// before direct observers of ProfileOAuth2TokenService.
+class TestTokenServiceObserver : public OAuth2TokenService::Observer,
+                                 public identity::IdentityManager::Observer {
+ public:
+  explicit TestTokenServiceObserver(OAuth2TokenService* token_service)
+      : token_service_(token_service) {
+    token_service_->AddObserver(this);
+  }
+  ~TestTokenServiceObserver() override {
+    token_service_->RemoveObserver(this);
+    identity_manager_->RemoveObserver(this);
+  }
+
+  void set_identity_manager(IdentityManager* identity_manager) {
+    identity_manager_ = identity_manager;
+    identity_manager_->AddObserver(this);
+  }
+
+  void set_on_refresh_token_available_callback(base::OnceClosure callback) {
+    on_refresh_token_available_callback_ = std::move(callback);
+  }
+  void set_on_refresh_token_revoked_callback(base::OnceClosure callback) {
+    on_refresh_token_revoked_callback_ = std::move(callback);
+  }
+
+ private:
+  // IdentityManager::Observer:
+  void OnRefreshTokenUpdatedForAccount(const AccountInfo& account_info,
+                                       bool is_valid) override {
+    EXPECT_TRUE(
+        account_id_from_identity_manager_token_updated_callback_.empty());
+    account_id_from_identity_manager_token_updated_callback_ =
+        account_info.account_id;
+  }
+  void OnRefreshTokenRemovedForAccount(
+      const AccountInfo& account_info) override {
+    EXPECT_TRUE(
+        account_id_from_identity_manager_token_removed_callback_.empty());
+    account_id_from_identity_manager_token_removed_callback_ =
+        account_info.account_id;
+  }
+
+  // OAuth2TokenService::Observer:
+  void OnRefreshTokenAvailable(const std::string& account_id) override {
+    // This object should have received the corresponding IdentityManager
+    // callback before receiving this callback.
+    EXPECT_EQ(account_id_from_identity_manager_token_updated_callback_,
+              account_id);
+    account_id_from_identity_manager_token_updated_callback_.clear();
+    if (on_refresh_token_available_callback_)
+      std::move(on_refresh_token_available_callback_).Run();
+  }
+  void OnRefreshTokenRevoked(const std::string& account_id) override {
+    // This object should have received the corresponding IdentityManager
+    // callback before receiving this callback.
+    EXPECT_EQ(account_id_from_identity_manager_token_removed_callback_,
+              account_id);
+    account_id_from_identity_manager_token_removed_callback_.clear();
+    if (on_refresh_token_revoked_callback_)
+      std::move(on_refresh_token_revoked_callback_).Run();
+  }
+
+  OAuth2TokenService* token_service_;
+  IdentityManager* identity_manager_;
+  std::string account_id_from_identity_manager_token_updated_callback_;
+  std::string account_id_from_identity_manager_token_removed_callback_;
+  base::OnceClosure on_refresh_token_available_callback_;
+  base::OnceClosure on_refresh_token_revoked_callback_;
+};
+
 class TestIdentityManagerObserver : IdentityManager::Observer {
  public:
   explicit TestIdentityManagerObserver(IdentityManager* identity_manager)
@@ -150,6 +224,23 @@
     return primary_account_from_cleared_callback_;
   }
 
+  void set_on_refresh_token_updated_callback(base::OnceClosure callback) {
+    on_refresh_token_updated_callback_ = std::move(callback);
+  }
+  void set_on_refresh_token_removed_callback(base::OnceClosure callback) {
+    on_refresh_token_removed_callback_ = std::move(callback);
+  }
+
+  const AccountInfo& account_from_refresh_token_updated_callback() {
+    return account_from_refresh_token_updated_callback_;
+  }
+  bool validity_from_refresh_token_updated_callback() {
+    return validity_from_refresh_token_updated_callback_;
+  }
+  const AccountInfo& account_from_refresh_token_removed_callback() {
+    return account_from_refresh_token_removed_callback_;
+  }
+
  private:
   // IdentityManager::Observer:
   void OnPrimaryAccountSet(const AccountInfo& primary_account_info) override {
@@ -163,12 +254,30 @@
     if (on_primary_account_cleared_callback_)
       std::move(on_primary_account_cleared_callback_).Run();
   }
+  void OnRefreshTokenUpdatedForAccount(const AccountInfo& account_info,
+                                       bool is_valid) override {
+    account_from_refresh_token_updated_callback_ = account_info;
+    validity_from_refresh_token_updated_callback_ = is_valid;
+    if (on_refresh_token_updated_callback_)
+      std::move(on_refresh_token_updated_callback_).Run();
+  }
+  void OnRefreshTokenRemovedForAccount(
+      const AccountInfo& account_info) override {
+    account_from_refresh_token_removed_callback_ = account_info;
+    if (on_refresh_token_removed_callback_)
+      std::move(on_refresh_token_removed_callback_).Run();
+  }
 
   IdentityManager* identity_manager_;
   base::OnceClosure on_primary_account_set_callback_;
   base::OnceClosure on_primary_account_cleared_callback_;
+  base::OnceClosure on_refresh_token_updated_callback_;
+  base::OnceClosure on_refresh_token_removed_callback_;
   AccountInfo primary_account_from_set_callback_;
   AccountInfo primary_account_from_cleared_callback_;
+  AccountInfo account_from_refresh_token_updated_callback_;
+  bool validity_from_refresh_token_updated_callback_;
+  AccountInfo account_from_refresh_token_removed_callback_;
 };
 
 class TestIdentityManagerDiagnosticsObserver
@@ -516,4 +625,284 @@
 }
 #endif
 
+TEST_F(IdentityManagerTest,
+       CallbackSentOnPrimaryAccountRefreshTokenUpdateWithValidToken) {
+  std::string account_id = signin_manager()->GetAuthenticatedAccountId();
+
+  base::RunLoop run_loop;
+  identity_manager_observer()->set_on_refresh_token_updated_callback(
+      run_loop.QuitClosure());
+  token_service()->UpdateCredentials(account_id, "refresh_token");
+  run_loop.Run();
+
+  AccountInfo account_info =
+      identity_manager_observer()
+          ->account_from_refresh_token_updated_callback();
+  EXPECT_EQ(kTestGaiaId, account_info.gaia);
+  EXPECT_EQ(kTestEmail, account_info.email);
+
+  EXPECT_TRUE(identity_manager_observer()
+                  ->validity_from_refresh_token_updated_callback());
+}
+
+TEST_F(IdentityManagerTest,
+       CallbackSentOnPrimaryAccountRefreshTokenUpdateWithInvalidToken) {
+  std::string account_id = signin_manager()->GetAuthenticatedAccountId();
+
+  base::RunLoop run_loop;
+  identity_manager_observer()->set_on_refresh_token_updated_callback(
+      run_loop.QuitClosure());
+  token_service()->UpdateCredentials(
+      account_id, OAuth2TokenServiceDelegate::kInvalidRefreshToken);
+  run_loop.Run();
+
+  AccountInfo account_info =
+      identity_manager_observer()
+          ->account_from_refresh_token_updated_callback();
+  EXPECT_EQ(kTestGaiaId, account_info.gaia);
+  EXPECT_EQ(kTestEmail, account_info.email);
+
+  EXPECT_FALSE(identity_manager_observer()
+                   ->validity_from_refresh_token_updated_callback());
+}
+
+TEST_F(IdentityManagerTest, CallbackSentOnPrimaryAccountRefreshTokenRemoval) {
+  std::string account_id = signin_manager()->GetAuthenticatedAccountId();
+
+  base::RunLoop run_loop;
+  identity_manager_observer()->set_on_refresh_token_updated_callback(
+      run_loop.QuitClosure());
+  token_service()->UpdateCredentials(account_id, "refresh_token");
+  run_loop.Run();
+
+  base::RunLoop run_loop2;
+  identity_manager_observer()->set_on_refresh_token_removed_callback(
+      run_loop2.QuitClosure());
+  token_service()->RevokeCredentials(account_id);
+  run_loop2.Run();
+
+  AccountInfo account_info =
+      identity_manager_observer()
+          ->account_from_refresh_token_removed_callback();
+  EXPECT_EQ(kTestGaiaId, account_info.gaia);
+  EXPECT_EQ(kTestEmail, account_info.email);
+}
+
+TEST_F(IdentityManagerTest,
+       CallbackSentOnSecondaryAccountRefreshTokenUpdateWithValidToken) {
+  account_tracker()->SeedAccountInfo(kTestGaiaId2, kTestEmail2);
+  std::string account_id =
+      account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId2).account_id;
+
+  base::RunLoop run_loop;
+  identity_manager_observer()->set_on_refresh_token_updated_callback(
+      run_loop.QuitClosure());
+  token_service()->UpdateCredentials(account_id, "refresh_token");
+  run_loop.Run();
+
+  AccountInfo account_info =
+      identity_manager_observer()
+          ->account_from_refresh_token_updated_callback();
+  EXPECT_EQ(kTestGaiaId2, account_info.gaia);
+  EXPECT_EQ(kTestEmail2, account_info.email);
+
+  EXPECT_TRUE(identity_manager_observer()
+                  ->validity_from_refresh_token_updated_callback());
+}
+
+TEST_F(IdentityManagerTest,
+       CallbackSentOnSecondaryAccountRefreshTokenUpdateWithInvalidToken) {
+  account_tracker()->SeedAccountInfo(kTestGaiaId2, kTestEmail2);
+  std::string account_id =
+      account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId2).account_id;
+
+  base::RunLoop run_loop;
+  identity_manager_observer()->set_on_refresh_token_updated_callback(
+      run_loop.QuitClosure());
+  token_service()->UpdateCredentials(
+      account_id, OAuth2TokenServiceDelegate::kInvalidRefreshToken);
+  run_loop.Run();
+
+  AccountInfo account_info =
+      identity_manager_observer()
+          ->account_from_refresh_token_updated_callback();
+  EXPECT_EQ(kTestGaiaId2, account_info.gaia);
+  EXPECT_EQ(kTestEmail2, account_info.email);
+
+  EXPECT_FALSE(identity_manager_observer()
+                   ->validity_from_refresh_token_updated_callback());
+}
+
+TEST_F(IdentityManagerTest, CallbackSentOnSecondaryAccountRefreshTokenRemoval) {
+  account_tracker()->SeedAccountInfo(kTestGaiaId2, kTestEmail2);
+  std::string account_id =
+      account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId2).account_id;
+
+  base::RunLoop run_loop;
+  identity_manager_observer()->set_on_refresh_token_updated_callback(
+      run_loop.QuitClosure());
+  token_service()->UpdateCredentials(account_id, "refresh_token");
+  run_loop.Run();
+
+  base::RunLoop run_loop2;
+  identity_manager_observer()->set_on_refresh_token_removed_callback(
+      run_loop2.QuitClosure());
+  token_service()->RevokeCredentials(account_id);
+  run_loop2.Run();
+
+  AccountInfo account_info =
+      identity_manager_observer()
+          ->account_from_refresh_token_removed_callback();
+  EXPECT_EQ(kTestGaiaId2, account_info.gaia);
+  EXPECT_EQ(kTestEmail2, account_info.email);
+}
+
+#if !defined(OS_CHROMEOS)
+TEST_F(
+    IdentityManagerTest,
+    CallbackSentOnSecondaryAccountRefreshTokenUpdateWithValidTokenWhenNoPrimaryAccount) {
+  base::RunLoop run_loop;
+  identity_manager_observer()->set_on_primary_account_cleared_callback(
+      run_loop.QuitClosure());
+  signin_manager()->ForceSignOut();
+  run_loop.Run();
+
+  account_tracker()->SeedAccountInfo(kTestGaiaId2, kTestEmail2);
+  std::string account_id =
+      account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId2).account_id;
+
+  base::RunLoop run_loop2;
+  identity_manager_observer()->set_on_refresh_token_updated_callback(
+      run_loop2.QuitClosure());
+  token_service()->UpdateCredentials(account_id, "refresh_token");
+  run_loop2.Run();
+
+  AccountInfo account_info =
+      identity_manager_observer()
+          ->account_from_refresh_token_updated_callback();
+  EXPECT_EQ(kTestGaiaId2, account_info.gaia);
+  EXPECT_EQ(kTestEmail2, account_info.email);
+
+  EXPECT_TRUE(identity_manager_observer()
+                  ->validity_from_refresh_token_updated_callback());
+}
+
+TEST_F(
+    IdentityManagerTest,
+    CallbackSentOnSecondaryAccountRefreshTokenUpdateWithInvalidTokeWhenNoPrimaryAccount) {
+  base::RunLoop run_loop;
+  identity_manager_observer()->set_on_primary_account_cleared_callback(
+      run_loop.QuitClosure());
+  signin_manager()->ForceSignOut();
+  run_loop.Run();
+
+  account_tracker()->SeedAccountInfo(kTestGaiaId2, kTestEmail2);
+  std::string account_id =
+      account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId2).account_id;
+
+  base::RunLoop run_loop2;
+  identity_manager_observer()->set_on_refresh_token_updated_callback(
+      run_loop2.QuitClosure());
+  token_service()->UpdateCredentials(
+      account_id, OAuth2TokenServiceDelegate::kInvalidRefreshToken);
+  run_loop2.Run();
+
+  AccountInfo account_info =
+      identity_manager_observer()
+          ->account_from_refresh_token_updated_callback();
+  EXPECT_EQ(kTestGaiaId2, account_info.gaia);
+  EXPECT_EQ(kTestEmail2, account_info.email);
+
+  EXPECT_FALSE(identity_manager_observer()
+                   ->validity_from_refresh_token_updated_callback());
+}
+
+TEST_F(IdentityManagerTest,
+       CallbackSentOnSecondaryAccountRefreshTokenRemovalWhenNoPrimaryAccount) {
+  base::RunLoop run_loop;
+  identity_manager_observer()->set_on_primary_account_cleared_callback(
+      run_loop.QuitClosure());
+  signin_manager()->ForceSignOut();
+  run_loop.Run();
+
+  account_tracker()->SeedAccountInfo(kTestGaiaId2, kTestEmail2);
+  std::string account_id =
+      account_tracker()->FindAccountInfoByGaiaId(kTestGaiaId2).account_id;
+
+  base::RunLoop run_loop2;
+  identity_manager_observer()->set_on_refresh_token_updated_callback(
+      run_loop2.QuitClosure());
+  token_service()->UpdateCredentials(account_id, "refresh_token");
+  run_loop2.Run();
+
+  base::RunLoop run_loop3;
+  identity_manager_observer()->set_on_refresh_token_removed_callback(
+      run_loop3.QuitClosure());
+  token_service()->RevokeCredentials(account_id);
+  run_loop3.Run();
+
+  AccountInfo account_info =
+      identity_manager_observer()
+          ->account_from_refresh_token_removed_callback();
+  EXPECT_EQ(kTestGaiaId2, account_info.gaia);
+  EXPECT_EQ(kTestEmail2, account_info.email);
+}
+#endif
+
+TEST_F(IdentityManagerTest,
+       IdentityManagerGetsTokenUpdateEventBeforeTokenServiceObserver) {
+  std::string account_id = signin_manager()->GetAuthenticatedAccountId();
+
+  base::RunLoop run_loop;
+  TestTokenServiceObserver token_service_observer(token_service());
+  token_service_observer.set_on_refresh_token_available_callback(
+      run_loop.QuitClosure());
+
+  // NOTE: For this test to be meaningful, TestTokenServiceObserver
+  // needs to be created before the IdentityManager instance that it's
+  // interacting with. Otherwise, even an implementation where they're
+  // both TokenService::Observers would work as IdentityManager would
+  // get notified first during the observer callbacks.
+  RecreateIdentityManager();
+  token_service_observer.set_identity_manager(identity_manager());
+
+  // When the observer receives the callback directly from the token service,
+  // IdentityManager should have already received the event and forwarded it on
+  // to its own observers. This is checked internally by
+  // TestTokenServiceObserver.
+  token_service()->UpdateCredentials(account_id, "refresh_token");
+  run_loop.Run();
+}
+
+TEST_F(IdentityManagerTest,
+       IdentityManagerGetsTokenRemovalEventBeforeTokenServiceObserver) {
+  std::string account_id = signin_manager()->GetAuthenticatedAccountId();
+
+  base::RunLoop run_loop;
+  TestTokenServiceObserver token_service_observer(token_service());
+  token_service_observer.set_on_refresh_token_available_callback(
+      run_loop.QuitClosure());
+
+  // NOTE: For this test to be meaningful, TestTokenServiceObserver
+  // needs to be created before the IdentityManager instance that it's
+  // interacting with. Otherwise, even an implementation where they're
+  // both TokenService::Observers would work as IdentityManager would
+  // get notified first during the observer callbacks.
+  RecreateIdentityManager();
+  token_service_observer.set_identity_manager(identity_manager());
+
+  token_service()->UpdateCredentials(account_id, "refresh_token");
+  run_loop.Run();
+
+  // When the observer receives the callback directly from the token service,
+  // IdentityManager should have already received the event and forwarded it on
+  // to its own observers. This is checked internally by
+  // TestTokenServiceObserver.
+  base::RunLoop run_loop2;
+  token_service_observer.set_on_refresh_token_revoked_callback(
+      run_loop2.QuitClosure());
+  token_service()->RevokeCredentials(account_id);
+  run_loop2.Run();
+}
+
 }  // namespace identity
diff --git a/services/service_manager/public/cpp/BUILD.gn b/services/service_manager/public/cpp/BUILD.gn
index df07080f..fead87b 100644
--- a/services/service_manager/public/cpp/BUILD.gn
+++ b/services/service_manager/public/cpp/BUILD.gn
@@ -21,6 +21,8 @@
     "service_context.h",
     "service_context_ref.cc",
     "service_context_ref.h",
+    "service_keepalive.cc",
+    "service_keepalive.h",
     "service_runner.cc",
     "service_runner.h",
   ]
diff --git a/services/service_manager/public/cpp/service_context_ref.cc b/services/service_manager/public/cpp/service_context_ref.cc
index 8712ecb..9865a60 100644
--- a/services/service_manager/public/cpp/service_context_ref.cc
+++ b/services/service_manager/public/cpp/service_context_ref.cc
@@ -70,8 +70,15 @@
       weak_factory_.GetWeakPtr(), base::SequencedTaskRunnerHandle::Get());
 }
 
+void ServiceContextRefFactory::SetRefAddedCallback(
+    const base::RepeatingClosure& ref_added_closure) {
+  ref_added_closure_ = ref_added_closure;
+}
+
 void ServiceContextRefFactory::AddRef() {
   ++ref_count_;
+  if (ref_added_closure_)
+    ref_added_closure_.Run();
 }
 
 void ServiceContextRefFactory::Release() {
diff --git a/services/service_manager/public/cpp/service_context_ref.h b/services/service_manager/public/cpp/service_context_ref.h
index 1126a0e..b5309c6 100644
--- a/services/service_manager/public/cpp/service_context_ref.h
+++ b/services/service_manager/public/cpp/service_context_ref.h
@@ -41,6 +41,8 @@
 
   bool HasNoRefs() const { return !ref_count_; }
 
+  void SetRefAddedCallback(const base::RepeatingClosure& on_ref_added);
+
  private:
   friend ServiceContextRefImpl;
 
@@ -49,6 +51,7 @@
   void Release();
 
   base::RepeatingClosure quit_closure_;
+  base::RepeatingClosure ref_added_closure_;
   int ref_count_ = 0;
   base::WeakPtrFactory<ServiceContextRefFactory> weak_factory_;
 
diff --git a/services/service_manager/public/cpp/service_keepalive.cc b/services/service_manager/public/cpp/service_keepalive.cc
new file mode 100644
index 0000000..0120997
--- /dev/null
+++ b/services/service_manager/public/cpp/service_keepalive.cc
@@ -0,0 +1,38 @@
+// 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/service_manager/public/cpp/service_keepalive.h"
+
+#include "base/bind.h"
+#include "base/task_scheduler/post_task.h"
+#include "services/service_manager/public/cpp/service_context.h"
+
+namespace service_manager {
+
+ServiceKeepalive::ServiceKeepalive(ServiceContext* context,
+                                   base::TimeDelta idle_timeout)
+    : context_(context),
+      idle_timeout_(idle_timeout),
+      ref_factory_(base::BindRepeating(&ServiceKeepalive::OnRefCountZero,
+                                       base::Unretained(this))),
+      weak_ptr_factory_(this) {
+  ref_factory_.SetRefAddedCallback(base::BindRepeating(
+      &ServiceKeepalive::OnRefAdded, base::Unretained(this)));
+}
+
+ServiceKeepalive::~ServiceKeepalive() = default;
+
+std::unique_ptr<ServiceContextRef> ServiceKeepalive::CreateRef() {
+  return ref_factory_.CreateRef();
+}
+
+void ServiceKeepalive::OnRefAdded() {
+  idle_timer_.Stop();
+}
+
+void ServiceKeepalive::OnRefCountZero() {
+  idle_timer_.Start(FROM_HERE, idle_timeout_, context_->CreateQuitClosure());
+}
+
+}  // namespace service_manager
diff --git a/services/service_manager/public/cpp/service_keepalive.h b/services/service_manager/public/cpp/service_keepalive.h
new file mode 100644
index 0000000..dc657dd
--- /dev/null
+++ b/services/service_manager/public/cpp/service_keepalive.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 SERVICES_SERVICE_MANAGER_PUBLIC_CPP_SERVICE_KEEPALIVE_H_
+#define SERVICES_SERVICE_MANAGER_PUBLIC_CPP_SERVICE_KEEPALIVE_H_
+
+#include "services/service_manager/public/cpp/export.h"
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/timer/timer.h"
+#include "services/service_manager/public/cpp/service_context_ref.h"
+
+namespace service_manager {
+
+class ServiceContext;
+
+// Helper class which vends ServiceContextRefs from its own
+// ServiceContextRefFactory. Whenever the ref count goes to zero, this starts an
+// idle timer (configured at construction time). If the timer runs out before
+// another ref is created, this requests clean service termination from the
+// service manager on the service's behalf.
+//
+// Useful if you want your service to stay alive for some fixed delay after
+// going idle, to insulate against frequent startup and shutdown of the service
+// when used at regular intervals or in rapid but not continuous succession, as
+// is fairly common.
+//
+// Use this in place of directly owning a ServiceContextRefFactory, to vend
+// service references to different endpoints in your service.
+class SERVICE_MANAGER_PUBLIC_CPP_EXPORT ServiceKeepalive {
+ public:
+  // Creates a keepalive which allows the service to be idle for |idle_timeout|
+  // before requesting termination. Must outlive |context|, which is not owned.
+  ServiceKeepalive(ServiceContext* context, base::TimeDelta idle_timeout);
+  ~ServiceKeepalive();
+
+  std::unique_ptr<ServiceContextRef> CreateRef();
+
+ private:
+  void OnRefAdded();
+  void OnRefCountZero();
+
+  ServiceContext* const context_;
+  const base::TimeDelta idle_timeout_;
+  base::OneShotTimer idle_timer_;
+  ServiceContextRefFactory ref_factory_;
+  base::WeakPtrFactory<ServiceKeepalive> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(ServiceKeepalive);
+};
+
+}  // namespace service_manager
+
+#endif  // SERVICES_SERVICE_MANAGER_PUBLIC_CPP_SERVICE_KEEPALIVE_H_
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index 788a3052..84609846 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -2585,7 +2585,6 @@
           "--test-launcher-batch-limit=1",
           "--test-launcher-print-test-stdio=always"
         ],
-        "experiment_percentage": 100,
         "swarming": {
           "can_use_on_swarming_builders": true,
           "shards": 4
@@ -2980,7 +2979,6 @@
           "--test-launcher-batch-limit=1",
           "--test-launcher-print-test-stdio=always"
         ],
-        "experiment_percentage": 100,
         "swarming": {
           "can_use_on_swarming_builders": true
         },
diff --git a/testing/buildbot/chromium.perf.fyi.json b/testing/buildbot/chromium.perf.fyi.json
index 482b8c8dc1..0fa5576 100644
--- a/testing/buildbot/chromium.perf.fyi.json
+++ b/testing/buildbot/chromium.perf.fyi.json
@@ -450,136 +450,6 @@
       }
     ]
   },
-  "Mac 10.13 Laptop High End": {
-    "isolated_scripts": [
-      {
-        "args": [
-          "--non-telemetry=true",
-          "--migrated-test=true"
-        ],
-        "isolate_name": "net_perftests",
-        "merge": {
-          "args": [
-            "--service-account-file",
-            "/creds/service_accounts/service-account-chromium-perf-histograms.json"
-          ],
-          "script": "//tools/perf/process_perf_results.py"
-        },
-        "name": "net_perftests",
-        "override_compile_targets": [
-          "net_perftests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "os": "Mac-10.13",
-              "pool": "chrome.tests.perf-fyi"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 36000,
-          "ignore_task_failure": false,
-          "io_timeout": 1800,
-          "shards": 1,
-          "upload_test_results": true
-        },
-        "trigger_script": {
-          "args": [
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/perf_device_trigger.py"
-        }
-      },
-      {
-        "args": [
-          "-v",
-          "--browser=release",
-          "--upload-results",
-          "--run-ref-build",
-          "--test-shard-map-filename=benchmark_desktop_bot_map.json"
-        ],
-        "isolate_name": "performance_test_suite",
-        "merge": {
-          "args": [
-            "--service-account-file",
-            "/creds/service_accounts/service-account-chromium-perf-histograms.json"
-          ],
-          "script": "//tools/perf/process_perf_results.py"
-        },
-        "name": "performance_test_suite",
-        "override_compile_targets": [
-          "performance_test_suite"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "os": "Mac-10.13",
-              "pool": "chrome.tests.perf-fyi"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 36000,
-          "ignore_task_failure": false,
-          "io_timeout": 1800,
-          "shards": 26,
-          "upload_test_results": true
-        },
-        "trigger_script": {
-          "args": [
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/perf_device_trigger.py"
-        }
-      },
-      {
-        "args": [
-          "--non-telemetry=true",
-          "--migrated-test=true"
-        ],
-        "isolate_name": "views_perftests",
-        "merge": {
-          "args": [
-            "--service-account-file",
-            "/creds/service_accounts/service-account-chromium-perf-histograms.json"
-          ],
-          "script": "//tools/perf/process_perf_results.py"
-        },
-        "name": "views_perftests",
-        "override_compile_targets": [
-          "views_perftests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "os": "Mac-10.13",
-              "pool": "chrome.tests.perf-fyi"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 36000,
-          "ignore_task_failure": false,
-          "io_timeout": 1800,
-          "shards": 1,
-          "upload_test_results": true
-        },
-        "trigger_script": {
-          "args": [
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/perf_device_trigger.py"
-        }
-      }
-    ]
-  },
   "Mojo Linux Perf": {
     "isolated_scripts": [
       {
diff --git a/testing/buildbot/chromium.perf.json b/testing/buildbot/chromium.perf.json
index 29b1317..13c74fe 100644
--- a/testing/buildbot/chromium.perf.json
+++ b/testing/buildbot/chromium.perf.json
@@ -20624,11723 +20624,11 @@
       "chromedriver"
     ]
   },
-  "Mac 10.12 Perf": {
-    "isolated_scripts": [
-      {
-        "args": [
-          "blink_perf.bindings",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.bindings",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.bindings",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.bindings.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.canvas",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.canvas",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.canvas",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.canvas.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.css",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.css",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.css",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.css.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.dom",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.dom",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build158-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.dom",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.dom.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build158-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.events",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.events",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.events",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.events.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.image_decoder",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.image_decoder",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.image_decoder",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.image_decoder.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.layout",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.layout",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.layout",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.layout.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.owp_storage",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.owp_storage",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.owp_storage",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.owp_storage.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.paint",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.paint",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build158-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.paint",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.paint.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build158-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.parser",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.parser",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build161-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.parser",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.parser.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build161-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.shadow_dom",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.shadow_dom",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.shadow_dom",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.shadow_dom.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.svg",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.svg",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build161-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.svg",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.svg.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build161-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "dromaeo",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "dromaeo",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "dromaeo",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "dromaeo.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "dummy_benchmark.histogram_benchmark_1",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "dummy_benchmark.histogram_benchmark_1",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "dummy_benchmark.histogram_benchmark_1",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "dummy_benchmark.histogram_benchmark_1.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "dummy_benchmark.noisy_benchmark_1",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "dummy_benchmark.noisy_benchmark_1",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "dummy_benchmark.noisy_benchmark_1",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "dummy_benchmark.noisy_benchmark_1.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "dummy_benchmark.stable_benchmark_1",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "dummy_benchmark.stable_benchmark_1",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build158-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "dummy_benchmark.stable_benchmark_1",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "dummy_benchmark.stable_benchmark_1.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build158-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "jetstream",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "jetstream",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build161-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "jetstream",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "jetstream.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build161-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "kraken",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "kraken",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "kraken",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "kraken.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "loading.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "loading.desktop",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 14400,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "media.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "media.desktop",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "media.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "media.desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "memory.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "memory.desktop",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build161-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "memory.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "memory.desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build161-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "memory.long_running_idle_gmail_background_tbmv2",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "memory.long_running_idle_gmail_background_tbmv2",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "memory.long_running_idle_gmail_background_tbmv2",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "memory.long_running_idle_gmail_background_tbmv2.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "memory.long_running_idle_gmail_tbmv2",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "memory.long_running_idle_gmail_tbmv2",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "memory.long_running_idle_gmail_tbmv2",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "memory.long_running_idle_gmail_tbmv2.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [],
-        "isolate_name": "net_perftests",
-        "name": "net_perftests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "octane",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "octane",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "octane",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "octane.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "oortonline_tbmv2",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "oortonline_tbmv2",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "oortonline_tbmv2",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "oortonline_tbmv2.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "power.idle_platform",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "power.idle_platform",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "rasterize_and_record_micro.partial_invalidation",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "rasterize_and_record_micro.partial_invalidation",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "rasterize_and_record_micro.partial_invalidation",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "rasterize_and_record_micro.partial_invalidation.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "rasterize_and_record_micro.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "rasterize_and_record_micro.top_25",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "rasterize_and_record_micro.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "rasterize_and_record_micro.top_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "rendering.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "rendering.desktop",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "rendering.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "rendering.desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "scheduler.tough_scheduling_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "scheduler.tough_scheduling_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build158-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "scheduler.tough_scheduling_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "scheduler.tough_scheduling_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build158-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.desktop_tough_pinch_zoom_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.desktop_tough_pinch_zoom_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.desktop_tough_pinch_zoom_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.desktop_tough_pinch_zoom_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.gpu_rasterization.polymer",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.gpu_rasterization.polymer",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.gpu_rasterization.polymer",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.gpu_rasterization.polymer.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.gpu_rasterization.tough_path_rendering_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.gpu_rasterization.tough_path_rendering_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.gpu_rasterization.tough_path_rendering_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.gpu_rasterization.tough_path_rendering_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.gpu_rasterization.tough_scrolling_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.gpu_rasterization.tough_scrolling_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.gpu_rasterization.tough_scrolling_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.gpu_rasterization.tough_scrolling_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.gpu_rasterization_and_decoding.image_decoding_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.gpu_rasterization_and_decoding.image_decoding_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.gpu_rasterization_and_decoding.image_decoding_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.gpu_rasterization_and_decoding.image_decoding_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.image_decoding_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.image_decoding_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.image_decoding_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.image_decoding_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.key_desktop_move_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.key_desktop_move_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build158-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.key_desktop_move_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.key_desktop_move_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build158-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.maps",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.maps",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.maps",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.maps.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.top_25_smooth",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.top_25_smooth",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.top_25_smooth",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.top_25_smooth.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_ad_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_ad_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build158-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_ad_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_ad_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build158-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_animation_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_animation_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_animation_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_animation_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_canvas_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_canvas_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build161-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_canvas_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_canvas_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build161-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_filters_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_filters_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_filters_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_filters_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_image_decode_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_image_decode_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build158-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_image_decode_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_image_decode_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build158-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_path_rendering_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_path_rendering_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_path_rendering_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_path_rendering_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_scrolling_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_scrolling_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_scrolling_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_scrolling_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_texture_upload_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_texture_upload_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_texture_upload_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_texture_upload_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_webgl_ad_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_webgl_ad_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_webgl_ad_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_webgl_ad_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_webgl_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_webgl_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_webgl_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_webgl_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "speedometer",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "speedometer",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "speedometer-future",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "speedometer-future",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build161-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "speedometer-future",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "speedometer-future.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build161-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "speedometer",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "speedometer.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "speedometer2",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "speedometer2",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "speedometer2-future",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "speedometer2-future",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build161-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "speedometer2-future",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "speedometer2-future.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build161-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "speedometer2",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "speedometer2.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "system_health.common_desktop",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "system_health.common_desktop",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "system_health.common_desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "system_health.common_desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build162-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "system_health.memory_desktop",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "system_health.memory_desktop",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build158-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "system_health.memory_desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "system_health.memory_desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build158-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "tab_switching.typical_25",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "tab_switching.typical_25",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "tab_switching.typical_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "tab_switching.typical_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "thread_times.tough_compositor_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "thread_times.tough_compositor_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "thread_times.tough_compositor_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "thread_times.tough_compositor_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "thread_times.tough_scrolling_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "thread_times.tough_scrolling_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "thread_times.tough_scrolling_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "thread_times.tough_scrolling_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "tracing.tracing_with_background_memory_infra",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "tracing.tracing_with_background_memory_infra",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "tracing.tracing_with_background_memory_infra",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "tracing.tracing_with_background_memory_infra.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build159-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "v8.browsing_desktop",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.browsing_desktop",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build161-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "v8.browsing_desktop-future",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.browsing_desktop-future",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "v8.browsing_desktop-future",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.browsing_desktop-future.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "v8.browsing_desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.browsing_desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build161-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "v8.runtime_stats.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.runtime_stats.top_25",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build158-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [],
-        "isolate_name": "views_perftests",
-        "name": "views_perftests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "wasm",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "wasm",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "wasm",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "wasm.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "webrtc",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "webrtc",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "webrtc",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "webrtc.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:0a2e",
-              "id": "build160-m1",
-              "os": "Mac-10.12",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      }
-    ]
-  },
-  "Mac Air 10.11 Perf": {
-    "isolated_scripts": [
-      {
-        "args": [
-          "blink_perf.bindings",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.bindings",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.bindings",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.bindings.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.canvas",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.canvas",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.canvas",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.canvas.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.css",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.css",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.css",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.css.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.dom",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.dom",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build123-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.dom",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.dom.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build123-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.events",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.events",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.events",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.events.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.image_decoder",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.image_decoder",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.image_decoder",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.image_decoder.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.layout",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.layout",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.layout",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.layout.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.owp_storage",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.owp_storage",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.owp_storage",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.owp_storage.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.paint",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.paint",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build123-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.paint",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.paint.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build123-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.parser",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.parser",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build126-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.parser",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.parser.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build126-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.shadow_dom",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.shadow_dom",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.shadow_dom",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.shadow_dom.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.svg",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.svg",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build126-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.svg",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.svg.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build126-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "dromaeo",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "dromaeo",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "dromaeo",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "dromaeo.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "dummy_benchmark.histogram_benchmark_1",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "dummy_benchmark.histogram_benchmark_1",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "dummy_benchmark.histogram_benchmark_1",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "dummy_benchmark.histogram_benchmark_1.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "dummy_benchmark.noisy_benchmark_1",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "dummy_benchmark.noisy_benchmark_1",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "dummy_benchmark.noisy_benchmark_1",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "dummy_benchmark.noisy_benchmark_1.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "dummy_benchmark.stable_benchmark_1",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "dummy_benchmark.stable_benchmark_1",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build123-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "dummy_benchmark.stable_benchmark_1",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "dummy_benchmark.stable_benchmark_1.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build123-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "jetstream",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "jetstream",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build126-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "jetstream",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "jetstream.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build126-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "kraken",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "kraken",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "kraken",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "kraken.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "loading.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "loading.desktop",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 14400,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "media.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "media.desktop",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "media.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "media.desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "memory.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "memory.desktop",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build126-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "memory.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "memory.desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build126-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "memory.long_running_idle_gmail_background_tbmv2",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "memory.long_running_idle_gmail_background_tbmv2",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "memory.long_running_idle_gmail_background_tbmv2",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "memory.long_running_idle_gmail_background_tbmv2.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "memory.long_running_idle_gmail_tbmv2",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "memory.long_running_idle_gmail_tbmv2",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "memory.long_running_idle_gmail_tbmv2",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "memory.long_running_idle_gmail_tbmv2.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "octane",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "octane",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "octane",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "octane.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "oortonline_tbmv2",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "oortonline_tbmv2",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "oortonline_tbmv2",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "oortonline_tbmv2.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [],
-        "isolate_name": "performance_browser_tests",
-        "name": "performance_browser_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build126-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "power.idle_platform",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "power.idle_platform",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "rasterize_and_record_micro.partial_invalidation",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "rasterize_and_record_micro.partial_invalidation",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "rasterize_and_record_micro.partial_invalidation",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "rasterize_and_record_micro.partial_invalidation.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "rasterize_and_record_micro.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "rasterize_and_record_micro.top_25",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "rasterize_and_record_micro.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "rasterize_and_record_micro.top_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "rendering.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "rendering.desktop",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "rendering.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "rendering.desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "scheduler.tough_scheduling_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "scheduler.tough_scheduling_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build123-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "scheduler.tough_scheduling_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "scheduler.tough_scheduling_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build123-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.desktop_tough_pinch_zoom_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.desktop_tough_pinch_zoom_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.desktop_tough_pinch_zoom_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.desktop_tough_pinch_zoom_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.gpu_rasterization.polymer",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.gpu_rasterization.polymer",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.gpu_rasterization.polymer",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.gpu_rasterization.polymer.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.gpu_rasterization.tough_path_rendering_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.gpu_rasterization.tough_path_rendering_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.gpu_rasterization.tough_path_rendering_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.gpu_rasterization.tough_path_rendering_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.gpu_rasterization.tough_scrolling_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.gpu_rasterization.tough_scrolling_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.gpu_rasterization.tough_scrolling_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.gpu_rasterization.tough_scrolling_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.gpu_rasterization_and_decoding.image_decoding_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.gpu_rasterization_and_decoding.image_decoding_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.gpu_rasterization_and_decoding.image_decoding_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.gpu_rasterization_and_decoding.image_decoding_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.image_decoding_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.image_decoding_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.image_decoding_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.image_decoding_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.key_desktop_move_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.key_desktop_move_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build123-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.key_desktop_move_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.key_desktop_move_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build123-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.maps",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.maps",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.maps",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.maps.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.top_25_smooth",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.top_25_smooth",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.top_25_smooth",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.top_25_smooth.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_ad_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_ad_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build123-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_ad_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_ad_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build123-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_animation_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_animation_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_animation_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_animation_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_canvas_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_canvas_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build126-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_canvas_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_canvas_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build126-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_filters_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_filters_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_filters_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_filters_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_image_decode_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_image_decode_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build123-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_image_decode_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_image_decode_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build123-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_path_rendering_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_path_rendering_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_path_rendering_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_path_rendering_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_scrolling_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_scrolling_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_scrolling_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_scrolling_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_texture_upload_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_texture_upload_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_texture_upload_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_texture_upload_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_webgl_ad_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_webgl_ad_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_webgl_ad_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_webgl_ad_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_webgl_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_webgl_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_webgl_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_webgl_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "speedometer",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "speedometer",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "speedometer-future",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "speedometer-future",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build126-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "speedometer-future",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "speedometer-future.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build126-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "speedometer",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "speedometer.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "speedometer2",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "speedometer2",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "speedometer2-future",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "speedometer2-future",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build126-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "speedometer2-future",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "speedometer2-future.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build126-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "speedometer2",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "speedometer2.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "system_health.common_desktop",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "system_health.common_desktop",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "system_health.common_desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "system_health.common_desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build127-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "system_health.memory_desktop",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "system_health.memory_desktop",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build123-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "system_health.memory_desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "system_health.memory_desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build123-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "tab_switching.typical_25",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "tab_switching.typical_25",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "tab_switching.typical_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "tab_switching.typical_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "thread_times.tough_compositor_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "thread_times.tough_compositor_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "thread_times.tough_compositor_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "thread_times.tough_compositor_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "thread_times.tough_scrolling_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "thread_times.tough_scrolling_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "thread_times.tough_scrolling_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "thread_times.tough_scrolling_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "tracing.tracing_with_background_memory_infra",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "tracing.tracing_with_background_memory_infra",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "tracing.tracing_with_background_memory_infra",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "tracing.tracing_with_background_memory_infra.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build124-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "v8.browsing_desktop",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.browsing_desktop",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build126-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "v8.browsing_desktop-future",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.browsing_desktop-future",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "v8.browsing_desktop-future",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.browsing_desktop-future.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "v8.browsing_desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.browsing_desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build126-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "v8.runtime_stats.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.runtime_stats.top_25",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "wasm",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "wasm",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "wasm",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "wasm.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build125-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "webrtc",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "webrtc",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build126-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "webrtc",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "webrtc.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:1626",
-              "id": "build126-b1",
-              "os": "Mac-10.11",
-              "pool": "Chrome-perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      }
-    ]
-  },
   "Mac Builder Perf": {
     "additional_compile_targets": [
       "chromedriver"
     ]
   },
-  "Mac Pro 10.11 Perf": {
-    "isolated_scripts": [
-      {
-        "args": [
-          "blink_perf.bindings",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.bindings",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.bindings",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.bindings.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.canvas",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.canvas",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.canvas",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.canvas.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.css",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.css",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.css",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.css.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.dom",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.dom",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build205-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.dom",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.dom.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build205-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.events",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.events",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.events",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.events.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.image_decoder",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.image_decoder",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.image_decoder",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.image_decoder.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.layout",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.layout",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.layout",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.layout.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.owp_storage",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.owp_storage",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.owp_storage",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.owp_storage.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.paint",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.paint",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build205-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.paint",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.paint.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build205-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.parser",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.parser",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build208-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.parser",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.parser.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build208-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.shadow_dom",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.shadow_dom",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.shadow_dom",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.shadow_dom.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.svg",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.svg",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build208-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "blink_perf.svg",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "blink_perf.svg.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build208-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "dromaeo",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "dromaeo",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "dromaeo",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "dromaeo.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "dummy_benchmark.histogram_benchmark_1",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "dummy_benchmark.histogram_benchmark_1",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "dummy_benchmark.histogram_benchmark_1",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "dummy_benchmark.histogram_benchmark_1.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "dummy_benchmark.noisy_benchmark_1",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "dummy_benchmark.noisy_benchmark_1",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "dummy_benchmark.noisy_benchmark_1",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "dummy_benchmark.noisy_benchmark_1.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "dummy_benchmark.stable_benchmark_1",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "dummy_benchmark.stable_benchmark_1",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build205-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "dummy_benchmark.stable_benchmark_1",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "dummy_benchmark.stable_benchmark_1.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build205-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "jetstream",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "jetstream",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build208-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "jetstream",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "jetstream.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build208-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "kraken",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "kraken",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "kraken",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "kraken.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "loading.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "loading.desktop",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 14400,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "media.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "media.desktop",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "media.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "media.desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "memory.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "memory.desktop",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build208-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "memory.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "memory.desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build208-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "memory.long_running_idle_gmail_background_tbmv2",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "memory.long_running_idle_gmail_background_tbmv2",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "memory.long_running_idle_gmail_background_tbmv2",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "memory.long_running_idle_gmail_background_tbmv2.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "memory.long_running_idle_gmail_tbmv2",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "memory.long_running_idle_gmail_tbmv2",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "memory.long_running_idle_gmail_tbmv2",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "memory.long_running_idle_gmail_tbmv2.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "octane",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "octane",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "octane",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "octane.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "oortonline_tbmv2",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "oortonline_tbmv2",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "oortonline_tbmv2",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "oortonline_tbmv2.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [],
-        "isolate_name": "performance_browser_tests",
-        "name": "performance_browser_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "power.idle_platform",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "power.idle_platform",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "rasterize_and_record_micro.partial_invalidation",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "rasterize_and_record_micro.partial_invalidation",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "rasterize_and_record_micro.partial_invalidation",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "rasterize_and_record_micro.partial_invalidation.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "rasterize_and_record_micro.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "rasterize_and_record_micro.top_25",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "rasterize_and_record_micro.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "rasterize_and_record_micro.top_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "rendering.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "rendering.desktop",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "rendering.desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "rendering.desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "scheduler.tough_scheduling_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "scheduler.tough_scheduling_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build205-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "scheduler.tough_scheduling_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "scheduler.tough_scheduling_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build205-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.desktop_tough_pinch_zoom_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.desktop_tough_pinch_zoom_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.desktop_tough_pinch_zoom_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.desktop_tough_pinch_zoom_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.gpu_rasterization.polymer",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.gpu_rasterization.polymer",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.gpu_rasterization.polymer",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.gpu_rasterization.polymer.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.gpu_rasterization.tough_path_rendering_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.gpu_rasterization.tough_path_rendering_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.gpu_rasterization.tough_path_rendering_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.gpu_rasterization.tough_path_rendering_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.gpu_rasterization.tough_scrolling_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.gpu_rasterization.tough_scrolling_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.gpu_rasterization.tough_scrolling_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.gpu_rasterization.tough_scrolling_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.gpu_rasterization_and_decoding.image_decoding_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.gpu_rasterization_and_decoding.image_decoding_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.gpu_rasterization_and_decoding.image_decoding_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.gpu_rasterization_and_decoding.image_decoding_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.image_decoding_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.image_decoding_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.image_decoding_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.image_decoding_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.key_desktop_move_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.key_desktop_move_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build205-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.key_desktop_move_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.key_desktop_move_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build205-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.maps",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.maps",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.maps",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.maps.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.top_25_smooth",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.top_25_smooth",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.top_25_smooth",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.top_25_smooth.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_ad_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_ad_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build205-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_ad_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_ad_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build205-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_animation_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_animation_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_animation_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_animation_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_canvas_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_canvas_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build208-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_canvas_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_canvas_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build208-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_filters_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_filters_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_filters_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_filters_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_image_decode_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_image_decode_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build205-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_image_decode_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_image_decode_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build205-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_path_rendering_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_path_rendering_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_path_rendering_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_path_rendering_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_scrolling_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_scrolling_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_scrolling_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_scrolling_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_texture_upload_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_texture_upload_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_texture_upload_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_texture_upload_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_webgl_ad_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_webgl_ad_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_webgl_ad_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_webgl_ad_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_webgl_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_webgl_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "smoothness.tough_webgl_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "smoothness.tough_webgl_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "speedometer",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "speedometer",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "speedometer-future",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "speedometer-future",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build208-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "speedometer-future",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "speedometer-future.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build208-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "speedometer",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "speedometer.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "speedometer2",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "speedometer2",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "speedometer2-future",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "speedometer2-future",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build208-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "speedometer2-future",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "speedometer2-future.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build208-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "speedometer2",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "speedometer2.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "system_health.common_desktop",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "system_health.common_desktop",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "system_health.common_desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "system_health.common_desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build209-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "system_health.memory_desktop",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "system_health.memory_desktop",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build205-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "system_health.memory_desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "system_health.memory_desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build205-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "tab_switching.typical_25",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "tab_switching.typical_25",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "tab_switching.typical_25",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "tab_switching.typical_25.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "thread_times.tough_compositor_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "thread_times.tough_compositor_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "thread_times.tough_compositor_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "thread_times.tough_compositor_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "thread_times.tough_scrolling_cases",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "thread_times.tough_scrolling_cases",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "thread_times.tough_scrolling_cases",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "thread_times.tough_scrolling_cases.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "tracing.tracing_with_background_memory_infra",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "tracing.tracing_with_background_memory_infra",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "tracing.tracing_with_background_memory_infra",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "tracing.tracing_with_background_memory_infra.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "v8.browsing_desktop",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.browsing_desktop",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build208-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "v8.browsing_desktop-future",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.browsing_desktop-future",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "v8.browsing_desktop-future",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.browsing_desktop-future.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "v8.browsing_desktop",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.browsing_desktop.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build208-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "v8.runtime_stats.top_25",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "v8.runtime_stats.top_25",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build205-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "wasm",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "wasm",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "wasm",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "wasm.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build207-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "webrtc",
-          "-v",
-          "--upload-results",
-          "--browser=release",
-          "--output-format=histograms"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "webrtc",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": false,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      },
-      {
-        "args": [
-          "webrtc",
-          "-v",
-          "--upload-results",
-          "--browser=reference",
-          "--output-format=histograms",
-          "--max-failures=5",
-          "--output-trace-tag=_ref"
-        ],
-        "isolate_name": "telemetry_perf_tests",
-        "name": "webrtc.reference",
-        "override_compile_targets": [
-          "telemetry_perf_tests"
-        ],
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "1002:6821",
-              "id": "build206-b7",
-              "os": "Mac-10.11",
-              "pool": "chrome.tests.perf"
-            }
-          ],
-          "expiration": 36000,
-          "hard_timeout": 10800,
-          "ignore_task_failure": true,
-          "io_timeout": 1200,
-          "upload_test_results": true
-        }
-      }
-    ]
-  },
   "Win 10 High-DPI Perf": {
     "isolated_scripts": [
       {
@@ -48349,6 +36637,47 @@
       },
       {
         "args": [
+          "--non-telemetry=true",
+          "--migrated-test=true"
+        ],
+        "isolate_name": "performance_browser_tests",
+        "merge": {
+          "args": [
+            "--service-account-file",
+            "/creds/service_accounts/service-account-chromium-perf-histograms.json"
+          ],
+          "script": "//tools/perf/process_perf_results.py"
+        },
+        "name": "performance_browser_tests",
+        "override_compile_targets": [
+          "performance_browser_tests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "8086:1626",
+              "os": "Mac-10.12",
+              "pool": "chrome.tests.perf"
+            }
+          ],
+          "expiration": 36000,
+          "hard_timeout": 36000,
+          "ignore_task_failure": false,
+          "io_timeout": 1800,
+          "shards": 1,
+          "upload_test_results": true
+        },
+        "trigger_script": {
+          "args": [
+            "--multiple-dimension-script-verbose",
+            "True"
+          ],
+          "script": "//testing/trigger_scripts/perf_device_trigger.py"
+        }
+      },
+      {
+        "args": [
           "-v",
           "--browser=release",
           "--upload-results",
@@ -48392,5 +36721,176 @@
         }
       }
     ]
+  },
+  "mac-10_13_laptop_high_end-perf": {
+    "isolated_scripts": [
+      {
+        "args": [
+          "--non-telemetry=true",
+          "--migrated-test=true"
+        ],
+        "isolate_name": "media_perftests",
+        "merge": {
+          "args": [
+            "--service-account-file",
+            "/creds/service_accounts/service-account-chromium-perf-histograms.json"
+          ],
+          "script": "//tools/perf/process_perf_results.py"
+        },
+        "name": "media_perftests",
+        "override_compile_targets": [
+          "media_perftests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "1002:6821",
+              "os": "Mac-10.13",
+              "pool": "chrome.tests.perf"
+            }
+          ],
+          "expiration": 36000,
+          "hard_timeout": 36000,
+          "ignore_task_failure": false,
+          "io_timeout": 1800,
+          "shards": 1,
+          "upload_test_results": true
+        },
+        "trigger_script": {
+          "args": [
+            "--multiple-dimension-script-verbose",
+            "True"
+          ],
+          "script": "//testing/trigger_scripts/perf_device_trigger.py"
+        }
+      },
+      {
+        "args": [
+          "--non-telemetry=true",
+          "--migrated-test=true"
+        ],
+        "isolate_name": "net_perftests",
+        "merge": {
+          "args": [
+            "--service-account-file",
+            "/creds/service_accounts/service-account-chromium-perf-histograms.json"
+          ],
+          "script": "//tools/perf/process_perf_results.py"
+        },
+        "name": "net_perftests",
+        "override_compile_targets": [
+          "net_perftests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "1002:6821",
+              "os": "Mac-10.13",
+              "pool": "chrome.tests.perf"
+            }
+          ],
+          "expiration": 36000,
+          "hard_timeout": 36000,
+          "ignore_task_failure": false,
+          "io_timeout": 1800,
+          "shards": 1,
+          "upload_test_results": true
+        },
+        "trigger_script": {
+          "args": [
+            "--multiple-dimension-script-verbose",
+            "True"
+          ],
+          "script": "//testing/trigger_scripts/perf_device_trigger.py"
+        }
+      },
+      {
+        "args": [
+          "-v",
+          "--browser=release",
+          "--upload-results",
+          "--run-ref-build",
+          "--test-shard-map-filename=benchmark_desktop_bot_map.json"
+        ],
+        "isolate_name": "performance_test_suite",
+        "merge": {
+          "args": [
+            "--service-account-file",
+            "/creds/service_accounts/service-account-chromium-perf-histograms.json"
+          ],
+          "script": "//tools/perf/process_perf_results.py"
+        },
+        "name": "performance_test_suite",
+        "override_compile_targets": [
+          "performance_test_suite"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "1002:6821",
+              "os": "Mac-10.13",
+              "pool": "chrome.tests.perf"
+            }
+          ],
+          "expiration": 36000,
+          "hard_timeout": 36000,
+          "ignore_task_failure": false,
+          "io_timeout": 1800,
+          "shards": 26,
+          "upload_test_results": true
+        },
+        "trigger_script": {
+          "args": [
+            "--multiple-dimension-script-verbose",
+            "True"
+          ],
+          "script": "//testing/trigger_scripts/perf_device_trigger.py"
+        }
+      },
+      {
+        "args": [
+          "--non-telemetry=true",
+          "--migrated-test=true"
+        ],
+        "isolate_name": "views_perftests",
+        "merge": {
+          "args": [
+            "--service-account-file",
+            "/creds/service_accounts/service-account-chromium-perf-histograms.json"
+          ],
+          "script": "//tools/perf/process_perf_results.py"
+        },
+        "name": "views_perftests",
+        "override_compile_targets": [
+          "views_perftests"
+        ],
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "gpu": "1002:6821",
+              "os": "Mac-10.13",
+              "pool": "chrome.tests.perf"
+            }
+          ],
+          "expiration": 36000,
+          "hard_timeout": 36000,
+          "ignore_task_failure": false,
+          "io_timeout": 1800,
+          "shards": 1,
+          "upload_test_results": true
+        },
+        "trigger_script": {
+          "args": [
+            "--multiple-dimension-script-verbose",
+            "True"
+          ],
+          "script": "//testing/trigger_scripts/perf_device_trigger.py"
+        }
+      }
+    ]
   }
 }
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index af6ad4ce..3e86160 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -884,8 +884,6 @@
         'swarming': {
           'shards': 4,
         },
-        # crbug.com/848278
-        'experiment_percentage': 100,
       },
       'Linux Chromium OS ASan LSan Tests (1)': {
         # content_browsertests is slow on ASAN try bot. crbug.com/822461.
@@ -1933,13 +1931,6 @@
       'Linux ChromiumOS MSan Tests',  # https://crbug.com/831676
       'Linux MSan Tests',  # https://crbug.com/831676
     ],
-    'modifications': {
-      # chromium.memory
-      # crbug.com/848278
-      'Linux ASan LSan Tests (1)': {
-        'experiment_percentage': 100,
-      },
-    },
   },
   'not_site_per_process_browser_tests': {
     'remove_from': [
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
index 858a73f..9551b14 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -5,9 +5,7 @@
 crbug.com/755750 accessibility/selection-affinity.html [ Failure ]
 
 ## Reverse hosting of editable block
-crbug.com/707656 editing/input/scroll-viewport-page-up-down.html [ Failure Pass ]
 crbug.com/707656 editing/selection/click-on-body-margin.html [ Failure ]
-crbug.com/789878 fast/css/readwrite-contenteditable.html [ Failure Pass ]
 
 # Non-interoperable behavior not worth to fix.
 crbug.com/591099 fast/text/apply-start-width-after-skipped-text.html [ Skip ]
@@ -39,7 +37,7 @@
 crbug.com/591099 fast/block/child-not-removed-from-parent-lineboxes-crash.html [ Crash ]
 
 # Crashes/asserts/failures due to inline item reuse.
-crbug.com/591099 fast/css/getComputedStyle/getComputedStyle-resolved-values.html [ Crash ]
+crbug.com/591099 fast/css/getComputedStyle/getComputedStyle-resolved-values.html [ Crash Pass ]
 
 # Fails because we don't yet special-case marquee like legacy does:
 # https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/layout/layout_block.cc?l=1372&rcl=0e081149ecd6a83f6289e3aee5797936008a1e10
@@ -95,8 +93,7 @@
 crbug.com/591099 accessibility/disabled-controls.html [ Failure ]
 crbug.com/714962 accessibility/div-within-anchors-causes-crash.html [ Failure ]
 crbug.com/714962 accessibility/dl-role.html [ Failure ]
-crbug.com/591099 accessibility/element-role-mapping-focusable.html [ Failure Pass ]
-crbug.com/591099 accessibility/element-role-mapping-normal.html [ Failure ]
+crbug.com/591099 accessibility/element-role-mapping-normal.html [ Failure Pass ]
 crbug.com/714962 accessibility/first-letter-text-transform-causes-crash.html [ Failure ]
 crbug.com/591099 accessibility/focusable-div.html [ Failure ]
 crbug.com/591099 accessibility/focusable-span.html [ Failure ]
@@ -104,7 +101,6 @@
 crbug.com/591099 accessibility/inline-text-bidi-bounds-for-range.html [ Failure ]
 crbug.com/714962 accessibility/inline-text-bounds-for-range-br.html [ Failure ]
 crbug.com/591099 accessibility/inline-text-bounds-for-range.html [ Failure ]
-crbug.com/591099 accessibility/inline-text-box-next-on-line.html [ Failure Pass ]
 crbug.com/591099 accessibility/inline-text-change-style.html [ Failure ]
 crbug.com/591099 accessibility/inline-text-changes.html [ Failure ]
 crbug.com/591099 accessibility/inline-text-word-boundaries.html [ Failure ]
@@ -172,36 +168,25 @@
 crbug.com/591099 css3/selectors3/xml/css3-modsel-167.xml [ Failure ]
 crbug.com/591099 css3/selectors3/xml/css3-modsel-167a.xml [ Failure ]
 crbug.com/591099 css3/selectors3/xml/css3-modsel-38.xml [ Failure ]
-crbug.com/591099 editing/assert_selection.html [ Failure Pass ]
 crbug.com/591099 editing/caret/caret-color-014.html [ Failure ]
 crbug.com/591099 editing/caret/caret-color-015.html [ Failure ]
 crbug.com/591099 editing/execCommand/findString.html [ Failure ]
-crbug.com/714962 editing/pasteboard/copy-element-with-conflicting-background-color-from-rule.html [ Failure Pass ]
 crbug.com/714962 editing/pasteboard/copy-paste-pre-line-content.html [ Failure ]
 crbug.com/591099 editing/pasteboard/copy-paste-white-space.html [ Failure ]
-crbug.com/591099 editing/pasteboard/drag-image-to-contenteditable-in-iframe.html [ Failure Pass ]
-crbug.com/591099 editing/pasteboard/drag-list-item.html [ Failure Pass ]
 crbug.com/591099 editing/pasteboard/dragstart-contains-default-content.html [ Failure ]
-crbug.com/591099 editing/pasteboard/paste-noscript.html [ Failure Pass ]
 crbug.com/591099 editing/selection/4402375.html [ Failure ]
 crbug.com/591099 editing/selection/4776665.html [ Failure ]
 crbug.com/591099 editing/selection/4960137.html [ Failure ]
-crbug.com/591099 editing/selection/4975120.html [ Failure Pass ]
 crbug.com/591099 editing/selection/5232159.html [ Failure ]
 crbug.com/591099 editing/selection/5354455-2.html [ Failure ]
 crbug.com/591099 editing/selection/continuations-with-move-caret-to-boundary.html [ Failure ]
 crbug.com/591099 editing/selection/continuations-without-move-caret-to-boundary.html [ Failure ]
-crbug.com/591099 editing/selection/doubleclick-beside-cr-span.html [ Failure Pass ]
 crbug.com/591099 editing/selection/drag-in-iframe.html [ Failure ]
 crbug.com/591099 editing/selection/extend-inside-transforms-backward.html [ Failure ]
 crbug.com/591099 editing/selection/extend-inside-transforms-forward.html [ Failure ]
 crbug.com/591099 editing/selection/extend-selection-bidi.html [ Failure ]
-crbug.com/591099 editing/selection/home-end.html [ Pass Timeout ]
-crbug.com/591099 editing/selection/mixed-editability-10.html [ Failure Pass ]
 crbug.com/714962 editing/selection/modify_move/move-forward-after-line-break.html [ Failure ]
 crbug.com/591099 editing/selection/paint-hyphen.html [ Failure ]
-crbug.com/591099 editing/selection/programmatic-selection-on-mac-is-directionless.html [ Pass Timeout ]
-crbug.com/591099 editing/selection/skip-over-contenteditable.html [ Failure Pass ]
 crbug.com/591099 external/wpt/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_11.html [ Pass ]
 crbug.com/591099 external/wpt/WebCryptoAPI/derive_bits_keys/test_hkdf.https.html [ Timeout ]
 crbug.com/591099 external/wpt/WebCryptoAPI/generateKey/failures.worker.html [ Timeout ]
@@ -229,7 +214,6 @@
 crbug.com/591099 external/wpt/css/CSS2/normal-flow/root-box-001.xht [ Failure ]
 crbug.com/591099 external/wpt/css/CSS2/text/white-space-mixed-003.xht [ Pass ]
 crbug.com/591099 external/wpt/css/css-backgrounds/box-shadow-syntax-001.xht [ Failure ]
-crbug.com/591099 external/wpt/css/css-display/display-contents-details.html [ Crash ]
 crbug.com/591099 external/wpt/css/css-display/display-contents-dynamic-list-001-inline.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-display/display-contents-dynamic-list-001-none.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-display/display-contents-list-001.html [ Failure ]
@@ -237,6 +221,7 @@
 crbug.com/714962 external/wpt/css/css-fonts/font-features-across-space-1.html [ Pass ]
 crbug.com/714962 external/wpt/css/css-fonts/font-features-across-space-3.html [ Pass ]
 crbug.com/591099 external/wpt/css/css-fonts/font-variant-ligatures-11.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-grid/alignment/grid-row-axis-self-baseline-synthesized-001.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-grid/alignment/grid-self-alignment-non-static-positioned-items-009.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-grid/alignment/grid-self-alignment-non-static-positioned-items-010.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-grid/alignment/grid-self-alignment-non-static-positioned-items-011.html [ Failure ]
@@ -385,8 +370,6 @@
 crbug.com/591099 external/wpt/css/css-writing-modes/vertical-alignment-vlr-027.xht [ Failure ]
 crbug.com/591099 external/wpt/css/css-writing-modes/wm-propagation-body-006.xht [ Failure ]
 crbug.com/591099 external/wpt/css/geometry/interfaces.worker.html [ Pass ]
-crbug.com/591099 external/wpt/css/selectors/focus-visible-003-manual.html [ Pass Timeout ]
-crbug.com/591099 external/wpt/css/selectors/focus-visible-004-manual.html [ Pass Timeout ]
 crbug.com/591099 external/wpt/css/selectors/focus-within-004.html [ Pass ]
 crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-baseline-multi-item-vert-001b.html [ Pass ]
 crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-definite-sizes-002.html [ Failure ]
@@ -425,14 +408,15 @@
 crbug.com/591099 external/wpt/dom/ranges/Range-comparePoint.html [ Timeout ]
 crbug.com/591099 external/wpt/dom/ranges/Range-isPointInRange.html [ Timeout ]
 crbug.com/591099 external/wpt/dom/ranges/Range-set.html [ Timeout ]
-crbug.com/591099 external/wpt/editing/run/bold.html [ Pass Timeout ]
-crbug.com/591099 external/wpt/editing/run/formatblock.html [ Pass Timeout ]
-crbug.com/591099 external/wpt/editing/run/insertparagraph.html [ Pass Timeout ]
-crbug.com/591099 external/wpt/editing/run/justifycenter.html [ Pass Timeout ]
-crbug.com/591099 external/wpt/editing/run/justifyfull.html [ Pass Timeout ]
-crbug.com/591099 external/wpt/editing/run/justifyright.html [ Pass Timeout ]
-crbug.com/591099 external/wpt/editing/run/multitest.html [ Pass Timeout ]
+crbug.com/591099 external/wpt/editing/run/bold.html [ Pass ]
+crbug.com/591099 external/wpt/editing/run/formatblock.html [ Pass ]
+crbug.com/591099 external/wpt/editing/run/insertparagraph.html [ Pass ]
+crbug.com/591099 external/wpt/editing/run/justifycenter.html [ Pass ]
+crbug.com/591099 external/wpt/editing/run/justifyfull.html [ Pass ]
+crbug.com/591099 external/wpt/editing/run/justifyright.html [ Pass ]
+crbug.com/591099 external/wpt/editing/run/multitest.html [ Pass ]
 crbug.com/591099 external/wpt/encoding/textdecoder-fatal-single-byte.html [ Timeout ]
+crbug.com/591099 external/wpt/geolocation-API/PositionOptions.https.html [ Pass ]
 crbug.com/591099 external/wpt/html-media-capture/capture_audio_cancel-manual.html [ Failure ]
 crbug.com/591099 external/wpt/html-media-capture/capture_image_cancel-manual.html [ Failure ]
 crbug.com/591099 external/wpt/html-media-capture/capture_video_cancel-manual.html [ Failure ]
@@ -450,7 +434,6 @@
 crbug.com/591099 external/wpt/payment-request/payment-disabled-by-feature-policy.https.sub.html [ Pass ]
 crbug.com/591099 external/wpt/pointerevents/pointerevent_click_during_capture-manual.html [ Crash Timeout ]
 crbug.com/591099 external/wpt/quirks/line-height-calculation.html [ Failure ]
-crbug.com/591099 external/wpt/quirks/table-cell-width-calculation.html [ Pass ]
 crbug.com/591099 external/wpt/requestidlecallback/basic.html [ Pass ]
 crbug.com/591099 external/wpt/requestidlecallback/callback-exception.html [ Pass ]
 crbug.com/591099 external/wpt/requestidlecallback/callback-idle-periods.html [ Pass ]
@@ -458,6 +441,7 @@
 crbug.com/591099 external/wpt/requestidlecallback/callback-invoked.html [ Pass ]
 crbug.com/591099 external/wpt/requestidlecallback/cancel-invoked.html [ Pass ]
 crbug.com/591099 external/wpt/requestidlecallback/idlharness.html [ Pass ]
+crbug.com/591099 external/wpt/resource-timing/resource_timing.worker.html [ Pass ]
 crbug.com/591099 external/wpt/selection/collapse-30.html [ Timeout ]
 crbug.com/591099 external/wpt/service-workers/service-worker/registration-updateviacache.https.html [ Pass Timeout ]
 crbug.com/591099 external/wpt/shadow-dom/DocumentOrShadowRoot-prototype-elementFromPoint.html [ Failure ]
@@ -534,7 +518,7 @@
 crbug.com/591099 fast/css-grid-layout/grid-self-baseline-vertical-rl-05.html [ Failure ]
 crbug.com/591099 fast/css-grid-layout/grid-self-baseline-vertical-rl-06.html [ Failure ]
 crbug.com/591099 fast/css-grid-layout/grid-self-baseline-vertical-rl-07.html [ Failure ]
-crbug.com/591099 fast/css-grid-layout/grid-shorthand-get-set.html [ Timeout ]
+crbug.com/591099 fast/css-grid-layout/grid-shorthand-get-set.html [ Pass Timeout ]
 crbug.com/591099 fast/css-grid-layout/grid-template-columns-rows-computed-style-gaps-content-alignment.html [ Pass Timeout ]
 crbug.com/591099 fast/css-grid-layout/grid-template-shorthand-get-set.html [ Pass Timeout ]
 crbug.com/591099 fast/css-grid-layout/maximize-tracks-definite-indefinite-width.html [ Failure ]
@@ -566,7 +550,7 @@
 crbug.com/591099 fast/css/getComputedStyle/getComputedStyle-margin-auto.html [ Failure ]
 crbug.com/591099 fast/css/getComputedStyle/getComputedStyle-margin-percentage.html [ Failure ]
 crbug.com/714962 fast/css/hover-pseudo-element-quirks.html [ Failure ]
-crbug.com/591099 fast/css/import_with_baseurl.html [ Failure Pass ]
+crbug.com/591099 fast/css/import_with_baseurl.html [ Failure ]
 crbug.com/591099 fast/css/margin-top-bottom-dynamic.html [ Failure ]
 crbug.com/591099 fast/css/negative-text-indent-in-inline-block.html [ Failure ]
 crbug.com/591099 fast/css/opacity-float.html [ Pass ]
@@ -645,7 +629,6 @@
 crbug.com/591099 fast/inline/inline-box-background-repeat-y.html [ Failure ]
 crbug.com/591099 fast/inline/inline-box-background.html [ Failure ]
 crbug.com/591099 fast/inline/inline-focus-ring-under-absolute-enclosing-relative-div.html [ Failure ]
-crbug.com/591099 fast/inline/inline-focus-ring.html [ Failure Pass ]
 crbug.com/591099 fast/inline/inline-offsetLeft-relpos.html [ Failure ]
 crbug.com/591099 fast/inline/inline-with-empty-inline-children.html [ Failure ]
 crbug.com/591099 fast/inline/justify-emphasis-inline-box.html [ Failure ]
@@ -660,12 +643,10 @@
 crbug.com/591099 fast/lists/004.html [ Failure ]
 crbug.com/591099 fast/lists/009-vertical.html [ Failure ]
 crbug.com/591099 fast/lists/calc-width-with-space.html [ Failure ]
-crbug.com/591099 fast/lists/drag-into-marker.html [ Failure Pass ]
 crbug.com/591099 fast/lists/inline-before-content-after-list-marker.html [ Failure ]
 crbug.com/591099 fast/lists/list-color-change-no-layout.html [ Failure ]
 crbug.com/591099 fast/lists/list-item-line-height.html [ Failure ]
 crbug.com/591099 fast/lists/marker-before-empty-inline.html [ Failure ]
-crbug.com/826267 fast/lists/markers-in-selection.html [ Failure Pass ]
 crbug.com/591099 fast/masking/clip-path-selection.html [ Failure ]
 crbug.com/824918 fast/multicol/break-before-first-line-in-first-child.html [ Failure ]
 crbug.com/824918 fast/multicol/caret-range-anonymous-block-rtl.html [ Failure ]
@@ -688,7 +669,6 @@
 crbug.com/591099 fast/parser/entities-in-html.html [ Failure ]
 crbug.com/591099 fast/parser/entities-in-xhtml.xhtml [ Failure ]
 crbug.com/591099 fast/replaced/absolute-position-percentage-height.html [ Failure ]
-crbug.com/591099 fast/replaced/border-radius-clip.html [ Failure Pass ]
 crbug.com/591099 fast/replaced/preferred-widths.html [ Failure ]
 crbug.com/591099 fast/replaced/table-replaced-element.html [ Failure ]
 crbug.com/591099 fast/ruby/position-after.html [ Failure ]
@@ -706,9 +686,7 @@
 crbug.com/591099 fast/sub-pixel/sub-pixel-border-2.html [ Failure ]
 crbug.com/591099 fast/table/032.html [ Failure ]
 crbug.com/591099 fast/table/background-gradient-border-collapsed.html [ Failure ]
-crbug.com/591099 fast/table/border-collapsing/003-vertical.html [ Failure Pass ]
 crbug.com/591099 fast/table/border-collapsing/004-vertical.html [ Failure ]
-crbug.com/591099 fast/table/border-collapsing/border-collapsing-head-foot-vertical.html [ Failure Pass ]
 crbug.com/591099 fast/table/border-collapsing/composited-cell-collapsed-border.html [ Failure ]
 crbug.com/591099 fast/table/column-in-inline.html [ Failure ]
 crbug.com/591099 fast/table/dynamic-descendant-percentage-height.html [ Failure ]
@@ -813,7 +791,7 @@
 crbug.com/591099 fast/text/whitespace/inline-whitespace-wrapping-5.html [ Failure ]
 crbug.com/591099 fast/text/zero-width-characters-complex-script.html [ Failure ]
 crbug.com/591099 fast/text/zero-width-characters.html [ Failure ]
-crbug.com/591099 fast/writing-mode/Kusa-Makura-background-canvas.html [ Failure ]
+crbug.com/591099 fast/writing-mode/Kusa-Makura-background-canvas.html [ Failure Pass ]
 crbug.com/591099 fast/writing-mode/auto-sizing-orthogonal-flows.html [ Failure ]
 crbug.com/714962 fast/writing-mode/background-vertical-lr.html [ Failure ]
 crbug.com/591099 fast/writing-mode/background-vertical-rl.html [ Failure ]
@@ -825,21 +803,21 @@
 crbug.com/714962 fast/writing-mode/border-styles-vertical-rl.html [ Failure ]
 crbug.com/591099 fast/writing-mode/fieldsets.html [ Failure ]
 crbug.com/714962 fast/writing-mode/flipped-blocks-hit-test-line-edges.html [ Failure ]
-crbug.com/591099 fast/writing-mode/flipped-blocks-inline-map-local-to-container.html [ Failure ]
+crbug.com/591099 fast/writing-mode/flipped-blocks-inline-map-local-to-container.html [ Failure Pass ]
 crbug.com/714962 fast/writing-mode/japanese-lr-selection.html [ Failure ]
 crbug.com/714962 fast/writing-mode/japanese-rl-selection.html [ Failure ]
 crbug.com/591099 fast/writing-mode/percentage-height-orthogonal-writing-modes.html [ Failure ]
 crbug.com/591099 fast/writing-mode/percentage-margins-absolute-replaced.html [ Failure ]
 crbug.com/591099 fast/writing-mode/percentage-margins-absolute.html [ Failure ]
 crbug.com/591099 fast/writing-mode/table-percent-width-quirk.html [ Failure ]
-crbug.com/591099 fast/writing-mode/text-combine-compress.html [ Failure ]
+crbug.com/591099 fast/writing-mode/text-combine-compress.html [ Failure Pass ]
 crbug.com/591099 fast/writing-mode/text-combine-justify.html [ Failure ]
 crbug.com/591099 fast/writing-mode/text-combine-line-break.html [ Failure ]
 crbug.com/591099 fast/writing-mode/text-combine-various-fonts.html [ Failure ]
 crbug.com/591099 fast/writing-mode/vertical-baseline-alignment.html [ Failure ]
 crbug.com/591099 fast/writing-mode/vertical-font-fallback.html [ Failure ]
 crbug.com/591099 fast/writing-mode/vertical-lr-replaced-selection.html [ Failure ]
-crbug.com/591099 fast/xmlhttprequest/xmlhttprequest-recursive-sync-event.html [ Failure Pass ]
+crbug.com/591099 fullscreen/full-screen-line-boxes-crash.html [ Failure ]
 crbug.com/591099 fullscreen/full-screen-with-flex-item.html [ Failure ]
 crbug.com/591099 hittesting/border-hittest-inlineFlowBox.html [ Failure ]
 crbug.com/714962 hittesting/culled-inline.html [ Failure ]
@@ -849,7 +827,6 @@
 crbug.com/591099 html/details_summary/details-writing-mode-align-right.html [ Failure ]
 crbug.com/591099 html/details_summary/details-writing-mode.html [ Failure ]
 crbug.com/591099 html/dialog/fixpos-dialog-layout.html [ Failure ]
-crbug.com/591099 html/dialog/form-method-dialog.html [ Crash Pass ]
 crbug.com/591099 html/dialog/modal-dialog-in-table-column.html [ Failure ]
 crbug.com/591099 html/dialog/modal-dialog-scroll-height.html [ Failure ]
 crbug.com/591099 html/dialog/multiple-centered-dialogs.html [ Failure ]
@@ -859,7 +836,6 @@
 crbug.com/591099 http/tests/devtools/console/console-search.js [ Timeout ]
 crbug.com/591099 http/tests/devtools/console/console-viewport-control.js [ Failure ]
 crbug.com/591099 http/tests/devtools/editor/text-editor-ctrl-d-2.js [ Pass Timeout ]
-crbug.com/714962 http/tests/devtools/elements/edit/edit-dom-actions-4.js [ Crash Pass ]
 crbug.com/714962 http/tests/devtools/elements/inspect-pseudo-element.js [ Timeout ]
 crbug.com/591099 http/tests/devtools/persistence/persistence-merge-editor-tabs.js [ Failure ]
 crbug.com/591099 http/tests/devtools/text-autosizing-override.js [ Failure ]
@@ -886,6 +862,7 @@
 crbug.com/591099 http/tests/permissions/test-api-surface.html [ Pass ]
 crbug.com/591099 http/tests/security/cors-rfc1918/addressspace-document-appcache.https.html [ Crash Failure ]
 crbug.com/591099 http/tests/security/cors-rfc1918/addressspace-document-csp-appcache.https.html [ Crash Failure Pass ]
+crbug.com/591099 http/tests/security/cross-origin-session-storage-allowed.html [ Pass ]
 crbug.com/591099 http/tests/security/xssAuditor/block-does-not-leak-location.html [ Failure ]
 crbug.com/591099 http/tests/text-autosizing/narrow-iframe.html [ Failure ]
 crbug.com/591099 http/tests/text-autosizing/wide-iframe.html [ Failure ]
@@ -950,7 +927,6 @@
 crbug.com/591099 paint/invalidation/css-grid-layout/grid-element-change-rows-repaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/css-grid-layout/grid-item-change-column-repaint.html [ Failure ]
 crbug.com/591099 paint/invalidation/css-grid-layout/grid-item-z-index-change-repaint.html [ Failure ]
-crbug.com/591099 paint/invalidation/details-open-repaint.html [ Failure Pass ]
 crbug.com/591099 paint/invalidation/flexbox/align-content-change-keeping-geometry.html [ Failure ]
 crbug.com/714962 paint/invalidation/flexbox/align-content-change-no-flex.html [ Failure ]
 crbug.com/591099 paint/invalidation/flexbox/align-content-change.html [ Failure ]
@@ -1049,10 +1025,8 @@
 crbug.com/591099 paint/invalidation/scroll/fixed-with-border-under-composited-absolute-scrolled.html [ Crash ]
 crbug.com/591099 paint/invalidation/scroll/invalidate-after-composited-scroll-of-window.html [ Failure ]
 crbug.com/591099 paint/invalidation/scroll/line-in-scrolled-clipped-block.html [ Failure ]
-crbug.com/591099 paint/invalidation/selection/invalidation-rect-includes-newline-for-rtl.html [ Failure Pass ]
 crbug.com/591099 paint/invalidation/selection/invalidation-rect-includes-newline-for-vertical-lr.html [ Failure ]
 crbug.com/591099 paint/invalidation/selection/invalidation-rect-includes-newline-for-vertical-rl.html [ Failure ]
-crbug.com/591099 paint/invalidation/selection/invalidation-rect-includes-newline.html [ Failure Pass ]
 crbug.com/591099 paint/invalidation/selection/invalidation-rect-with-br-includes-newline.html [ Failure ]
 crbug.com/591099 paint/invalidation/selection/japanese-rl-selection-clear.html [ Failure ]
 crbug.com/591099 paint/invalidation/selection/japanese-rl-selection-repaint.html [ Failure ]
@@ -1062,7 +1036,6 @@
 crbug.com/591099 paint/invalidation/selection/selection-within-composited-scroller.html [ Failure ]
 crbug.com/714962 paint/invalidation/selection/text-selection-rect-in-overflow-2.html [ Failure ]
 crbug.com/714962 paint/invalidation/selection/text-selection-rect-in-overflow.html [ Failure ]
-crbug.com/591099 paint/invalidation/shadow-multiple.html [ Failure Pass ]
 crbug.com/591099 paint/invalidation/stacked-diacritics.html [ Failure ]
 crbug.com/591099 paint/invalidation/stacking-context-lost.html [ Failure ]
 crbug.com/591099 paint/invalidation/svg/add-background-property-on-root.html [ Failure ]
@@ -1134,11 +1107,7 @@
 crbug.com/591099 paint/pagination/pagination-change-clip-crash.html [ Failure ]
 crbug.com/708452 paint/selection/text-selection-inline-block-rtl.html [ Failure ]
 crbug.com/708452 paint/selection/text-selection-inline-block.html [ Failure ]
-crbug.com/591099 paint/selection/text-selection-newline-across-blocks.html [ Failure Pass ]
-crbug.com/591099 paint/selection/text-selection-newline-br.html [ Failure Pass ]
 crbug.com/591099 paint/selection/text-selection-newline-rtl-double-linebreak.html [ Failure ]
-crbug.com/591099 paint/selection/text-selection-newline-span-across-line.html [ Failure Pass ]
-crbug.com/591099 paint/selection/text-selection-newline-span.html [ Failure Pass ]
 crbug.com/591099 paint/selection/text-selection-newline-vertical-lr.html [ Failure ]
 crbug.com/591099 paint/text/selection-no-clip-text.html [ Failure ]
 crbug.com/714962 paint/text/text-match-highlights-big-line-height.html [ Failure ]
@@ -1149,9 +1118,10 @@
 crbug.com/591099 scrollbars/scrollbar-miss-mousemove-disabled.html [ Failure ]
 crbug.com/591099 shapedetection/detection-HTMLVideoElement.html [ Pass ]
 crbug.com/591099 storage/indexeddb/cursor-continue-validity.html [ Timeout ]
-crbug.com/591099 storage/indexeddb/index-cursor.html [ Timeout ]
+crbug.com/591099 storage/indexeddb/index-cursor.html [ Pass Timeout ]
 crbug.com/591099 storage/indexeddb/mozilla/indexes.html [ Timeout ]
 crbug.com/591099 storage/indexeddb/mozilla/test_objectStore_openKeyCursor.html [ Timeout ]
+crbug.com/591099 storage/indexeddb/objectstore-cursor.html [ Timeout ]
 crbug.com/591099 storage/indexeddb/objectstore-keycursor.html [ Pass Timeout ]
 crbug.com/714962 svg/as-background-image/svg-as-background-body.html [ Failure ]
 crbug.com/591099 svg/as-border-image/svg-as-border-image-2.html [ Failure ]
@@ -1215,10 +1185,11 @@
 crbug.com/591099 virtual/gpu-rasterization/images/feature-policy-max-downscaling-image-resize.html [ Failure ]
 crbug.com/591099 virtual/gpu-rasterization/images/feature-policy-max-downscaling-image-styles.html [ Failure ]
 crbug.com/591099 virtual/gpu-rasterization/images/feature-policy-max-downscaling-image.html [ Failure ]
+crbug.com/591099 virtual/gpu/fast/canvas/shadow-huge-blur.html [ Timeout ]
 crbug.com/591099 virtual/layout_ng/ [ Skip ]
 crbug.com/824918 virtual/layout_ng_experimental/ [ Skip ]
 crbug.com/714962 virtual/mouseevent_fractional/fast/events/event-on-culled_inline.html [ Failure ]
-crbug.com/714962 virtual/mouseevent_fractional/fast/events/mouse-down-on-pseudo-element-remove-crash.html [ Failure ]
+crbug.com/714962 virtual/mouseevent_fractional/fast/events/mouse-down-on-pseudo-element-remove-crash.html [ Failure Pass ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouse-relative-position.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/onclick-list-marker.html [ Failure ]
 crbug.com/591099 virtual/mouseevent_fractional/fast/events/select-element.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 037f103..159e028 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -290,7 +290,6 @@
 crbug.com/847274 external/wpt/css/css-contain/contain-paint-005.html [ Failure ]
 crbug.com/847274 external/wpt/css/css-contain/contain-paint-006.html [ Failure ]
 crbug.com/847274 external/wpt/css/css-contain/contain-paint-007.html [ Failure ]
-crbug.com/843329 external/wpt/css/css-contain/contain-size-005.html [ Failure ]
 
 # ====== Layout team owned tests to here ======
 
@@ -4823,7 +4822,6 @@
 crbug.com/847373 [ Mac Linux ] virtual/pwa-full-code-cache/http/tests/devtools/service-workers/service-workers-force-update-on-page-load.js [ Pass Timeout ]
 
 # Sheriff 2018-05-31
-crbug.com/848258 [ Win ] fast/gradients/unprefixed-repeating-linear-gradient.html [ Failure ]
 crbug.com/848281 [ Linux ] http/tests/security/cross-origin-session-storage-allowed.html [ Failure ]
 crbug.com/848354 [ Linux ] plugins/fullscreen-plugins-dont-reload.html [ Skip ]
 crbug.com/848398 [ Linux Mac ] http/tests/devtools/oopif/oopif-performance-cpu-profiles.js [ Pass Timeout Failure ]
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
index b22fd67..9307d89 100644
--- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
+++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -35501,6 +35501,90 @@
      {}
     ]
    ],
+   "css/css-contain/contain-size-006.html": [
+    [
+     "/css/css-contain/contain-size-006.html",
+     [
+      [
+       "/css/css-contain/reference/contain-size-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-contain/contain-size-007.html": [
+    [
+     "/css/css-contain/contain-size-007.html",
+     [
+      [
+       "/css/css-contain/reference/contain-size-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-contain/contain-size-008.html": [
+    [
+     "/css/css-contain/contain-size-008.html",
+     [
+      [
+       "/css/css-contain/reference/contain-size-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-contain/contain-size-009.html": [
+    [
+     "/css/css-contain/contain-size-009.html",
+     [
+      [
+       "/css/css-contain/reference/contain-size-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-contain/contain-size-010.html": [
+    [
+     "/css/css-contain/contain-size-010.html",
+     [
+      [
+       "/css/css-contain/reference/contain-size-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-contain/contain-size-011.html": [
+    [
+     "/css/css-contain/contain-size-011.html",
+     [
+      [
+       "/css/css-contain/reference/contain-paint-014-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-contain/contain-size-012.html": [
+    [
+     "/css/css-contain/contain-size-012.html",
+     [
+      [
+       "/css/css-contain/reference/contain-paint-014-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-contain/contain-size-breaks-001.html": [
     [
      "/css/css-contain/contain-size-breaks-001.html",
@@ -158590,6 +158674,11 @@
      {}
     ]
    ],
+   "priority-hints/resources/stylesheet.css": [
+    [
+     {}
+    ]
+   ],
    "quirks/OWNERS": [
     [
      {}
@@ -170665,6 +170754,11 @@
      {}
     ]
    ],
+   "workers/modules/resources/dynamic-import-remote-origin-script-worker.sub.js": [
+    [
+     {}
+    ]
+   ],
    "workers/modules/resources/dynamic-import-worker.js": [
     [
      {}
@@ -170690,6 +170784,11 @@
      {}
     ]
    ],
+   "workers/modules/resources/export-on-load-script.js.headers": [
+    [
+     {}
+    ]
+   ],
    "workers/modules/resources/export-on-static-import-script.js": [
     [
      {}
@@ -170715,6 +170814,11 @@
      {}
     ]
    ],
+   "workers/modules/resources/new-worker-window.html": [
+    [
+     {}
+    ]
+   ],
    "workers/modules/resources/post-message-on-load-worker.js": [
     [
      {}
@@ -170730,6 +170834,11 @@
      {}
     ]
    ],
+   "workers/modules/resources/static-import-remote-origin-script-worker.sub.js": [
+    [
+     {}
+    ]
+   ],
    "workers/modules/resources/static-import-worker.js": [
     [
      {}
@@ -231768,6 +231877,18 @@
      {}
     ]
    ],
+   "priority-hints/img-attr-named-constructor.tentative.html": [
+    [
+     "/priority-hints/img-attr-named-constructor.tentative.html",
+     {}
+    ]
+   ],
+   "priority-hints/link-attr.tentative.html": [
+    [
+     "/priority-hints/link-attr.tentative.html",
+     {}
+    ]
+   ],
    "quirks/blocks-ignore-line-height.html": [
     [
      "/quirks/blocks-ignore-line-height.html",
@@ -245080,12 +245201,6 @@
      {}
     ]
    ],
-   "touch-events/create-touch-touchlist.html": [
-    [
-     "/touch-events/create-touch-touchlist.html",
-     {}
-    ]
-   ],
    "touch-events/historical.html": [
     [
      "/touch-events/historical.html",
@@ -252188,6 +252303,12 @@
      {}
     ]
    ],
+   "workers/modules/dedicated-worker-import-csp.html": [
+    [
+     "/workers/modules/dedicated-worker-import-csp.html",
+     {}
+    ]
+   ],
    "workers/modules/dedicated-worker-import-failure.html": [
     [
      "/workers/modules/dedicated-worker-import-failure.html",
@@ -287016,11 +287137,11 @@
    "testharness"
   ],
   "css/css-backgrounds/background-332-expected.txt": [
-   "e4f961f67893badedf31e4603d776ccc3fc0c486",
+   "9116b1467a1530559acf12a5895ad488d2229baf",
    "support"
   ],
   "css/css-backgrounds/background-332.html": [
-   "ba3453739dee1dac840b3916b09cf161752d2f1d",
+   "5831da212a187d7f69864475f1fae96053d3a5a7",
    "testharness"
   ],
   "css/css-backgrounds/background-333.html": [
@@ -291635,6 +291756,34 @@
    "dfb0708ceeda5812a7434454f39a360d576597ea",
    "reftest"
   ],
+  "css/css-contain/contain-size-006.html": [
+   "2952e1bfc74d784dd2d16867ad95199d78c08efa",
+   "reftest"
+  ],
+  "css/css-contain/contain-size-007.html": [
+   "54d0f08274e3bb380d098fb5dbf9edeee67780f3",
+   "reftest"
+  ],
+  "css/css-contain/contain-size-008.html": [
+   "eaff3d8150332dffa1c70fc75efd66929f8adc79",
+   "reftest"
+  ],
+  "css/css-contain/contain-size-009.html": [
+   "727fa2cfad094c1a4e4785fb71cdc3c09a5d7f1b",
+   "reftest"
+  ],
+  "css/css-contain/contain-size-010.html": [
+   "1bfca9e97f9135b4f4b1b456f017a641c8b85a1c",
+   "reftest"
+  ],
+  "css/css-contain/contain-size-011.html": [
+   "c4b06e89428d47d9777610bb949714f70685dac5",
+   "reftest"
+  ],
+  "css/css-contain/contain-size-012.html": [
+   "ea98297a40836557325e66184854e7f7c3f82660",
+   "reftest"
+  ],
   "css/css-contain/contain-size-breaks-001.html": [
    "3a3c80029a6c126c584a21e2ff3b25e5459c32e8",
    "reftest"
@@ -379343,6 +379492,18 @@
    "f64f2ab5d0afa93e5adfa327e478936c0e295823",
    "support"
   ],
+  "priority-hints/img-attr-named-constructor.tentative.html": [
+   "7c30cb250fb854916a8bf87a4fd5c049ee1dcf5b",
+   "testharness"
+  ],
+  "priority-hints/link-attr.tentative.html": [
+   "39dd57841d9752f9220473c5de3a99d1c8ca18a1",
+   "testharness"
+  ],
+  "priority-hints/resources/stylesheet.css": [
+   "bb230110dd1cf4647e020d7172bc375e972c7b41",
+   "support"
+  ],
   "quirks/OWNERS": [
    "bec450f77cd9a3a2f278cc41724ae55f23b883a3",
    "support"
@@ -394303,12 +394464,8 @@
    "f5462722396e482446969be47192397dbb7dea41",
    "support"
   ],
-  "touch-events/create-touch-touchlist.html": [
-   "4872b365fc9e704fc873b411dd0ab60a509531ab",
-   "testharness"
-  ],
   "touch-events/historical.html": [
-   "0ccfb39ef6b094dadc6e6ac91de937b5180b2c84",
+   "2a748b6f1b66874fa613f3188125a04c95587976",
    "testharness"
   ],
   "touch-events/multi-touch-interactions.js": [
@@ -394912,7 +395069,7 @@
    "support"
   ],
   "url/README.md": [
-   "17ffb158bda35ef8b55f8f7f5f084df2e0651bfc",
+   "37bbc0fb70e865c45ff369a434de1a4a0a2bbc3e",
    "support"
   ],
   "url/a-element-origin-xhtml.xhtml": [
@@ -395552,11 +395709,11 @@
    "support"
   ],
   "web-animations/animation-model/animation-types/accumulation-per-property.html": [
-   "b26f3961d1913de731906ff0eed9a8548df7bbb2",
+   "40be406294368fc2eccb9a4e525c1f2bb40a3683",
    "testharness"
   ],
   "web-animations/animation-model/animation-types/addition-per-property.html": [
-   "c16ee3be3338bd5831ff3eab455cbf6943aa8d5b",
+   "0077ef18e19f57f2f6b1b312079a9c8d03bd1714",
    "testharness"
   ],
   "web-animations/animation-model/animation-types/discrete.html": [
@@ -395564,11 +395721,11 @@
    "testharness"
   ],
   "web-animations/animation-model/animation-types/interpolation-per-property.html": [
-   "2bcb2919b3034042d8a61d7af5de099a42386451",
+   "ab09cd8b77d05a1036f9976c3f0e92a6d9e183f3",
    "testharness"
   ],
   "web-animations/animation-model/animation-types/property-list.js": [
-   "3d3b60b27f20c298ccb7a3abb628054817f2b079",
+   "9416f470f1ac1d320bb4d46461938e85946439e2",
    "support"
   ],
   "web-animations/animation-model/animation-types/property-types.js": [
@@ -396016,7 +396173,7 @@
    "support"
   ],
   "web-nfc/nfc_push.https.html": [
-   "ada53723b88641d04566f76f7af366f45ec783e9",
+   "6db968d910771fe1f4bcc1378eb45d0568c89071",
    "testharness"
   ],
   "web-nfc/nfc_push_ArrayBuffer-manual.https-expected.txt": [
@@ -403407,6 +403564,10 @@
    "6bffa3be83d81e2faa93119e710e4fee93fb855e",
    "testharness"
   ],
+  "workers/modules/dedicated-worker-import-csp.html": [
+   "e889866185addcccf72828df7e75cec387cffab5",
+   "testharness"
+  ],
   "workers/modules/dedicated-worker-import-failure.html": [
    "63b2320a3ecf6133a3525574bf5a1d185d1f3aa7",
    "testharness"
@@ -403424,7 +403585,7 @@
    "testharness"
   ],
   "workers/modules/dedicated-worker-options-credentials.html": [
-   "1d6a1629f81d26efcd05bf1c7d40011609238f4f",
+   "f182ac364e933ce744b18c0ca6e03ae975a883a3",
    "testharness"
   ],
   "workers/modules/dedicated-worker-options-credentials.html.headers": [
@@ -403447,6 +403608,10 @@
    "9d64de6e63d110e6eff89a124e94cdec9d1802c2",
    "support"
   ],
+  "workers/modules/resources/dynamic-import-remote-origin-script-worker.sub.js": [
+   "bb2d9e0c4c641451640987cecb2f28eff3f8b518",
+   "support"
+  ],
   "workers/modules/resources/dynamic-import-worker.js": [
    "9db02105e0ee1300518ca70259d4a93671062219",
    "support"
@@ -403467,6 +403632,10 @@
    "fab13482dce29d3150f4eb06b1375c2610ab07f3",
    "support"
   ],
+  "workers/modules/resources/export-on-load-script.js.headers": [
+   "90d51a5e46cc58404dd5ec1e9e4e10934a6c0707",
+   "support"
+  ],
   "workers/modules/resources/export-on-static-import-script.js": [
    "fccc8ed2855b857d435d71382ed056f94be6e69d",
    "support"
@@ -403487,6 +403656,10 @@
    "7a6cdac13e91d27348e63310fc53443948a51aa6",
    "support"
   ],
+  "workers/modules/resources/new-worker-window.html": [
+   "46ae6f9fe4975ca75c0d6534710238e6140aaa4a",
+   "support"
+  ],
   "workers/modules/resources/post-message-on-load-worker.js": [
    "c67a79ade775435a67e5999d17e7cdda450c8e50",
    "support"
@@ -403499,6 +403672,10 @@
    "e8e1f0aedcc780aac742af01387dd151b10104bc",
    "support"
   ],
+  "workers/modules/resources/static-import-remote-origin-script-worker.sub.js": [
+   "2f0657e4a67fb1e5e5c6c8bb81fcc084a846ad71",
+   "support"
+  ],
   "workers/modules/resources/static-import-worker.js": [
    "4ccc3d3a7522527a5e62ec1adeb963220cfcd43c",
    "support"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/background-332-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/background-332-expected.txt
index 28192fd..a2b1457c2 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/background-332-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/background-332-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-FAIL background_specified_image assert_equals: background specified value for background-image expected "url(support/60x60-green.png)" but got "url(\"http://web-platform.test:8001/css/css-backgrounds/support/60x60-green.png\")"
+PASS Computed value for background-image after setting background shorthand
 PASS background_specified_position
 FAIL background_specified_size assert_equals: background specified value for background-size expected "10em 10em" but got "160px"
 FAIL background_specified_repeat assert_equals: background specified value for background-repeat expected "round round" but got "round"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/background-332.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/background-332.html
index 2621cb6..8a6d8d4 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/background-332.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/background-332.html
@@ -22,8 +22,8 @@
 
         test(function() {
             assert_equals(cs.getPropertyValue("background-image"),
-                "url(support/60x60-green.png)", "background specified value for background-image");
-        }, "background_specified_image");
+                'url("' + new URL("support/60x60-green.png", window.location.href).href + '")');
+        }, "Computed value for background-image after setting background shorthand");
 
         test(function() {
             assert_equals(cs.getPropertyValue("background-position"),
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-contain/contain-size-006.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-contain/contain-size-006.html
new file mode 100644
index 0000000..dc1773e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-contain/contain-size-006.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Containment Test: Size containment on table-cell</title>
+<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-size">
+<link rel="match" href="reference/contain-size-001-ref.html">
+<meta name=assert content="Size containment doesn't apply to table-cell elements.">
+<style>
+div {
+  display: table-cell;
+  contain: size;
+  overflow: hidden;
+}
+</style>
+
+<p>This test passes if you can see the word PASS below.</p>
+<div>PASS</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-contain/contain-size-007.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-contain/contain-size-007.html
new file mode 100644
index 0000000..9cf6d91
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-contain/contain-size-007.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Containment Test: Size containment on table-row-group</title>
+<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-size">
+<link rel="match" href="reference/contain-size-001-ref.html">
+<meta name=assert content="Size containment doesn't apply to table-row-group elements.">
+<style>
+div {
+  display: table-row-group;
+  contain: size;
+  overflow: hidden;
+}
+</style>
+
+<p>This test passes if you can see the word PASS below.</p>
+<div>PASS</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-contain/contain-size-008.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-contain/contain-size-008.html
new file mode 100644
index 0000000..07ba0e2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-contain/contain-size-008.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Containment Test: Size containment on table-header-group</title>
+<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-size">
+<link rel="match" href="reference/contain-size-001-ref.html">
+<meta name=assert content="Size containment doesn't apply to table-header-group elements.">
+<style>
+div {
+  display: table-header-group;
+  contain: size;
+  overflow: hidden;
+}
+</style>
+
+<p>This test passes if you can see the word PASS below.</p>
+<div>PASS</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-contain/contain-size-009.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-contain/contain-size-009.html
new file mode 100644
index 0000000..a3ca43c2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-contain/contain-size-009.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Containment Test: Size containment on table-footer-group</title>
+<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-size">
+<link rel="match" href="reference/contain-size-001-ref.html">
+<meta name=assert content="Size containment doesn't apply to table-footer-group elements.">
+<style>
+div {
+  display: table-footer-group;
+  contain: size;
+  overflow: hidden;
+}
+</style>
+
+<p>This test passes if you can see the word PASS below.</p>
+<div>PASS</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-contain/contain-size-010.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-contain/contain-size-010.html
new file mode 100644
index 0000000..a28110d0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-contain/contain-size-010.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Containment Test: Size containment on table-row</title>
+<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-size">
+<link rel="match" href="reference/contain-size-001-ref.html">
+<meta name=assert content="Size containment doesn't apply to table-row elements.">
+<style>
+div {
+  display: table-row;
+  contain: size;
+  overflow: hidden;
+}
+</style>
+
+<p>This test passes if you can see the word PASS below.</p>
+<div>PASS</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-contain/contain-size-011.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-contain/contain-size-011.html
new file mode 100644
index 0000000..0d8e3670
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-contain/contain-size-011.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Containment Test: Size containment on table-caption</title>
+<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-size">
+<link rel="match" href="reference/contain-paint-014-ref.html">
+<meta name=assert content="Size containment does apply to table-caption elements.">
+<style>
+div {
+  display: table-caption;
+  contain: size;
+  overflow: hidden;
+}
+</style>
+
+<p>This test passes if you can NOT see the word FAIL below.</p>
+<div>FAIL</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-contain/contain-size-012.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-contain/contain-size-012.html
new file mode 100644
index 0000000..af56444
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-contain/contain-size-012.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Containment Test: Size containment on table</title>
+<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-size">
+<link rel="match" href="reference/contain-paint-014-ref.html">
+<meta name=assert content="Size containment does apply to table elements.">
+<style>
+div {
+  display: table;
+  contain: size;
+  overflow: hidden;
+}
+</style>
+
+<p>This test passes if you can NOT see the word FAIL below.</p>
+<div>FAIL</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/priority-hints/img-attr-named-constructor.tentative.html b/third_party/WebKit/LayoutTests/external/wpt/priority-hints/img-attr-named-constructor.tentative.html
new file mode 100644
index 0000000..d9dd22a9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/priority-hints/img-attr-named-constructor.tentative.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>Priority Hints - Image element</title>
+<meta name="author" title="Dominic Farolino" href="mailto:domfarolino@gmail.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<img id=img1 src=/images/green.png importance=high>
+<img id=img2 src=/images/green.png importance=low>
+<img id=img3 src=/images/green.png importance=auto>
+<img id=img4 src=/images/green.png importance=xyz>
+<img id=img5 src=/images/green.png>
+
+<script>
+  test(() => {
+    assert_equals(img1.importance, "high", "high importance is a valid IDL value on the image element");
+    assert_equals(img2.importance, "low", "high importance is a valid IDL value on the image element");
+    assert_equals(img3.importance, "auto", "auto importance is a valid IDL value on the image element");
+    assert_equals(img4.importance, "auto", "invalid importance reflects as 'auto' IDL attribute on the image element");
+    assert_equals(img5.importance, "auto", "missing importance reflects as 'auto' IDL attribute on the image element");
+  }, "importance attribute on <img> elements should reflect valid IDL values");
+
+  const img = new Image();
+  assert_equals(img.importance, "auto");
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/priority-hints/link-attr.tentative.html b/third_party/WebKit/LayoutTests/external/wpt/priority-hints/link-attr.tentative.html
new file mode 100644
index 0000000..1c5aeb53
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/priority-hints/link-attr.tentative.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>Priority Hints - Link element</title>
+<meta name="author" title="Dominic Farolino" href="mailto:domfarolino@gmail.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<link id=link1 href=resources/stylesheet.css importance=high>
+<link id=link2 href=resources/stylesheet.css importance=low>
+<link id=link3 href=resources/stylesheet.css importance=auto>
+<link id=link4 href=resources/stylesheet.css importance=xyz>
+<link id=link5 href=resources/stylesheet.css>
+
+<script>
+  test(() => {
+    assert_equals(link1.importance, "high", "high importance is a valid IDL value on the link element");
+    assert_equals(link2.importance, "low", "high importance is a valid IDL value on the link element");
+    assert_equals(link3.importance, "auto", "auto importance is a valid IDL value on the link element");
+    assert_equals(link4.importance, "auto", "invalid importance reflects as 'auto' IDL attribute on the link element");
+    assert_equals(link5.importance, "auto", "missing importance reflects as 'auto' IDL attribute on the link element");
+  }, "importance attribute on <link> elements should reflect valid IDL values");
+
+  const link = document.createElement("link");
+  assert_equals(link.importance, "auto");
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/priority-hints/resources/stylesheet.css b/third_party/WebKit/LayoutTests/external/wpt/priority-hints/resources/stylesheet.css
new file mode 100644
index 0000000..9d9d772f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/priority-hints/resources/stylesheet.css
@@ -0,0 +1,3 @@
+body {
+  background-color: green;
+}
diff --git a/third_party/WebKit/LayoutTests/external/wpt/resources/idlharness.js b/third_party/WebKit/LayoutTests/external/wpt/resources/idlharness.js
index e83c4bf6..d005724 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/resources/idlharness.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/resources/idlharness.js
@@ -887,7 +887,7 @@
         return;
     }
 
-    if (type.sequence)
+    if (type.generic === "sequence")
     {
         assert_true(Array.isArray(value), "should be an Array");
         if (!value.length)
diff --git a/third_party/WebKit/LayoutTests/external/wpt/url/README.md b/third_party/WebKit/LayoutTests/external/wpt/url/README.md
index 34c35dc..667951d 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/url/README.md
+++ b/third_party/WebKit/LayoutTests/external/wpt/url/README.md
@@ -23,7 +23,7 @@
 
 In addition to testing that parsing `input` against `base` gives the result, a test harness for the
 `URL` constructor (or similar APIs) should additionally test the following pattern: if `failure` is
-true, parsing `about:blank` against `base` must give failure. This tests that the logic for
+true, parsing `about:blank` against `input` must give failure. This tests that the logic for
 converting base URLs into strings properly fails the whole parsing algorithm if the base URL cannot
 be parsed.
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property.html b/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property.html
index 870e489..420617d 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property.html
@@ -17,41 +17,43 @@
 <script>
 'use strict';
 
-for (const property in gCSSProperties) {
-  if (!isSupported(property)) {
-    continue;
-  }
-
-  const setupFunction = gCSSProperties[property].setup;
-  for (const animationType of gCSSProperties[property].types) {
-    let typeObject;
-    let animationTypeString;
-    if (typeof animationType === 'string') {
-      typeObject = types[animationType];
-      animationTypeString = animationType;
-    } else if (typeof animationType === 'object' &&
-               animationType.type && typeof animationType.type === 'string') {
-      typeObject = types[animationType.type];
-      animationTypeString = animationType.type;
+test(function() {
+  for (const property in gCSSProperties) {
+    if (!isSupported(property)) {
+      continue;
     }
 
-    // First, test that the animation type object has 'testAccumulation'.
-    // We use test() function here so that we can continue the remainder tests
-    // even if this test fails.
-    test(t => {
-      assert_own_property(typeObject, 'testAccumulation', animationTypeString +
-                          ' should have testAccumulation property');
-      assert_equals(typeof typeObject.testAccumulation, 'function',
-                    'testAccumulation method should be a function');
-    }, `${property} (type: ${animationTypeString}) has testAccumulation`
-       + ' function');
+    const setupFunction = gCSSProperties[property].setup;
+    for (const animationType of gCSSProperties[property].types) {
+      let typeObject;
+      let animationTypeString;
+      if (typeof animationType === 'string') {
+        typeObject = types[animationType];
+        animationTypeString = animationType;
+      } else if (typeof animationType === 'object' &&
+                 animationType.type && typeof animationType.type === 'string') {
+        typeObject = types[animationType.type];
+        animationTypeString = animationType.type;
+      }
 
-    if (typeObject.testAccumulation &&
-        typeof typeObject.testAccumulation === 'function') {
-      typeObject.testAccumulation(property,
-                              setupFunction,
-                              animationType.options);
+      // First, test that the animation type object has 'testAccumulation'.
+      // We use test() function here so that we can continue the remainder tests
+      // even if this test fails.
+      test(t => {
+        assert_own_property(typeObject, 'testAccumulation', animationTypeString +
+                            ' should have testAccumulation property');
+        assert_equals(typeof typeObject.testAccumulation, 'function',
+                      'testAccumulation method should be a function');
+      }, `${property} (type: ${animationTypeString}) has testAccumulation`
+         + ' function');
+
+      if (typeObject.testAccumulation &&
+          typeof typeObject.testAccumulation === 'function') {
+        typeObject.testAccumulation(property,
+                                setupFunction,
+                                animationType.options);
+      }
     }
   }
-}
+}, 'Setup');
 </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/addition-per-property.html b/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/addition-per-property.html
index 6125631..f17eeda 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/addition-per-property.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/addition-per-property.html
@@ -17,41 +17,43 @@
 <script>
 'use strict';
 
-for (const property in gCSSProperties) {
-  if (!isSupported(property)) {
-    continue;
-  }
-
-  const setupFunction = gCSSProperties[property].setup;
-  for (const animationType of gCSSProperties[property].types) {
-    let typeObject;
-    let animationTypeString;
-    if (typeof animationType === 'string') {
-      typeObject = types[animationType];
-      animationTypeString = animationType;
-    } else if (typeof animationType === 'object' &&
-               animationType.type && typeof animationType.type === 'string') {
-      typeObject = types[animationType.type];
-      animationTypeString = animationType.type;
+test(function() {
+  for (const property in gCSSProperties) {
+    if (!isSupported(property)) {
+      continue;
     }
 
-    // First, test that the animation type object has 'testAddition'.
-    // We use test() function here so that we can continue the remainder tests
-    // even if this test fails.
-    test(t => {
-      assert_own_property(typeObject, 'testAddition', animationTypeString +
-                          ' should have testAddition property');
-      assert_equals(typeof typeObject.testAddition, 'function',
-                    'testAddition method should be a function');
-    }, `${property} (type: ${animationTypeString}) has testAddition`
-       + ' function');
+    const setupFunction = gCSSProperties[property].setup;
+    for (const animationType of gCSSProperties[property].types) {
+      let typeObject;
+      let animationTypeString;
+      if (typeof animationType === 'string') {
+        typeObject = types[animationType];
+        animationTypeString = animationType;
+      } else if (typeof animationType === 'object' &&
+                 animationType.type && typeof animationType.type === 'string') {
+        typeObject = types[animationType.type];
+        animationTypeString = animationType.type;
+      }
 
-    if (typeObject.testAddition &&
-        typeof typeObject.testAddition === 'function') {
-      typeObject.testAddition(property,
-                              setupFunction,
-                              animationType.options);
+      // First, test that the animation type object has 'testAddition'.
+      // We use test() function here so that we can continue the remainder tests
+      // even if this test fails.
+      test(t => {
+        assert_own_property(typeObject, 'testAddition', animationTypeString +
+                            ' should have testAddition property');
+        assert_equals(typeof typeObject.testAddition, 'function',
+                      'testAddition method should be a function');
+      }, `${property} (type: ${animationTypeString}) has testAddition`
+         + ' function');
+
+      if (typeObject.testAddition &&
+          typeof typeObject.testAddition === 'function') {
+        typeObject.testAddition(property,
+                                setupFunction,
+                                animationType.options);
+      }
     }
   }
-}
+}, "Setup");
 </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property.html b/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property.html
index 2c335da..fe23d89 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property.html
@@ -17,41 +17,43 @@
 <script>
 'use strict';
 
-for (const property in gCSSProperties) {
-  if (!isSupported(property)) {
-    continue;
-  }
-
-  const setupFunction = gCSSProperties[property].setup;
-  for (const animationType of gCSSProperties[property].types) {
-    let typeObject;
-    let animationTypeString;
-    if (typeof animationType === 'string') {
-      typeObject = types[animationType];
-      animationTypeString = animationType;
-    } else if (typeof animationType === 'object' &&
-               animationType.type && typeof animationType.type === 'string') {
-      typeObject = types[animationType.type];
-      animationTypeString = animationType.type;
+test(function() {
+  for (const property in gCSSProperties) {
+    if (!isSupported(property)) {
+      continue;
     }
 
-    // First, test that the animation type object has 'testInterpolation'.
-    // We use test() function() here so that we can continue the remainder tests
-    // even if this test fails.
-    test(t => {
-      assert_own_property(typeObject, 'testInterpolation', animationTypeString +
-                          ' should have testInterpolation property');
-      assert_equals(typeof typeObject.testInterpolation, 'function',
-                    'testInterpolation method should be a function');
-    }, `${property} (type: ${animationTypeString}) has testInterpolation`
-       + ' function');
+    const setupFunction = gCSSProperties[property].setup;
+    for (const animationType of gCSSProperties[property].types) {
+      let typeObject;
+      let animationTypeString;
+      if (typeof animationType === 'string') {
+        typeObject = types[animationType];
+        animationTypeString = animationType;
+      } else if (typeof animationType === 'object' &&
+                 animationType.type && typeof animationType.type === 'string') {
+        typeObject = types[animationType.type];
+        animationTypeString = animationType.type;
+      }
 
-    if (typeObject.testInterpolation &&
-        typeof typeObject.testInterpolation === 'function') {
-      typeObject.testInterpolation(property,
-                                   setupFunction,
-                                   animationType.options);
+      // First, test that the animation type object has 'testInterpolation'.
+      // We use test() function() here so that we can continue the remainder tests
+      // even if this test fails.
+      test(t => {
+        assert_own_property(typeObject, 'testInterpolation', animationTypeString +
+                            ' should have testInterpolation property');
+        assert_equals(typeof typeObject.testInterpolation, 'function',
+                      'testInterpolation method should be a function');
+      }, `${property} (type: ${animationTypeString}) has testInterpolation`
+         + ' function');
+
+      if (typeObject.testInterpolation &&
+          typeof typeObject.testInterpolation === 'function') {
+        typeObject.testInterpolation(property,
+                                     setupFunction,
+                                     animationType.options);
+      }
     }
   }
-}
+}, 'Setup');
 </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/property-list.js b/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/property-list.js
index ec0c33f..f0b2a64 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/property-list.js
+++ b/third_party/WebKit/LayoutTests/external/wpt/web-animations/animation-model/animation-types/property-list.js
@@ -1556,6 +1556,7 @@
 
 function isSupported(property) {
   const testKeyframe = new TestKeyframe(propertyToIDL(property));
+  assert_not_equals(window.KeyframeEffect, undefined, 'window.KeyframeEffect');
   try {
     // Since TestKeyframe returns 'undefined' for |property|,
     // the KeyframeEffect constructor will throw
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-nfc/nfc_push.https.html b/third_party/WebKit/LayoutTests/external/wpt/web-nfc/nfc_push.https.html
index 19ee5d3..cb3cf761 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/web-nfc/nfc_push.https.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/web-nfc/nfc_push.https.html
@@ -137,21 +137,25 @@
 promise_test(() => {
   return new Promise((resolve,reject) => {
     let iframe = document.createElement('iframe');
-    iframe.srcdoc = '<script>' +
-                    '  window.onmessage = message => {' +
-                    '    if (message.data === "Ready") {' +
-                    '      let onSuccess = () => { parent.postMessage("Failure", "*"); };' +
-                    '      let onError = error => {' +
-                    '        if (error.name == "SecurityError") {' +
-                    '          parent.postMessage("Success", "*");' +
-                    '        } else {' +
-                    '          parent.postMessage("Failure", "*");' +
-                    '        }' +
-                    '      };' +
-                    '      navigator.nfc.push("Test").then(onSuccess, onError);' +
-                    '    }' +
-                    '  };' +
-                    '<\/script>';
+    iframe.srcdoc = `<script>
+                      window.onmessage = message => {
+                        if (message.data === "Ready") {
+                          let onSuccess = () => { parent.postMessage("Failure", "*"); };
+                          let onError = error => {
+                            if (error.name == "SecurityError") {
+                              parent.postMessage("Success", "*");
+                            } else {
+                              parent.postMessage("Failure", "*");
+                            }
+                          };
+                          try {
+                            navigator.nfc.push("Test").then(onSuccess, onError);
+                          } catch(e) {
+                            parent.postMessage("Failure", "*");
+                          }
+                        }
+                      };
+                    <\/script>`;
     iframe.onload = () => iframe.contentWindow.postMessage('Ready', '*');
     document.body.appendChild(iframe);
     window.onmessage = message => {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/workers/modules/dedicated-worker-import-csp.html b/third_party/WebKit/LayoutTests/external/wpt/workers/modules/dedicated-worker-import-csp.html
new file mode 100644
index 0000000..02b88e8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/workers/modules/dedicated-worker-import-csp.html
@@ -0,0 +1,114 @@
+<!DOCTYPE html>
+<title>DedicatedWorker: CSP for ES Modules</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+
+async function openWindow(url) {
+  const win = window.open(url, '_blank');
+  add_result_callback(() => win.close());
+  const msg_event = await new Promise(resolve => window.onmessage = resolve);
+  assert_equals(msg_event.data, 'LOADED');
+  return win;
+}
+
+function import_csp_test(
+    cspHeader, scriptURL, expectedImportedModules, description) {
+  const windowURL =
+      `resources/new-worker-window.html?pipe=header(` +
+          `Content-Security-Policy, ${cspHeader})`;
+  promise_test(async () => {
+    // Open a window that has the given CSP header.
+    const win = await openWindow(windowURL);
+    // Ask the window to start a dedicated worker. The worker inherits the
+    // window's CSP header.
+    // https://w3c.github.io/webappsec-csp/#initialize-global-object-csp
+    win.postMessage(scriptURL, '*');
+    const msg_event = await new Promise(resolve => window.onmessage = resolve);
+    assert_array_equals(msg_event.data, expectedImportedModules);
+  }, description);
+}
+
+// Tests for static import.
+//
+// Static import should obey the worker-src directive and the script-src
+// directive. If the both directives are specified, the worker-src directive
+// should be prioritized.
+//
+// Step 1: "If the result of executing 6.6.1.11 Get the effective directive for
+// request on request is "worker-src", and policy contains a directive whose
+// name is "worker-src", return "Allowed"."
+// "Note: If worker-src is present, we’ll defer to it when handling worker
+// requests."
+// https://w3c.github.io/webappsec-csp/#script-src-pre-request
+
+import_csp_test(
+    "worker-src 'self' 'unsafe-inline'",
+    "static-import-remote-origin-script-worker.sub.js",
+    ['ERROR'],
+    "worker-src 'self' directive should disallow cross origin static import.");
+
+import_csp_test(
+    "worker-src * 'unsafe-inline'",
+    "static-import-remote-origin-script-worker.sub.js",
+    ["export-on-load-script.js"],
+    "worker-src * directive should allow cross origin static import.")
+
+import_csp_test(
+    "script-src 'self' 'unsafe-inline'",
+    "static-import-remote-origin-script-worker.sub.js",
+    ['ERROR'],
+    "script-src 'self' directive should disallow cross origin static import.");
+
+import_csp_test(
+    "script-src * 'unsafe-inline'",
+    "static-import-remote-origin-script-worker.sub.js",
+    ["export-on-load-script.js"],
+    "script-src * directive should allow cross origin static import.")
+
+import_csp_test(
+    "worker-src *; script-src 'self' 'unsafe-inline'",
+    "static-import-remote-origin-script-worker.sub.js",
+    ["export-on-load-script.js"],
+    "worker-src * directive should override script-src 'self' directive and " +
+        "allow cross origin static import.");
+
+import_csp_test(
+    "worker-src 'self'; script-src * 'unsafe-inline'",
+    "static-import-remote-origin-script-worker.sub.js",
+    ['ERROR'],
+    "worker-src 'self' directive should override script-src * directive and " +
+        "disallow cross origin static import.");
+
+// Tests for dynamic import.
+//
+// Dynamic import should obey the script-src directive instead of the worker-src
+// directive according to the specs:
+//
+// Dynamic import has the "script" destination.
+// Step 2.4: "Fetch a module script graph given url, ..., "script", ..."
+// https://html.spec.whatwg.org/multipage/webappapis.html#hostimportmoduledynamically(referencingscriptormodule,-specifier,-promisecapability)
+//
+// The "script" destination should obey the script-src CSP directive.
+// Step 2: "If request's destination is script-like:"
+// https://w3c.github.io/webappsec-csp/#script-src-pre-request
+
+import_csp_test(
+    "script-src 'self' 'unsafe-inline'",
+    "dynamic-import-remote-origin-script-worker.sub.js",
+    ['ERROR'],
+    "script-src 'self' directive should disallow cross origin dynamic import.");
+
+import_csp_test(
+    "script-src * 'unsafe-inline'",
+    "dynamic-import-remote-origin-script-worker.sub.js",
+    ["export-on-load-script.js"],
+    "script-src * directive should allow cross origin dynamic import.")
+
+import_csp_test(
+    "worker-src 'self' 'unsafe-inline'",
+    "dynamic-import-remote-origin-script-worker.sub.js",
+    ["export-on-load-script.js"],
+    "worker-src 'self' directive should not take effect on dynamic import.");
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/workers/modules/resources/dynamic-import-remote-origin-script-worker.sub.js b/third_party/WebKit/LayoutTests/external/wpt/workers/modules/resources/dynamic-import-remote-origin-script-worker.sub.js
new file mode 100644
index 0000000..0937086
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/workers/modules/resources/dynamic-import-remote-origin-script-worker.sub.js
@@ -0,0 +1,4 @@
+// Import a remote origin script.
+import('https://{{domains[www1]}}:{{ports[https][0]}}/workers/modules/resources/export-on-load-script.js')
+  .then(module => postMessage(module.importedModules))
+  .catch(e => postMessage(['ERROR']));
diff --git a/third_party/WebKit/LayoutTests/external/wpt/workers/modules/resources/export-on-load-script.js.headers b/third_party/WebKit/LayoutTests/external/wpt/workers/modules/resources/export-on-load-script.js.headers
new file mode 100644
index 0000000..cb762eff
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/workers/modules/resources/export-on-load-script.js.headers
@@ -0,0 +1 @@
+Access-Control-Allow-Origin: *
diff --git a/third_party/WebKit/LayoutTests/external/wpt/workers/modules/resources/new-worker-window.html b/third_party/WebKit/LayoutTests/external/wpt/workers/modules/resources/new-worker-window.html
new file mode 100644
index 0000000..5ae1507
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/workers/modules/resources/new-worker-window.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<title>DedicatedWorker: new Worker()</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+let worker;
+
+// Creates a new dedicated worker for a given script url.
+window.onmessage = e => {
+  worker = new Worker(e.data, { type: 'module' });
+  worker.onmessage = msg => window.opener.postMessage(msg.data, '*');
+  worker.onerror = err => window.opener.postMessage(['ERROR'], '*');
+};
+window.opener.postMessage('LOADED', '*');
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/workers/modules/resources/static-import-remote-origin-script-worker.sub.js b/third_party/WebKit/LayoutTests/external/wpt/workers/modules/resources/static-import-remote-origin-script-worker.sub.js
new file mode 100644
index 0000000..00ef44e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/workers/modules/resources/static-import-remote-origin-script-worker.sub.js
@@ -0,0 +1,3 @@
+// Import a remote origin script.
+import * as module from 'https://{{domains[www1]}}:{{ports[https][0]}}/workers/modules/resources/export-on-load-script.js';
+postMessage(module.importedModules);
diff --git a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-getCapabilities.html b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-getCapabilities.html
index 5ed957a..45c4879fb 100644
--- a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-getCapabilities.html
+++ b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-getCapabilities.html
@@ -6,7 +6,7 @@
   return navigator.mediaDevices.getUserMedia({audio: true})
       .then(function(stream) {
     var capabilities = stream.getAudioTracks()[0].getCapabilities();
-    assert_equals(Object.keys(capabilities).length, 5);
+    assert_equals(Object.keys(capabilities).length, 6);
     assert_true(capabilities.hasOwnProperty('deviceId'));
     assert_true(capabilities.hasOwnProperty('groupId'));
     verifyAudioProcessingProperties(capabilities, true);
@@ -28,7 +28,7 @@
 test(function() {
   var stream = (new AudioContext()).createMediaStreamDestination().stream;
   var capabilities = stream.getAudioTracks()[0].getCapabilities();
-  assert_equals(Object.keys(capabilities).length, 4);
+  assert_equals(Object.keys(capabilities).length, 5);
   assert_true(capabilities.hasOwnProperty('deviceId'));
   verifyAudioProcessingProperties(capabilities, false);
 }, 'getCapabilities() support for audio track associated with a MediaStreamAudioDestinationNode.');
@@ -52,7 +52,7 @@
     var stream = video.captureStream();
     var audioCapabilities = stream.getAudioTracks()[0].getCapabilities();
     var videoCapabilities = stream.getVideoTracks()[0].getCapabilities();
-    assert_equals(Object.keys(audioCapabilities).length, 4);
+    assert_equals(Object.keys(audioCapabilities).length, 5);
     assert_true(audioCapabilities.hasOwnProperty('deviceId'));
     verifyAudioProcessingProperties(audioCapabilities, false);
     assert_greater_than(Object.keys(videoCapabilities).length, 0);
@@ -74,7 +74,7 @@
     var remoteStream = callee.getRemoteStreams()[0];
     var audioCapabilities = remoteStream.getAudioTracks()[0].getCapabilities();
     var videoCapabilities = remoteStream.getVideoTracks()[0].getCapabilities();
-    assert_equals(Object.keys(audioCapabilities).length, 4);
+    assert_equals(Object.keys(audioCapabilities).length, 5);
     assert_true(audioCapabilities.hasOwnProperty('deviceId'));
     verifyAudioProcessingProperties(audioCapabilities, false);
     assert_greater_than(Object.keys(videoCapabilities).length, 0);
@@ -98,6 +98,19 @@
 function verifyAudioProcessingProperties(capabilities, is_get_user_media) {
   assert_true(capabilities.hasOwnProperty('echoCancellation'));
   assert_equals(Object.keys(capabilities.echoCancellation).length, is_get_user_media ? 2 : 1);
+
+  assert_true(capabilities.hasOwnProperty('echoCancellationType'));
+  var ec_type_length = Object.keys(capabilities.echoCancellationType).length;
+  if (is_get_user_media) {
+    assert_true(ec_type_length == 1 || ec_type_length == 2);
+    if (ec_type_length == 1) {
+      assert_true(capabilities.echoCancellationType[0] == 'browser');
+    } else {
+      assert_true(capabilities.echoCancellationType[0] == 'browser' || capabilities.echoCancellationType[1] == 'browser');
+    }
+  } else {
+    assert_equals(ec_type_length, 0);
+  }
   assert_true(capabilities.hasOwnProperty('autoGainControl'));
   assert_equals(Object.keys(capabilities.autoGainControl).length, is_get_user_media ? 2 : 1);
   assert_true(capabilities.hasOwnProperty('noiseSuppression'));
@@ -130,4 +143,4 @@
     assert_less_than_equal(capabilities.frameRate.min, capabilities.frameRate.max);
   }
 }
-</script>
\ No newline at end of file
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/peerconnection/RTCRtpSender-getParameters.html b/third_party/WebKit/LayoutTests/fast/peerconnection/RTCRtpSender-getParameters.html
index 2f62db9..fbce385 100644
--- a/third_party/WebKit/LayoutTests/fast/peerconnection/RTCRtpSender-getParameters.html
+++ b/third_party/WebKit/LayoutTests/fast/peerconnection/RTCRtpSender-getParameters.html
@@ -55,7 +55,7 @@
 
 function verifySenderParameters(parameters, kind) {
   assert_exists(parameters, "transactionId", "transactionId");
-  assert_not_exists(parameters, "rtcp", "unimplemented rtcp");
+  assert_exists(parameters, "rtcp", "rtcp");
 
   assert_greater_than(parameters.codecs.length, 0);
   for(let codec of parameters.codecs) {
diff --git a/third_party/WebKit/LayoutTests/fast/peerconnection/RTCRtpSender-setParameters-expected.txt b/third_party/WebKit/LayoutTests/fast/peerconnection/RTCRtpSender-setParameters-expected.txt
index 15f17d37..4f12111 100644
--- a/third_party/WebKit/LayoutTests/fast/peerconnection/RTCRtpSender-setParameters-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/peerconnection/RTCRtpSender-setParameters-expected.txt
@@ -33,7 +33,6 @@
 PASS video setParameters() check for headerExtensions.id removed
 PASS video setParameters() check for headerExtensions.encrypted modification
 PASS video setParameters() check for headerExtensions.encrypted removed
-PASS video setParameters() check for rtcp removed
 PASS video setParameters() check for rtcp.cname modification
 PASS video setParameters() check for rtcp.reducedSize modification
 PASS audio setParameters() check for transactionId modification
@@ -66,7 +65,6 @@
 PASS audio setParameters() check for headerExtensions.id removed
 PASS audio setParameters() check for headerExtensions.encrypted modification
 PASS audio setParameters() check for headerExtensions.encrypted removed
-PASS audio setParameters() check for rtcp removed
 PASS audio setParameters() check for rtcp.cname modification
 PASS audio setParameters() check for rtcp.reducedSize modification
 PASS setParameters() set low maxBitrate value
diff --git a/third_party/WebKit/LayoutTests/fast/peerconnection/RTCRtpSender-setParameters.html b/third_party/WebKit/LayoutTests/fast/peerconnection/RTCRtpSender-setParameters.html
index 31c6dd95..c96cf31 100644
--- a/third_party/WebKit/LayoutTests/fast/peerconnection/RTCRtpSender-setParameters.html
+++ b/third_party/WebKit/LayoutTests/fast/peerconnection/RTCRtpSender-setParameters.html
@@ -81,7 +81,7 @@
     new DOMException(
       "getParameters() needs to be called before setParameters().",
       "InvalidStateError"),
-    videoSender.setParameters({}));
+    videoSender.setParameters({ rtcp: {}}));
 }, 'setParameters() fails without getParameters()');
 
 /**
@@ -257,19 +257,12 @@
     },
   },
   {
-    name: "rtcp removed",
-    transform: (p) => { delete p.rtcp; },
-    check: (p) => { return p.rtcp !== undefined; },
-  },
-  {
     name: "rtcp.cname modification",
     transform: (p) => { p.rtcp.cname = "cname"; },
-    check: (p) => { return p.rtcp !== undefined; },
   },
   {
     name: "rtcp.reducedSize modification",
     transform: (p) => { p.rtcp.reducedSize = !p.rtcp.reducedSize; },
-    check: (p) => { return p.rtcp !== undefined; },
   },
 ];
 
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/deleting/delete-br-013-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/deleting/delete-br-013-expected.txt
index 20fe098..3b1fcb2 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/deleting/delete-br-013-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/deleting/delete-br-013-expected.txt
@@ -10,7 +10,7 @@
       LayoutBlockFlow {DIV} at (0,40) size 784x20
         LayoutText {#text} at (0,0) size 315x19
           text run at (0,0) width 315: "The test passes if the text below is still underlined."
-      LayoutNGBlockFlow (anonymous) at (0,60) size 769x20
+      LayoutBlockFlow (anonymous) at (0,60) size 784x20
         LayoutBR {BR} at (0,0) size 0x19
       LayoutBlockFlow {DIV} at (0,80) size 784x20
         LayoutInline {SPAN} at (0,0) size 191x19
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/deleting/merge-no-br-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/deleting/merge-no-br-expected.txt
index 2c4c97f..6feadbe 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/deleting/merge-no-br-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/deleting/merge-no-br-expected.txt
@@ -4,9 +4,9 @@
 layer at (0,0) size 800x600
   LayoutView at (0,0) size 800x600
 layer at (0,0) size 800x600
-  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
-    LayoutNGBlockFlow {BODY} at (8,8) size 784x584
-      LayoutNGBlockFlow {P} at (0,0) size 784x40
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
+      LayoutBlockFlow {P} at (0,0) size 784x40
         LayoutText {#text} at (0,0) size 780x39
           text run at (0,0) width 780: "This places the caret before the 'T' in 'Two' and Deletes. 'One' and 'Two' should be merged but the blocks containing 'Three'"
           text run at (0,20) width 230: "and 'Four' should remain untouched."
@@ -18,7 +18,7 @@
           LayoutBlockFlow {DIV} at (19,19) size 698x42 [border: (3px solid #000000)]
             LayoutText {#text} at (11,11) size 37x19
               text run at (11,11) width 37: "Three"
-          LayoutNGBlockFlow (anonymous) at (11,69) size 699x20
+          LayoutBlockFlow (anonymous) at (11,69) size 714x20
             LayoutText {#text} at (0,0) size 30x19
               text run at (0,0) width 30: "Four"
 caret: position 3 of child 0 {#text} of child 1 {DIV} of child 2 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/execCommand/5142012-1-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/execCommand/5142012-1-expected.txt
index 7195519..a9d8474 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/execCommand/5142012-1-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/execCommand/5142012-1-expected.txt
@@ -16,7 +16,7 @@
           LayoutInline {SPAN} at (0,0) size 12x19
             LayoutText {#text} at (23,0) size 12x19
               text run at (23,0) width 12: "lo"
-        LayoutNGBlockFlow (anonymous) at (0,20) size 769x0
+        LayoutBlockFlow (anonymous) at (0,20) size 784x0
         LayoutBlockFlow {DIV} at (0,20) size 784x20
           LayoutInline {SPAN} at (0,0) size 15x19
             LayoutText {#text} at (0,0) size 15x19
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/input/caret-read-only-after-editable-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/input/caret-read-only-after-editable-expected.txt
index b92ba89..d8167e5 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/input/caret-read-only-after-editable-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/input/caret-read-only-after-editable-expected.txt
@@ -3,7 +3,7 @@
 layer at (0,0) size 800x86
   LayoutBlockFlow {HTML} at (0,0) size 800x86
     LayoutBlockFlow {BODY} at (8,8) size 784x70
-      LayoutNGBlockFlow (anonymous) at (0,0) size 769x20
+      LayoutBlockFlow (anonymous) at (0,0) size 784x20
         LayoutText {#text} at (0,0) size 303x19
           text run at (0,0) width 303: "Test passes if caret is visible after text is entered."
       LayoutBlockFlow {DIV} at (0,20) size 784x50 [border: (1px solid #000000)]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/inserting/5002441-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/inserting/5002441-expected.txt
index 561065f..0a600952 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/inserting/5002441-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/inserting/5002441-expected.txt
@@ -1,13 +1,13 @@
 layer at (0,0) size 800x600
   LayoutView at (0,0) size 800x600
 layer at (0,0) size 800x600
-  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
-    LayoutNGBlockFlow {BODY} at (8,8) size 784x584
-      LayoutNGBlockFlow {P} at (0,0) size 784x20
+  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 521x19
           text run at (0,0) width 521: "This tests for a bug where spaces couldn't be inserted before signatures and replies."
       LayoutBlockFlow {DIV} at (0,36) size 784x40
-        LayoutNGBlockFlow (anonymous) at (0,0) size 769x20
+        LayoutBlockFlow (anonymous) at (0,0) size 784x20
           LayoutText {#text} at (0,0) size 4x19
             text run at (0,0) width 4: " "
           LayoutBR {BR} at (4,15) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/inserting/5058163-1-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/inserting/5058163-1-expected.txt
index 00e4bce..e1231a0 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/inserting/5058163-1-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/inserting/5058163-1-expected.txt
@@ -1,9 +1,9 @@
 layer at (0,0) size 800x600
   LayoutView at (0,0) size 800x600
 layer at (0,0) size 800x600
-  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
-    LayoutNGBlockFlow {BODY} at (8,8) size 784x584
-      LayoutNGBlockFlow {P} at (0,0) size 784x20
+  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 759x19
           text run at (0,0) width 759: "This tests for a bug where hitting return between two tables would add a new paragraph at the end of the editable region."
       LayoutBlockFlow {DIV} at (0,36) size 784x96
@@ -13,7 +13,7 @@
               LayoutTableCell {TD} at (2,2) size 469x22 [r=0 c=0 rs=1 cs=1]
                 LayoutText {#text} at (1,1) size 467x19
                   text run at (1,1) width 467: "There should be two empty paragraphs after this table and before the next."
-        LayoutNGBlockFlow (anonymous) at (0,28) size 769x40
+        LayoutBlockFlow (anonymous) at (0,28) size 784x40
           LayoutBR {BR} at (0,0) size 0x19
           LayoutBR {BR} at (0,20) size 0x19
         LayoutTable {TABLE} at (0,68) size 276x28 [border: (1px solid #AAAAAA)]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/inserting/5510537-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/inserting/5510537-expected.txt
index 65c0e46..3cf612c 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/inserting/5510537-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/inserting/5510537-expected.txt
@@ -9,7 +9,7 @@
           text run at (639,0) width 134: "The test has passed if"
           text run at (0,20) width 400: "there are no empty lines (quoted or unquoted) in the box below."
       LayoutBlockFlow {DIV} at (0,56) size 784x100
-        LayoutNGBlockFlow (anonymous) at (0,0) size 784x20
+        LayoutBlockFlow (anonymous) at (0,0) size 784x20
           LayoutText {#text} at (0,0) size 59x19
             text run at (0,0) width 59: "unquoted"
           LayoutBR {BR} at (59,15) size 0x0
@@ -21,7 +21,7 @@
           LayoutBlockFlow {DIV} at (12,0) size 772x20
             LayoutText {#text} at (0,0) size 96x19
               text run at (0,0) width 96: "quote level one"
-        LayoutNGBlockFlow (anonymous) at (0,60) size 784x20
+        LayoutBlockFlow (anonymous) at (0,60) size 784x20
           LayoutText {#text} at (0,0) size 59x19
             text run at (0,0) width 59: "unquoted"
           LayoutBR {BR} at (59,15) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/inserting/6703873-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/inserting/6703873-expected.txt
index 948a65f..0681da5 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/inserting/6703873-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/inserting/6703873-expected.txt
@@ -14,7 +14,7 @@
             LayoutText {#text} at (0,0) size 43x19
               text run at (0,0) width 43: "quoted"
           LayoutBlockFlow {DIV} at (12,20) size 772x0
-        LayoutNGBlockFlow (anonymous) at (0,20) size 784x20
+        LayoutBlockFlow (anonymous) at (0,20) size 784x20
           LayoutText {#text} at (0,0) size 59x19
             text run at (0,0) width 59: "unquoted"
           LayoutBR {BR} at (59,15) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/inserting/break-blockquote-after-delete-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/inserting/break-blockquote-after-delete-expected.txt
index 2708bf95..01bb25b 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/inserting/break-blockquote-after-delete-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/inserting/break-blockquote-after-delete-expected.txt
@@ -3,7 +3,7 @@
 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 769x40
+      LayoutBlockFlow (anonymous) at (0,0) size 784x40
         LayoutText {#text} at (0,0) size 759x19
           text run at (0,0) width 759: "This tests that the blockquote's typing style doesn't remain after breaking the blockquote and typing in the unquoted area."
         LayoutBR {BR} at (759,15) size 0x0
@@ -12,7 +12,7 @@
         LayoutBlockFlow {BLOCKQUOTE} at (0,0) size 784x20 [color=#0000FF] [border: none (2px solid #0000FF)]
           LayoutText {#text} at (12,0) size 27x19
             text run at (12,0) width 27: "blue"
-        LayoutNGBlockFlow (anonymous) at (0,20) size 784x20
+        LayoutBlockFlow (anonymous) at (0,20) size 784x20
           LayoutText {#text} at (0,0) size 34x19
             text run at (0,0) width 34: "black"
           LayoutBR {BR} at (34,15) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/inserting/insert-3800346-fix-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/inserting/insert-3800346-fix-expected.txt
index fc55f49..6991776 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/inserting/insert-3800346-fix-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/inserting/insert-3800346-fix-expected.txt
@@ -18,17 +18,17 @@
 layer at (0,0) size 800x600
   LayoutView at (0,0) size 800x600
 layer at (0,0) size 800x600
-  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
-    LayoutNGBlockFlow {BODY} at (8,8) size 784x584
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
       LayoutBlockFlow {DIV} at (0,0) size 784x244 [border: (2px solid #FF0000)]
         LayoutBlockFlow {DIV} at (14,14) size 756x216
-          LayoutNGBlockFlow (anonymous) at (0,0) size 741x28
+          LayoutBlockFlow (anonymous) at (0,0) size 756x28
             LayoutText {#text} at (0,0) size 40x27
               text run at (0,0) width 40: "Test"
           LayoutBlockFlow {BLOCKQUOTE} at (40,52) size 676x28
             LayoutText {#text} at (0,0) size 40x27
               text run at (0,0) width 40: "Test"
-          LayoutNGBlockFlow (anonymous) at (0,104) size 741x112
+          LayoutBlockFlow (anonymous) at (0,104) size 756x112
             LayoutBR {BR} at (0,0) size 0x27
             LayoutBR {BR} at (0,28) size 0x27
             LayoutBR {BR} at (0,56) size 0x27
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/5006779-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/5006779-expected.txt
index aaaddd2..4e9bfb8 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/5006779-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/5006779-expected.txt
@@ -8,7 +8,7 @@
           text run at (0,0) width 421: "This tests copying/pasting less than a paragraph of quoted content. "
           text run at (421,0) width 176: "It should not appear quoted."
       LayoutBlockFlow {DIV} at (0,36) size 784x100
-        LayoutNGBlockFlow (anonymous) at (0,0) size 769x40
+        LayoutBlockFlow (anonymous) at (0,0) size 784x40
           LayoutText {#text} at (0,0) size 20x19
             text run at (0,0) width 20: "On"
           LayoutBR {BR} at (20,15) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/5071074-2-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/5071074-2-expected.txt
index e8f45b4..14f51bf 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/5071074-2-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/5071074-2-expected.txt
@@ -1,13 +1,13 @@
 layer at (0,0) size 800x600
   LayoutView at (0,0) size 800x600
 layer at (0,0) size 800x600
-  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
-    LayoutNGBlockFlow {BODY} at (8,8) size 784x584
-      LayoutNGBlockFlow {P} at (0,0) size 784x20
+  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 541x19
           text run at (0,0) width 541: "This tests for a bug where copied links wouldn't be pasted as links at certain positions."
       LayoutBlockFlow {DIV} at (0,36) size 784x40
-        LayoutNGBlockFlow (anonymous) at (0,0) size 769x20
+        LayoutBlockFlow (anonymous) at (0,0) size 784x20
           LayoutText {#text} at (0,0) size 159x19
             text run at (0,0) width 159: "This should be plain text."
         LayoutBlockFlow {DIV} at (0,20) size 784x20
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/5134759-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/5134759-expected.txt
index f7ff962..f88fe39 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/5134759-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/5134759-expected.txt
@@ -19,5 +19,5 @@
           LayoutInline {SPAN} at (0,0) size 44x19
             LayoutText {#text} at (39,0) size 44x19
               text run at (39,0) width 44: "World!"
-        LayoutNGBlockFlow (anonymous) at (0,20) size 784x0
+        LayoutBlockFlow (anonymous) at (0,20) size 784x0
 caret: position 6 of child 0 {#text} of child 1 {SPAN} of child 0 {DIV} of child 2 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/7955-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/7955-expected.txt
index 87a4c6e..0562bab 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/7955-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/7955-expected.txt
@@ -1,12 +1,12 @@
 layer at (0,0) size 800x600
   LayoutView at (0,0) size 800x600
 layer at (0,0) size 800x600
-  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
-    LayoutNGBlockFlow {BODY} at (8,8) size 784x584
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
       LayoutBlockFlow {DIV} at (0,0) size 784x40
         LayoutBlockFlow {DIV} at (0,0) size 784x20
           LayoutText {#text} at (0,0) size 21x19
             text run at (0,0) width 21: "foo"
-        LayoutNGBlockFlow (anonymous) at (0,20) size 769x20
+        LayoutBlockFlow (anonymous) at (0,20) size 784x20
           LayoutText {#text} at (0,0) size 20x19
             text run at (0,0) width 20: "bar"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/copy-standalone-image-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/copy-standalone-image-expected.txt
index 84f5f8f1..0df47b0e 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/copy-standalone-image-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/copy-standalone-image-expected.txt
@@ -13,7 +13,7 @@
         LayoutText {#text} at (0,0) size 757x39
           text run at (0,0) width 757: "To perform this test manually, click once in the image frame, choose Edit -> Copy then click in the red box and paste the"
           text run at (0,20) width 355: "image. If the image pastes successfully the test is passed."
-      LayoutNGBlockFlow (anonymous) at (0,92) size 769x154
+      LayoutBlockFlow (anonymous) at (0,92) size 784x154
         LayoutText {#text} at (0,0) size 0x0
       LayoutBlockFlow {DIV} at (0,246) size 784x131 [border: (2px solid #FF0000)]
         LayoutImage {IMG} at (14,14) size 76x103
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/drag-selected-image-to-contenteditable-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/drag-selected-image-to-contenteditable-expected.txt
index 6429f3c..6405735 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/drag-selected-image-to-contenteditable-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/drag-selected-image-to-contenteditable-expected.txt
@@ -9,7 +9,7 @@
     LayoutBlockFlow {BODY} at (0,0) size 800x584
       LayoutBlockFlow {DIV} at (0,0) size 302x122 [border: (1px solid #000000)]
         LayoutImage {IMG} at (1,1) size 76x103
-      LayoutNGBlockFlow (anonymous) at (0,122) size 785x103
+      LayoutBlockFlow (anonymous) at (0,122) size 800x103
         LayoutImage {IMG} at (0,0) size 76x103
         LayoutText {#text} at (0,0) size 0x0
       LayoutBlockFlow {UL} at (0,241) size 800x20
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/paste-line-endings-002-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/paste-line-endings-002-expected.txt
index 169c874..a311c366 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/paste-line-endings-002-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/paste-line-endings-002-expected.txt
@@ -37,7 +37,7 @@
             text run at (0,55) width 715: "one\" and \"line two\". The insertion point must be at the start of \"line two\"."
       LayoutBlockFlow {DIV} at (0,234) size 784x60
         LayoutBlockFlow {DIV} at (0,0) size 784x60 [border: (2px solid #FF0000)]
-          LayoutNGBlockFlow (anonymous) at (2,2) size 765x28
+          LayoutBlockFlow (anonymous) at (2,2) size 780x28
             LayoutText {#text} at (0,0) size 78x27
               text run at (0,0) width 78: "line one"
           LayoutBlockFlow {DIV} at (2,30) size 780x28
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/paste-line-endings-004-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/paste-line-endings-004-expected.txt
index 1ff6592..d21911e 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/paste-line-endings-004-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/paste-line-endings-004-expected.txt
@@ -38,7 +38,7 @@
       LayoutBlockFlow {DIV} at (0,234) size 784x60
         LayoutBlockFlow {DIV} at (0,0) size 784x60 [border: (2px solid #FF0000)]
           LayoutBlockFlow {DIV} at (2,2) size 780x56
-            LayoutNGBlockFlow (anonymous) at (0,0) size 765x28
+            LayoutBlockFlow (anonymous) at (0,0) size 780x28
               LayoutText {#text} at (0,0) size 78x27
                 text run at (0,0) width 78: "line one"
             LayoutBlockFlow {DIV} at (0,28) size 780x28
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/paste-line-endings-005-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/paste-line-endings-005-expected.txt
index a6f71bf..3c6172d 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/paste-line-endings-005-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/paste-line-endings-005-expected.txt
@@ -41,7 +41,7 @@
             LayoutBlockFlow {DIV} at (0,0) size 780x28
               LayoutText {#text} at (0,0) size 78x27
                 text run at (0,0) width 78: "line one"
-            LayoutNGBlockFlow (anonymous) at (0,28) size 765x28
+            LayoutBlockFlow (anonymous) at (0,28) size 780x28
               LayoutText {#text} at (0,0) size 79x27
                 text run at (0,0) width 79: "line two"
 caret: position 0 of child 1 {#text} of child 1 {DIV} of child 1 {DIV} of child 3 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/paste-text-016-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/paste-text-016-expected.txt
index c844021..21d070c0 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/paste-text-016-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/paste-text-016-expected.txt
@@ -18,9 +18,9 @@
 layer at (0,0) size 800x600
   LayoutView at (0,0) size 800x600
 layer at (0,0) size 800x600
-  LayoutNGBlockFlow {HTML} 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 769x40
+      LayoutBlockFlow (anonymous) at (0,0) size 784x40
         LayoutText {#text} at (0,0) size 96x19
           text run at (0,0) width 96: "Fixes this bug: "
         LayoutInline {A} at (0,0) size 167x19 [color=#0000EE]
@@ -47,11 +47,11 @@
             LayoutText {#text} at (0,0) size 128x27
               text run at (0,0) width 128: "Another line."
           LayoutBlockFlow {P} at (14,126) size 756x0
-          LayoutNGBlockFlow (anonymous) at (14,126) size 741x28
+          LayoutBlockFlow (anonymous) at (14,126) size 756x28
             LayoutText {#text} at (0,0) size 6x27
               text run at (0,0) width 6: " "
           LayoutBlockFlow {P} at (14,154) size 756x0
-          LayoutNGBlockFlow (anonymous) at (14,154) size 741x28
+          LayoutBlockFlow (anonymous) at (14,154) size 756x28
             LayoutText {#text} at (0,0) size 6x27
               text run at (0,0) width 6: " "
           LayoutBlockFlow {P} at (14,182) size 756x28
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/pasting-tabs-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/pasting-tabs-expected.txt
index 7eb0ccdd6..fdefc5b 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/pasting-tabs-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/pasting-tabs-expected.txt
@@ -13,7 +13,7 @@
           text run at (0,0) width 647: "This tests copying plain text with tabs and pasting it into an editable region using paste and match tyle. "
           text run at (647,0) width 119: "The tabs should be"
           text run at (0,20) width 65: "preserved."
-      LayoutNGBlockFlow (anonymous) at (0,56) size 769x36
+      LayoutBlockFlow (anonymous) at (0,56) size 784x36
         LayoutText {#text} at (0,0) size 0x0
       LayoutBlockFlow {DIV} at (0,92) size 784x20
         LayoutText {#text} at (0,0) size 38x19
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/quirks-mode-br-1-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/quirks-mode-br-1-expected.txt
index f321d81..67f15f6e 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/quirks-mode-br-1-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/pasteboard/quirks-mode-br-1-expected.txt
@@ -18,6 +18,6 @@
             text run at (0,0) width 370: "The test should add a single blank line after this paragraph."
           LayoutInline {SPAN} at (0,0) size 0x19
           LayoutBR {BR} at (370,15) size 0x0
-        LayoutNGBlockFlow (anonymous) at (0,20) size 784x20
+        LayoutBlockFlow (anonymous) at (0,20) size 784x20
           LayoutBR {BR} at (0,0) size 0x19
 caret: position 0 of child 1 {BR} of child 2 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-ltr-2-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-ltr-2-expected.txt
index 6dac5d7..3851db0 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-ltr-2-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-ltr-2-expected.txt
@@ -10,7 +10,7 @@
       LayoutBlockFlow {DIV} at (0,56) size 205.59x45 [border: (1px solid #000000)]
         LayoutText {#text} at (122,11) size 73x22
           text run at (122,11) width 73: "WebKit2"
-      LayoutNGBlockFlow (anonymous) at (0,101) size 784x20
+      LayoutBlockFlow (anonymous) at (0,101) size 784x20
         LayoutText {#text} at (0,0) size 38x19
           text run at (0,0) width 38: "PASS"
         LayoutBR {BR} at (38,0) size 0x19
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-ltr-2-left-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-ltr-2-left-expected.txt
index ea24986..421d03f 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-ltr-2-left-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-ltr-2-left-expected.txt
@@ -10,7 +10,7 @@
       LayoutBlockFlow {DIV} at (0,56) size 205.59x45 [border: (1px solid #000000)]
         LayoutText {#text} at (122,11) size 73x22
           text run at (122,11) width 73: "WebKit2"
-      LayoutNGBlockFlow (anonymous) at (0,101) size 784x20
+      LayoutBlockFlow (anonymous) at (0,101) size 784x20
         LayoutText {#text} at (0,0) size 38x19
           text run at (0,0) width 38: "PASS"
         LayoutBR {BR} at (38,0) size 0x19
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-ltr-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-ltr-expected.txt
index 45549aae3..37aea02 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-ltr-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-ltr-expected.txt
@@ -10,7 +10,7 @@
       LayoutBlockFlow {DIV} at (0,56) size 205.59x45 [border: (1px solid #000000)]
         LayoutText {#text} at (11,11) size 72x22
           text run at (11,11) width 72: "WebKit2"
-      LayoutNGBlockFlow (anonymous) at (0,101) size 784x20
+      LayoutBlockFlow (anonymous) at (0,101) size 784x20
         LayoutText {#text} at (0,0) size 38x19
           text run at (0,0) width 38: "PASS"
         LayoutBR {BR} at (38,0) size 0x19
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-ltr-right-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-ltr-right-expected.txt
index 2d17645..136db77 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-ltr-right-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-ltr-right-expected.txt
@@ -10,7 +10,7 @@
       LayoutBlockFlow {DIV} at (0,56) size 205.59x45 [border: (1px solid #000000)]
         LayoutText {#text} at (11,11) size 72x22
           text run at (11,11) width 72: "WebKit2"
-      LayoutNGBlockFlow (anonymous) at (0,101) size 784x20
+      LayoutBlockFlow (anonymous) at (0,101) size 784x20
         LayoutText {#text} at (0,0) size 38x19
           text run at (0,0) width 38: "PASS"
         LayoutBR {BR} at (38,0) size 0x19
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-rtl-2-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-rtl-2-expected.txt
index da314141..3abd2e03 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-rtl-2-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-rtl-2-expected.txt
@@ -10,7 +10,7 @@
       LayoutBlockFlow {DIV} at (0,56) size 205.59x45 [border: (1px solid #000000)]
         LayoutText {#text} at (11,11) size 66x22
           text run at (11,11) width 66 RTL: "\x{5E9}\x{5D3}\x{5D4} \x{5D1}\x{5D5}\x{5E8}"
-      LayoutNGBlockFlow (anonymous) at (0,101) size 784x20
+      LayoutBlockFlow (anonymous) at (0,101) size 784x20
         LayoutText {#text} at (0,0) size 38x19
           text run at (0,0) width 38: "PASS"
         LayoutBR {BR} at (38,0) size 0x19
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-rtl-2-left-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-rtl-2-left-expected.txt
index 39d4eea..ae792187 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-rtl-2-left-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-rtl-2-left-expected.txt
@@ -10,7 +10,7 @@
       LayoutBlockFlow {DIV} at (0,56) size 205.59x45 [border: (1px solid #000000)]
         LayoutText {#text} at (11,11) size 66x22
           text run at (11,11) width 66 RTL: "\x{5E9}\x{5D3}\x{5D4} \x{5D1}\x{5D5}\x{5E8}"
-      LayoutNGBlockFlow (anonymous) at (0,101) size 784x20
+      LayoutBlockFlow (anonymous) at (0,101) size 784x20
         LayoutText {#text} at (0,0) size 38x19
           text run at (0,0) width 38: "PASS"
         LayoutBR {BR} at (38,0) size 0x19
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-rtl-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-rtl-expected.txt
index 2395bef..370e6d8 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-rtl-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-rtl-expected.txt
@@ -10,7 +10,7 @@
       LayoutBlockFlow {DIV} at (0,56) size 205.59x45 [border: (1px solid #000000)]
         LayoutText {#text} at (128,11) size 67x22
           text run at (128,11) width 67 RTL: "\x{5E9}\x{5D3}\x{5D4} \x{5D1}\x{5D5}\x{5E8}"
-      LayoutNGBlockFlow (anonymous) at (0,101) size 784x20
+      LayoutBlockFlow (anonymous) at (0,101) size 784x20
         LayoutText {#text} at (0,0) size 38x19
           text run at (0,0) width 38: "PASS"
         LayoutBR {BR} at (38,0) size 0x19
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-rtl-right-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-rtl-right-expected.txt
index b549561..69209f2 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-rtl-right-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/caret-rtl-right-expected.txt
@@ -10,7 +10,7 @@
       LayoutBlockFlow {DIV} at (0,56) size 205.59x45 [border: (1px solid #000000)]
         LayoutText {#text} at (128,11) size 67x22
           text run at (128,11) width 67 RTL: "\x{5E9}\x{5D3}\x{5D4} \x{5D1}\x{5D5}\x{5E8}"
-      LayoutNGBlockFlow (anonymous) at (0,101) size 784x20
+      LayoutBlockFlow (anonymous) at (0,101) size 784x20
         LayoutText {#text} at (0,0) size 38x19
           text run at (0,0) width 38: "PASS"
         LayoutBR {BR} at (38,0) size 0x19
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 d58473e..7e4119b 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 d92c265..38bd011 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,13 +3,13 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x579
-      LayoutNGBlockFlow (anonymous) at (0,0) size 769x60
-        LayoutText {#text} at (0,0) size 759x59
+      LayoutBlockFlow (anonymous) at (0,0) size 784x60
+        LayoutText {#text} at (0,0) size 781x59
           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 117: "programmatically. "
           text run at (117,20) width 186: "We do this as a convenience. "
-          text run at (303,20) width 419: "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."
+          text run at (303,20) width 478: "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."
       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/previous-line-position-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/previous-line-position-expected.txt
index 11cbe017..e737aa15 100644
--- 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
@@ -26,7 +26,7 @@
           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
+        LayoutBlockFlow (anonymous) at (1,21) size 782x40
           LayoutBR {BR} at (0,0) size 0x19
           LayoutText {#text} at (0,20) size 21x19
             text run at (0,20) width 21: "test"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/select-box-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/select-box-expected.txt
index 81f032cc..e7d6a63 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/select-box-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/select-box-expected.txt
@@ -63,7 +63,7 @@
           LayoutText {#text} at (0,0) size 71x19
             text run at (0,0) width 71: "select box: "
           LayoutMenuList {SELECT} at (71,0) size 29x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
-            LayoutNGBlockFlow (anonymous) at (1,1) size 27x18
+            LayoutBlockFlow (anonymous) at (1,1) size 27x18
               LayoutText (anonymous) at (4,1) size 7x16
                 text run at (4,1) width 7: "1"
           LayoutText {#text} at (100,0) size 66x19
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/select-element-paragraph-boundary-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/select-element-paragraph-boundary-expected.txt
index 5410e868..4bc1b8e2 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/select-element-paragraph-boundary-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/select-element-paragraph-boundary-expected.txt
@@ -12,7 +12,7 @@
           text run at (0,20) width 67: "select box."
       LayoutBlockFlow {DIV} at (0,56) size 784x20
         LayoutMenuList {SELECT} at (0,0) size 29x20 [bgcolor=#C0C0C0] [border: (1px solid #A9A9A9)]
-          LayoutNGBlockFlow (anonymous) at (1,1) size 27x18
+          LayoutBlockFlow (anonymous) at (1,1) size 27x18
             LayoutText (anonymous) at (4,1) size 7x16
               text run at (4,1) width 7: "1"
 caret: position 1 of child 0 {SELECT} of child 2 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/wrapped-line-caret-1-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/wrapped-line-caret-1-expected.txt
index f9d806c..b2cc74e 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/wrapped-line-caret-1-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/wrapped-line-caret-1-expected.txt
@@ -3,7 +3,7 @@
 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 769x20
+      LayoutBlockFlow (anonymous) at (0,0) size 784x20
         LayoutInline {SPAN} at (0,0) size 368x19
           LayoutText {#text} at (0,0) size 368x19
             text run at (0,0) width 368: "This test passes if the caret is at the start of the second line."
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/wrapped-line-caret-2-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/wrapped-line-caret-2-expected.txt
index 40f02382..b11db0d 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/wrapped-line-caret-2-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/wrapped-line-caret-2-expected.txt
@@ -3,7 +3,7 @@
 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 769x20
+      LayoutBlockFlow (anonymous) at (0,0) size 784x20
         LayoutInline {SPAN} at (0,0) size 368x19
           LayoutText {#text} at (0,0) size 368x19
             text run at (0,0) width 368: "This test passes if the caret is at the start of the second line."
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/style/5228141-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/style/5228141-expected.txt
index a8c0873..f216196 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/style/5228141-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/style/5228141-expected.txt
@@ -1,13 +1,13 @@
 layer at (0,0) size 800x600
   LayoutView at (0,0) size 800x600
 layer at (0,0) size 800x600
-  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
-    LayoutNGBlockFlow {BODY} at (8,8) size 784x584
-      LayoutNGBlockFlow {P} at (0,0) size 784x20
+  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 611x19
           text run at (0,0) width 611: "This tests for a bug where style would not be applied to a selection that ended just after an image."
       LayoutBlockFlow {DIV} at (0,36) size 784x128
-        LayoutNGBlockFlow (anonymous) at (0,0) size 769x20
+        LayoutBlockFlow (anonymous) at (0,0) size 784x20
           LayoutInline {B} at (0,0) size 0x19
             LayoutBR {BR} at (0,0) size 0x19
         LayoutBlockFlow {DIV} at (0,20) size 784x108
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/style/block-styles-007-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/style/block-styles-007-expected.txt
index f48eaca..1d9e3779 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/style/block-styles-007-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/style/block-styles-007-expected.txt
@@ -23,14 +23,14 @@
             text run at (422,27) width 327: " font loses bold style after pasting"
             text run at (0,55) width 384: "next to existing text and pressing return"
         LayoutBlockFlow {DIV} at (14,113) size 756x110
-          LayoutNGBlockFlow (anonymous) at (0,0) size 741x55
+          LayoutBlockFlow (anonymous) at (0,0) size 756x55
             LayoutText {#text} at (0,0) size 189x26
               text run at (0,0) width 189: "Expected Results: "
             LayoutBR {BR} at (189,21) size 0x0
             LayoutText {#text} at (0,27) size 436x27
               text run at (0,27) width 436: "Should see this content in the red box below:"
           LayoutBlockFlow {DIV} at (0,55) size 756x55
-            LayoutNGBlockFlow (anonymous) at (0,0) size 741x28
+            LayoutBlockFlow (anonymous) at (0,0) size 756x28
               LayoutText {#text} at (0,0) size 32x27
                 text run at (0,0) width 32: "foo"
             LayoutBlockFlow {DIV} at (0,28) size 756x27
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/unsupported-content/list-delete-001-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/unsupported-content/list-delete-001-expected.txt
index 4bf844c..7c345f4 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/unsupported-content/list-delete-001-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/unsupported-content/list-delete-001-expected.txt
@@ -29,7 +29,7 @@
               text run at (0,48) width 99: "For this test: "
           LayoutText {#text} at (99,48) size 168x20
             text run at (99,48) width 168: "Select and delete a list."
-        LayoutNGBlockFlow (anonymous) at (20,89) size 729x21
+        LayoutBlockFlow (anonymous) at (20,89) size 744x21
           LayoutBR {BR} at (0,0) size 0x20
         LayoutBlockFlow {DIV} at (20,110) size 744x111
           LayoutText {#text} at (0,0) size 189x26
@@ -50,7 +50,7 @@
           text run at (2,2) width 107: "beforeafter"
       LayoutBlockFlow {DIV} at (0,293) size 784x108
         LayoutBlockFlow {DIV} at (0,0) size 784x108 [border: (2px solid #FF0000)]
-          LayoutNGBlockFlow (anonymous) at (2,2) size 765x28
+          LayoutBlockFlow (anonymous) at (2,2) size 780x28
             LayoutText {#text} at (0,0) size 62x27
               text run at (0,0) width 62: "before"
           LayoutBlockFlow {UL} at (2,54) size 780x28
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/unsupported-content/list-delete-003-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/unsupported-content/list-delete-003-expected.txt
index cc745e4..9444393 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/unsupported-content/list-delete-003-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/unsupported-content/list-delete-003-expected.txt
@@ -29,7 +29,7 @@
               text run at (0,48) width 99: "For this test: "
           LayoutText {#text} at (99,48) size 392x20
             text run at (99,48) width 392: "Select and delete a list and some surrounding content."
-        LayoutNGBlockFlow (anonymous) at (20,89) size 729x21
+        LayoutBlockFlow (anonymous) at (20,89) size 744x21
           LayoutBR {BR} at (0,0) size 0x20
         LayoutBlockFlow {DIV} at (20,110) size 744x111
           LayoutText {#text} at (0,0) size 189x26
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/unsupported-content/list-type-after-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/unsupported-content/list-type-after-expected.txt
index 2ed4b22..f2960e3f 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/unsupported-content/list-type-after-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/unsupported-content/list-type-after-expected.txt
@@ -26,7 +26,7 @@
               text run at (0,48) width 99: "For this test: "
           LayoutText {#text} at (99,48) size 222x20
             text run at (99,48) width 222: "Test typing at the end of a list."
-        LayoutNGBlockFlow (anonymous) at (20,89) size 729x21
+        LayoutBlockFlow (anonymous) at (20,89) size 744x21
           LayoutBR {BR} at (0,0) size 0x20
         LayoutBlockFlow {DIV} at (20,110) size 744x90
           LayoutText {#text} at (0,0) size 189x26
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/unsupported-content/list-type-before-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/unsupported-content/list-type-before-expected.txt
index 23e6031..636af63 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/unsupported-content/list-type-before-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/unsupported-content/list-type-before-expected.txt
@@ -23,7 +23,7 @@
               text run at (0,48) width 99: "For this test: "
           LayoutText {#text} at (99,48) size 227x20
             text run at (99,48) width 227: "Test typing at the start of a list."
-        LayoutNGBlockFlow (anonymous) at (20,89) size 729x21
+        LayoutBlockFlow (anonymous) at (20,89) size 744x21
           LayoutBR {BR} at (0,0) size 0x20
         LayoutBlockFlow {DIV} at (20,110) size 744x90
           LayoutText {#text} at (0,0) size 189x26
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/unsupported-content/table-type-after-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/unsupported-content/table-type-after-expected.txt
index 1c0f558..be476139 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/unsupported-content/table-type-after-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/unsupported-content/table-type-after-expected.txt
@@ -33,7 +33,7 @@
               text run at (0,48) width 99: "For this test: "
           LayoutText {#text} at (99,48) size 177x20
             text run at (99,48) width 177: "Test typing after a table."
-        LayoutNGBlockFlow (anonymous) at (20,89) size 729x21
+        LayoutBlockFlow (anonymous) at (20,89) size 744x21
           LayoutBR {BR} at (0,0) size 0x20
         LayoutBlockFlow {DIV} at (20,110) size 744x90
           LayoutText {#text} at (0,0) size 189x26
@@ -81,7 +81,7 @@
               LayoutTableCell {TD} at (30,54) size 12x24 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
                 LayoutText {#text} at (2,2) size 8x19
                   text run at (2,2) width 8: "9"
-        LayoutNGBlockFlow (anonymous) at (2,84) size 765x28
+        LayoutBlockFlow (anonymous) at (2,84) size 780x28
           LayoutText {#text} at (0,0) size 36x27
             text run at (0,0) width 36: "xxx"
       LayoutBlockFlow {DIV} at (0,354) size 784x114
@@ -118,7 +118,7 @@
                 LayoutTableCell {TD} at (30,54) size 12x24 [border: (1px inset #808080)] [r=2 c=2 rs=1 cs=1]
                   LayoutText {#text} at (2,2) size 8x19
                     text run at (2,2) width 8: "9"
-          LayoutNGBlockFlow (anonymous) at (2,84) size 780x28
+          LayoutBlockFlow (anonymous) at (2,84) size 780x28
             LayoutText {#text} at (0,0) size 36x27
               text run at (0,0) width 36: "xxx"
 caret: position 3 of child 2 {#text} of child 1 {DIV} of child 5 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/unsupported-content/table-type-before-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/unsupported-content/table-type-before-expected.txt
index abf8d154..b0b619d 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/unsupported-content/table-type-before-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/unsupported-content/table-type-before-expected.txt
@@ -23,7 +23,7 @@
               text run at (0,48) width 99: "For this test: "
           LayoutText {#text} at (99,48) size 190x20
             text run at (99,48) width 190: "Test typing before a table."
-        LayoutNGBlockFlow (anonymous) at (20,89) size 729x21
+        LayoutBlockFlow (anonymous) at (20,89) size 744x21
           LayoutBR {BR} at (0,0) size 0x20
         LayoutBlockFlow {DIV} at (20,110) size 744x90
           LayoutText {#text} at (0,0) size 189x26
@@ -39,7 +39,7 @@
           LayoutText {#text} at (99,69) size 448x20
             text run at (99,69) width 448: "Typed text should appear before (on the line above) the table."
       LayoutBlockFlow {DIV} at (0,230) size 784x114 [border: (2px solid #008000)]
-        LayoutNGBlockFlow (anonymous) at (2,2) size 765x28
+        LayoutBlockFlow (anonymous) at (2,2) size 780x28
           LayoutText {#text} at (0,0) size 36x27
             text run at (0,0) width 36: "xxx"
         LayoutTable {TABLE} at (2,30) size 46x82 [border: (1px outset #808080)]
@@ -76,7 +76,7 @@
                   text run at (2,2) width 8: "9"
       LayoutBlockFlow {DIV} at (0,354) size 784x114
         LayoutBlockFlow {DIV} at (0,0) size 784x114 [border: (2px solid #FF0000)]
-          LayoutNGBlockFlow (anonymous) at (2,2) size 780x28
+          LayoutBlockFlow (anonymous) at (2,2) size 780x28
             LayoutText {#text} at (0,0) size 36x27
               text run at (0,0) width 36: "xxx"
           LayoutTable {TABLE} at (2,30) size 46x82 [border: (1px outset #808080)]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/dom/34176-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/dom/34176-expected.txt
index 0e19270f..ab59491c 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/dom/34176-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/dom/34176-expected.txt
@@ -199,10 +199,10 @@
           LayoutInline {B} at (0,0) size 28x19
             LayoutText {#text} at (741,0) size 28x19
               text run at (741,0) width 28: "Test"
-      LayoutNGBlockFlow (anonymous) at (0,778) size 769x0
+      LayoutBlockFlow (anonymous) at (0,778) size 769x0
         LayoutInline {B} at (0,0) size 0x0
           LayoutText {#text} at (0,0) size 0x0
-      LayoutNGBlockFlow (anonymous) at (0,786) size 769x748
+      LayoutBlockFlow (anonymous) at (0,786) size 769x748
         LayoutBlockFlow {P} at (0,18) size 769x20
           LayoutText {#text} at (99,0) size 670x19
             text run at (99,0) width 670: "Text in <img>, <href>, <em>, <tr>. The following English text should all display as \"This is a Test\"."
@@ -260,21 +260,21 @@
                 LayoutText {#text} at (732,0) size 37x19
                   text run at (732,0) width 37: "again"
         LayoutBlockFlow {DIV} at (0,156) size 769x46
-          LayoutNGBlockFlow (anonymous) at (0,0) size 769x20
+          LayoutBlockFlow (anonymous) at (0,0) size 769x20
             LayoutText {#text} at (683,0) size 60x19
               text run at (683,0) width 60: "This is a "
             LayoutInline {SPAN} at (0,0) size 26x19
               LayoutInline {EM} at (0,0) size 26x19
                 LayoutText {#text} at (743,0) size 26x19
                   text run at (743,0) width 26: "Test"
-          LayoutNGBlockFlow (anonymous) at (0,20) size 769x26
+          LayoutBlockFlow (anonymous) at (0,20) size 769x26
             LayoutTable {TABLE} at (755,0) size 14x26
               LayoutTableSection {TBODY} at (0,0) size 14x26
                 LayoutTableRow {TR} at (0,2) size 14x22
                   LayoutTableCell {TD} at (2,2) size 10x22 [r=0 c=0 rs=1 cs=1]
                     LayoutText {#text} at (1,1) size 8x19
                       text run at (1,1) width 8: "a"
-          LayoutNGBlockFlow (anonymous) at (0,46) size 769x0
+          LayoutBlockFlow (anonymous) at (0,46) size 769x0
             LayoutInline {SPAN} at (0,0) size 0x0
               LayoutInline {EM} at (0,0) size 0x0
         LayoutBlockFlow {UL} at (0,228) size 769x520
@@ -382,7 +382,7 @@
             LayoutListMarker (anonymous) at (-18,0) size 7x19: bullet
             LayoutText {#text} at (0,0) size 117x19
               text run at (0,0) width 117: "Test 25: : Success"
-      LayoutNGBlockFlow (anonymous) at (0,1550) size 769x0
+      LayoutBlockFlow (anonymous) at (0,1550) size 769x0
         LayoutInline {B} at (0,0) size 0x0
 layer at (8,92) size 769x2 clip at (0,0) size 0x0
   LayoutBlockFlow {HR} at (0,76) size 769x2 [border: (1px inset #EEEEEE)]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/dom/blur-contenteditable-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/dom/blur-contenteditable-expected.txt
index 52b290e..117eb9c 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/dom/blur-contenteditable-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/dom/blur-contenteditable-expected.txt
@@ -3,7 +3,7 @@
 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 769x20
+      LayoutBlockFlow (anonymous) at (0,0) size 784x20
         LayoutText {#text} at (0,0) size 484x19
           text run at (0,0) width 484: "This test will try to call blur() on a contenteditable div, and then a normal div."
       LayoutBlockFlow {DIV} at (0,20) size 784x26 [border: (3px solid #000000)]
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/dom/focus-contenteditable-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/dom/focus-contenteditable-expected.txt
index 7c39a3a..ace1c7cf 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/dom/focus-contenteditable-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/dom/focus-contenteditable-expected.txt
@@ -3,7 +3,7 @@
 layer at (0,-282) size 785x902 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600
   LayoutBlockFlow {HTML} at (0,0) size 785x902
     LayoutBlockFlow {BODY} at (8,8) size 769x886
-      LayoutNGBlockFlow (anonymous) at (0,0) size 769x40
+      LayoutBlockFlow (anonymous) at (0,0) size 769x40
         LayoutText {#text} at (0,0) size 497x19
           text run at (0,0) width 497: "This test will try to call focus() on a contenteditable div, and then a normal div. "
         LayoutBR {BR} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/events/selectstart-by-drag-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/events/selectstart-by-drag-expected.txt
index 5684177..b2ca3dec 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/events/selectstart-by-drag-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/events/selectstart-by-drag-expected.txt
@@ -5,9 +5,9 @@
 Moving slightly to the right: PASS
 Moving slightly to the left: PASS
 Moving to the right: PASS
-Moving further to the right: FAIL - expected selection to be range but was caret
+Moving further to the right: PASS
 Moving back to the left: PASS
-Moving to the right again: FAIL - expected selection to be range but was caret
+Moving to the right again: PASS
 Mouse down on the right: PASS
 Moving to the left: PASS
 Done.
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/caret-rtl-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/caret-rtl-expected.txt
index 30725120..0b0b2ea7 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/caret-rtl-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/caret-rtl-expected.txt
@@ -4,7 +4,7 @@
 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 769x20
+      LayoutBlockFlow (anonymous) at (0,0) size 784x20
         LayoutText {#text} at (0,0) size 570x19
           text run at (0,0) width 570: "This tests that clicking in a contenteditable div will set the caret in the right edge of the div "
         LayoutBR {BR} at (570,15) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/image/image-alt-text-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/image/image-alt-text-expected.txt
index 2255ece..bb8b4221 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/image/image-alt-text-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/image/image-alt-text-expected.txt
@@ -3,7 +3,7 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x576
-      LayoutNGBlockFlow (anonymous) at (0,0) size 769x40
+      LayoutBlockFlow (anonymous) at (0,0) size 784x40
         LayoutText {#text} at (0,0) size 746x39
           text run at (0,0) width 481: "This tests whether alt text is shown for image-type form input elements with "
           text run at (481,0) width 265: "no src attribute. You should see \"Success\""
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/image/input-align-image-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/image/input-align-image-expected.png
index c83f7967..a3756549 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/image/input-align-image-expected.png
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/image/input-align-image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/image/input-align-image-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/image/input-align-image-expected.txt
index 3147cb8..394377fd 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/image/input-align-image-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/image/input-align-image-expected.txt
@@ -6,14 +6,14 @@
       LayoutBlockFlow {P} at (0,0) size 784x20
         LayoutText {#text} at (0,0) size 579x19
           text run at (0,0) width 579: "The following 4 images should be all be rendered exactly the same, aligned to the right side."
-      LayoutNGBlockFlow (anonymous) at (0,36) size 769x120
-        LayoutImage (floating) {INPUT} at (752,0) size 17x19
+      LayoutBlockFlow (anonymous) at (0,36) size 784x120
+        LayoutImage (floating) {INPUT} at (767,0) size 17x19
         LayoutBR {BR} at (0,0) size 0x19
         LayoutBR {BR} at (0,20) size 0x19
-        LayoutImage (floating) {INPUT} at (752,40) size 17x19
+        LayoutImage (floating) {INPUT} at (767,40) size 17x19
         LayoutBR {BR} at (0,40) size 0x19
         LayoutBR {BR} at (0,60) size 0x19
-        LayoutImage (floating) {INPUT} at (752,80) size 17x19
+        LayoutImage (floating) {INPUT} at (767,80) size 17x19
         LayoutBR {BR} at (0,80) size 0x19
         LayoutBR {BR} at (0,100) size 0x19
       LayoutBlockFlow {DIV} at (0,156) size 784x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/input-appearance-height-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/input-appearance-height-expected.txt
index e1e79b6..4ad9e5f 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/input-appearance-height-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/forms/input-appearance-height-expected.txt
@@ -3,7 +3,7 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x576
-      LayoutNGBlockFlow (anonymous) at (0,0) size 769x20
+      LayoutBlockFlow (anonymous) at (0,0) size 784x20
         LayoutText {#text} at (0,0) size 762x19
           text run at (0,0) width 762: "This tests the height attribute of form elements. The only element that should honour this value is the Image type of input."
       LayoutBlockFlow {FORM} at (0,20) size 784x266
@@ -29,7 +29,7 @@
           text run at (0,66) width 24: "file "
         LayoutFileUploadControl {INPUT} at (24,65) size 238x22 "No file chosen"
           LayoutButton {INPUT} at (0,0) size 85x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
-            LayoutNGBlockFlow (anonymous) at (8,3) size 69x16
+            LayoutBlockFlow (anonymous) at (8,3) size 69x16
               LayoutText {#text} at (0,0) size 69x16
                 text run at (0,0) width 69: "Choose File"
         LayoutText {#text} at (262,66) size 4x19
@@ -59,7 +59,7 @@
         LayoutText {#text} at (0,157) size 33x19
           text run at (0,157) width 33: "reset "
         LayoutButton {INPUT} at (33,156) size 50x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
-          LayoutNGBlockFlow (anonymous) at (8,3) size 34x16
+          LayoutBlockFlow (anonymous) at (8,3) size 34x16
             LayoutText {#text} at (0,0) size 34x16
               text run at (0,0) width 34: "Reset"
         LayoutText {#text} at (83,157) size 4x19
@@ -68,7 +68,7 @@
         LayoutText {#text} at (0,179) size 46x19
           text run at (0,179) width 46: "submit "
         LayoutButton {INPUT} at (46,178) size 57x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
-          LayoutNGBlockFlow (anonymous) at (8,3) size 41x16
+          LayoutBlockFlow (anonymous) at (8,3) size 41x16
             LayoutText {#text} at (0,0) size 41x16
               text run at (0,0) width 41: "Submit"
         LayoutText {#text} at (103,179) size 4x19
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-empty-rt-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-empty-rt-expected.txt
index ea13202..802ce9a 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-empty-rt-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-empty-rt-expected.txt
@@ -6,7 +6,7 @@
       LayoutBlockFlow {P} at (0,0) size 784x20
         LayoutText {#text} at (0,0) size 451x19
           text run at (0,0) width 451: "The following is a test for having a <rt> immediately following another."
-      LayoutNGBlockFlow (anonymous) at (0,36) size 769x40
+      LayoutBlockFlow (anonymous) at (0,36) size 784x40
         LayoutBR {BR} at (0,0) size 0x19
         LayoutBR {BR} at (0,20) size 0x19
       LayoutBlockFlow {P} at (0,92) size 784x32
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-inline-style-not-updated-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-inline-style-not-updated-expected.txt
index 05be069..54de885 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-inline-style-not-updated-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-inline-style-not-updated-expected.txt
@@ -3,7 +3,7 @@
 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 769x128
+      LayoutBlockFlow (anonymous) at (0,0) size 784x128
         LayoutRuby (inline) {RUBY} at (0,0) size 512x128 [color=#0000FF]
           LayoutRubyRun (anonymous) at (0,0) size 512x128
             LayoutRubyBase (anonymous) at (0,0) size 512x128
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-run-break-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-run-break-expected.txt
index 7c7ef6b..0ca839a 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-run-break-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-run-break-expected.txt
@@ -3,7 +3,7 @@
 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 769x80
+      LayoutBlockFlow (anonymous) at (0,0) size 784x80
         LayoutText {#text} at (0,0) size 767x59
           text run at (0,0) width 752: "This is a test for multiple ruby runs and line breaks. There is a div with a blue border and 10px padding. This contains a"
           text run at (0,20) width 497: "single <ruby> markup in the text contained in the block, broken across 2 lines. "
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-runs-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-runs-expected.txt
index 39df261..d64728e 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-runs-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-runs-expected.txt
@@ -3,7 +3,7 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x576
-      LayoutNGBlockFlow (anonymous) at (0,0) size 769x40
+      LayoutBlockFlow (anonymous) at (0,0) size 784x40
         LayoutText {#text} at (0,0) size 227x19
           text run at (0,0) width 227: "This is a test for multiple ruby runs. "
         LayoutBR {BR} at (227,15) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-simple-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-simple-expected.txt
index 7f6fb2f..2e0fc27 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-simple-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-simple-expected.txt
@@ -3,7 +3,7 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x576
-      LayoutNGBlockFlow (anonymous) at (0,0) size 769x40
+      LayoutBlockFlow (anonymous) at (0,0) size 784x40
         LayoutText {#text} at (0,0) size 224x19
           text run at (0,0) width 224: "This is a initial test for simple ruby. "
         LayoutBR {BR} at (224,15) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-simple-rp-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-simple-rp-expected.txt
index e7fffcb..3730fc97 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-simple-rp-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-simple-rp-expected.txt
@@ -3,7 +3,7 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x576
-      LayoutNGBlockFlow (anonymous) at (0,0) size 769x60
+      LayoutBlockFlow (anonymous) at (0,0) size 784x60
         LayoutText {#text} at (0,0) size 760x39
           text run at (0,0) width 333: "This is a test for simple ruby that contains <rp> tags. "
           text run at (333,0) width 427: "Contents of the <rp> tags (opening and closing brackets) should not"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-text-before-child-split-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-text-before-child-split-expected.txt
index 1a4a17e..d79812a 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-text-before-child-split-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-text-before-child-split-expected.txt
@@ -7,17 +7,17 @@
         LayoutRubyRun (anonymous) at (0,0) size 10x10
           LayoutRubyText {RT} at (0,0) size 10x0
           LayoutRubyBase (anonymous) at (0,0) size 10x10
-            LayoutNGBlockFlow (anonymous) at (0,0) size 10x10
+            LayoutBlockFlow (anonymous) at (0,0) size 10x10
               LayoutText {#text} at (0,0) size 10x10
                 text run at (0,0) width 10: "A"
               LayoutInline {I} at (0,0) size 0x10
-            LayoutNGBlockFlow (anonymous) at (0,10) size 10x0
+            LayoutBlockFlow (anonymous) at (0,10) size 10x0
               LayoutBlockFlow {DIV} at (0,0) size 10x0
-            LayoutNGBlockFlow (anonymous) at (0,10) size 10x0
+            LayoutBlockFlow (anonymous) at (0,10) size 10x0
               LayoutInline {I} at (0,0) size 0x0
         LayoutRubyRun (anonymous) at (10,0) size 10x10
           LayoutRubyBase (anonymous) at (0,0) size 10x10
-            LayoutNGBlockFlow (anonymous) at (0,0) size 10x10
+            LayoutBlockFlow (anonymous) at (0,0) size 10x10
               LayoutText {#text} at (0,0) size 10x10
                 text run at (0,0) width 10: "B"
       LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-trailing-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-trailing-expected.txt
index 99e0809..f57b29e 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-trailing-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/ruby-trailing-expected.txt
@@ -6,7 +6,7 @@
       LayoutBlockFlow {P} at (0,0) size 784x20
         LayoutText {#text} at (0,0) size 590x19
           text run at (0,0) width 590: "The following is a test for having a trailing base within a <ruby> with no associated ruby text."
-      LayoutNGBlockFlow (anonymous) at (0,36) size 769x40
+      LayoutBlockFlow (anonymous) at (0,36) size 784x40
         LayoutBR {BR} at (0,0) size 0x19
         LayoutBR {BR} at (0,20) size 0x19
       LayoutBlockFlow {P} at (0,92) size 784x32
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-insert-rt-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-insert-rt-expected.txt
index d89465e..d3779d9d 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-insert-rt-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-insert-rt-expected.txt
@@ -9,7 +9,7 @@
       LayoutBlockFlow {P} at (0,36) size 784x20
         LayoutText {#text} at (0,0) size 436x19
           text run at (0,0) width 436: "Both lines should look identical (the first line is the one manipulated)."
-      LayoutNGBlockFlow (anonymous) at (0,72) size 769x40
+      LayoutBlockFlow (anonymous) at (0,72) size 784x40
         LayoutBR {BR} at (0,0) size 0x19
         LayoutBR {BR} at (0,20) size 0x19
       LayoutBlockFlow {P} at (0,128) size 784x32
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-insert-text1-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-insert-text1-expected.txt
index 47c26bd..7646530 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-insert-text1-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-insert-text1-expected.txt
@@ -9,7 +9,7 @@
       LayoutBlockFlow {P} at (0,36) size 784x20
         LayoutText {#text} at (0,0) size 436x19
           text run at (0,0) width 436: "Both lines should look identical (the first line is the one manipulated)."
-      LayoutNGBlockFlow (anonymous) at (0,72) size 769x40
+      LayoutBlockFlow (anonymous) at (0,72) size 784x40
         LayoutBR {BR} at (0,0) size 0x19
         LayoutBR {BR} at (0,20) size 0x19
       LayoutBlockFlow {P} at (0,128) size 784x32
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-insert-text2-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-insert-text2-expected.txt
index a00a4e0..233606a0 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-insert-text2-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-insert-text2-expected.txt
@@ -10,7 +10,7 @@
       LayoutBlockFlow {P} at (0,56) size 784x20
         LayoutText {#text} at (0,0) size 436x19
           text run at (0,0) width 436: "Both lines should look identical (the first line is the one manipulated)."
-      LayoutNGBlockFlow (anonymous) at (0,92) size 769x40
+      LayoutBlockFlow (anonymous) at (0,92) size 784x40
         LayoutBR {BR} at (0,0) size 0x19
         LayoutBR {BR} at (0,20) size 0x19
       LayoutBlockFlow {P} at (0,148) size 784x32
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-insert-text3-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-insert-text3-expected.txt
index 3be9ee7e..14358ca 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-insert-text3-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-insert-text3-expected.txt
@@ -9,7 +9,7 @@
       LayoutBlockFlow {P} at (0,36) size 784x20
         LayoutText {#text} at (0,0) size 436x19
           text run at (0,0) width 436: "Both lines should look identical (the first line is the one manipulated)."
-      LayoutNGBlockFlow (anonymous) at (0,72) size 769x40
+      LayoutBlockFlow (anonymous) at (0,72) size 784x40
         LayoutBR {BR} at (0,0) size 0x19
         LayoutBR {BR} at (0,20) size 0x19
       LayoutBlockFlow {P} at (0,128) size 784x32
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-remove-rt1-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-remove-rt1-expected.txt
index 03bfbbc..3d93b63 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-remove-rt1-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-remove-rt1-expected.txt
@@ -9,7 +9,7 @@
       LayoutBlockFlow {P} at (0,36) size 784x20
         LayoutText {#text} at (0,0) size 436x19
           text run at (0,0) width 436: "Both lines should look identical (the first line is the one manipulated)."
-      LayoutNGBlockFlow (anonymous) at (0,72) size 769x40
+      LayoutBlockFlow (anonymous) at (0,72) size 784x40
         LayoutBR {BR} at (0,0) size 0x19
         LayoutBR {BR} at (0,20) size 0x19
       LayoutBlockFlow {P} at (0,128) size 784x32
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-remove-rt2-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-remove-rt2-expected.txt
index fbcc3f6..01c21e28 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-remove-rt2-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-remove-rt2-expected.txt
@@ -10,7 +10,7 @@
       LayoutBlockFlow {P} at (0,56) size 784x20
         LayoutText {#text} at (0,0) size 436x19
           text run at (0,0) width 436: "Both lines should look identical (the first line is the one manipulated)."
-      LayoutNGBlockFlow (anonymous) at (0,92) size 769x40
+      LayoutBlockFlow (anonymous) at (0,92) size 784x40
         LayoutBR {BR} at (0,0) size 0x19
         LayoutBR {BR} at (0,20) size 0x19
       LayoutBlockFlow {P} at (0,148) size 784x32
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-remove-text1-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-remove-text1-expected.txt
index f511e6f..1abe1f1 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-remove-text1-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-remove-text1-expected.txt
@@ -9,7 +9,7 @@
       LayoutBlockFlow {P} at (0,36) size 784x20
         LayoutText {#text} at (0,0) size 436x19
           text run at (0,0) width 436: "Both lines should look identical (the first line is the one manipulated)."
-      LayoutNGBlockFlow (anonymous) at (0,72) size 769x40
+      LayoutBlockFlow (anonymous) at (0,72) size 784x40
         LayoutBR {BR} at (0,0) size 0x19
         LayoutBR {BR} at (0,20) size 0x19
       LayoutBlockFlow {P} at (0,128) size 784x32
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-remove-text2-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-remove-text2-expected.txt
index be8fc405..a6213e3 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-remove-text2-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/ruby/rubyDOM-remove-text2-expected.txt
@@ -9,7 +9,7 @@
       LayoutBlockFlow {P} at (0,36) size 784x20
         LayoutText {#text} at (0,0) size 436x19
           text run at (0,0) width 436: "Both lines should look identical (the first line is the one manipulated)."
-      LayoutNGBlockFlow (anonymous) at (0,72) size 769x40
+      LayoutBlockFlow (anonymous) at (0,72) size 784x40
         LayoutBR {BR} at (0,0) size 0x19
         LayoutBR {BR} at (0,20) size 0x19
       LayoutBlockFlow {P} at (0,128) size 784x20
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fragmentation/transformed-clip-before-second-column-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fragmentation/transformed-clip-before-second-column-expected.txt
index 13f971b..de54a1fd 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fragmentation/transformed-clip-before-second-column-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fragmentation/transformed-clip-before-second-column-expected.txt
@@ -11,7 +11,7 @@
     LayoutBlockFlow {DIV} at (0,0) size 384x100
 layer at (408,38) size 384x40 scrollHeight 41
   LayoutBlockFlow {DIV} at (0,100) size 384x40
-    LayoutNGBlockFlow (anonymous) at (0,0) size 376.50x20
+    LayoutBlockFlow (anonymous) at (0,0) size 384x20
       LayoutText {#text} at (0,0) size 312x19
         text run at (0,0) width 312: "There should be a black rectangle below this text."
 layer at (408,58) size 384x20
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/html/details_summary/details-nested-1-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/html/details_summary/details-nested-1-expected.txt
index e535743e..9b1dc29 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/html/details_summary/details-nested-1-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/html/details_summary/details-nested-1-expected.txt
@@ -1,11 +1,11 @@
 layer at (0,0) size 800x600
   LayoutView at (0,0) size 800x600
 layer at (0,0) size 800x600
-  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
-    LayoutNGBlockFlow {BODY} at (8,8) size 784x584
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
       LayoutBlockFlow {DETAILS} at (0,0) size 784x144 [border: (8px solid #555599)]
         LayoutBlockFlow {SUMMARY} at (8,8) size 768x108 [border: (8px solid #9999CC)]
-          LayoutNGBlockFlow (anonymous) at (8,8) size 737x20
+          LayoutBlockFlow (anonymous) at (8,8) size 752x20
             LayoutDetailsMarker {DIV} at (0,4.45) size 10.55x10.55: down
             LayoutText {#text} at (16,0) size 63x19
               text run at (16,0) width 5: " "
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/html/details_summary/details-nested-2-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/html/details_summary/details-nested-2-expected.txt
index 14d6eb1..27acac5 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/html/details_summary/details-nested-2-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/html/details_summary/details-nested-2-expected.txt
@@ -1,8 +1,8 @@
 layer at (0,0) size 800x600
   LayoutView at (0,0) size 800x600
 layer at (0,0) size 800x600
-  LayoutNGBlockFlow {HTML} at (0,0) size 800x600
-    LayoutNGBlockFlow {BODY} at (8,8) size 784x584
+  LayoutBlockFlow {HTML} at (0,0) size 800x600
+    LayoutBlockFlow {BODY} at (8,8) size 784x584
       LayoutBlockFlow {DETAILS} at (0,0) size 784x144 [border: (8px solid #555599)]
         LayoutBlockFlow {SUMMARY} at (8,8) size 768x36 [border: (8px solid #9999CC)]
           LayoutDetailsMarker {DIV} at (8,12.45) size 10.55x10.55: down
@@ -19,6 +19,6 @@
             LayoutBlockFlow {DIV} at (8,44) size 752x20
               LayoutText {#text} at (0,0) size 179x19
                 text run at (0,0) width 179: "nested details (details-deails)"
-          LayoutNGBlockFlow (anonymous) at (0,72) size 753x20
+          LayoutBlockFlow (anonymous) at (0,72) size 768x20
             LayoutText {#text} at (0,0) size 40x19
               text run at (0,0) width 40: "details"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/html/details_summary/details-replace-summary-child-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/html/details_summary/details-replace-summary-child-expected.txt
index e019731..aefb2ace 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/html/details_summary/details-replace-summary-child-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/html/details_summary/details-replace-summary-child-expected.txt
@@ -18,9 +18,9 @@
               text run at (0,0) width 64: "Details3"
           LayoutText {#text} at (0,0) size 0x0
         LayoutBlockFlow {DIV} at (0,20) size 784x0
-      LayoutNGBlockFlow (anonymous) at (0,20) size 769x22
+      LayoutBlockFlow (anonymous) at (0,20) size 784x22
         LayoutButton {INPUT} at (0,0) size 43x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
-          LayoutNGBlockFlow (anonymous) at (8,3) size 27x16
+          LayoutBlockFlow (anonymous) at (8,3) size 27x16
             LayoutText {#text} at (0,0) size 27x16
               text run at (0,0) width 27: "click"
         LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/html/details_summary/details-replace-text-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/html/details_summary/details-replace-text-expected.txt
index 037dc31..39c1684 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/html/details_summary/details-replace-text-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/html/details_summary/details-replace-text-expected.txt
@@ -18,9 +18,9 @@
             LayoutText {#text} at (0,0) size 64x16
               text run at (0,0) width 64: "Details2"
           LayoutText {#text} at (0,0) size 0x0
-      LayoutNGBlockFlow (anonymous) at (0,40) size 769x22
+      LayoutBlockFlow (anonymous) at (0,40) size 784x22
         LayoutButton {INPUT} at (0,0) size 43x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)]
-          LayoutNGBlockFlow (anonymous) at (8,3) size 27x16
+          LayoutBlockFlow (anonymous) at (8,3) size 27x16
             LayoutText {#text} at (0,0) size 27x16
               text run at (0,0) width 27: "click"
         LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/selection/invalidation-rect-includes-newline-for-vertical-lr-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/selection/invalidation-rect-includes-newline-for-vertical-lr-expected.png
new file mode 100644
index 0000000..b1ee98b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/selection/invalidation-rect-includes-newline-for-vertical-lr-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/selection/invalidation-rect-includes-newline-for-vertical-lr-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/selection/invalidation-rect-includes-newline-for-vertical-lr-expected.txt
new file mode 100644
index 0000000..4ac5448
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/selection/invalidation-rect-includes-newline-for-vertical-lr-expected.txt
@@ -0,0 +1,44 @@
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "drawsContent": false,
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "backgroundColor": "#FFFFFF",
+      "paintInvalidations": [
+        {
+          "object": "NGPaintFragment",
+          "rect": [24, 8, 32, 16],
+          "reason": "selection"
+        },
+        {
+          "object": "NGPaintFragment",
+          "rect": [8, 8, 16, 48],
+          "reason": "selection"
+        }
+      ]
+    }
+  ],
+  "objectPaintInvalidations": [
+    {
+      "object": "NGPaintFragment",
+      "reason": "selection"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "selection"
+    }
+  ]
+}
+
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/selection/invalidation-rect-includes-newline-for-vertical-rl-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/selection/invalidation-rect-includes-newline-for-vertical-rl-expected.png
new file mode 100644
index 0000000..ab2ad5e1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/selection/invalidation-rect-includes-newline-for-vertical-rl-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/selection/invalidation-rect-includes-newline-for-vertical-rl-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/selection/invalidation-rect-includes-newline-for-vertical-rl-expected.txt
new file mode 100644
index 0000000..c5b57c6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/selection/invalidation-rect-includes-newline-for-vertical-rl-expected.txt
@@ -0,0 +1,44 @@
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "drawsContent": false,
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "backgroundColor": "#FFFFFF",
+      "paintInvalidations": [
+        {
+          "object": "NGPaintFragment",
+          "rect": [24, 8, 32, 48],
+          "reason": "selection"
+        },
+        {
+          "object": "NGPaintFragment",
+          "rect": [8, 8, 16, 16],
+          "reason": "selection"
+        }
+      ]
+    }
+  ],
+  "objectPaintInvalidations": [
+    {
+      "object": "NGPaintFragment",
+      "reason": "selection"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "selection"
+    }
+  ]
+}
+
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/selection/invalidation-rect-with-br-includes-newline-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/selection/invalidation-rect-with-br-includes-newline-expected.png
new file mode 100644
index 0000000..ae94bee
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/selection/invalidation-rect-with-br-includes-newline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/selection/invalidation-rect-with-br-includes-newline-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/selection/invalidation-rect-with-br-includes-newline-expected.txt
new file mode 100644
index 0000000..b5160e4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/selection/invalidation-rect-with-br-includes-newline-expected.txt
@@ -0,0 +1,48 @@
+{
+  "layers": [
+    {
+      "name": "LayoutView #document",
+      "bounds": [800, 600],
+      "drawsContent": false,
+      "backgroundColor": "#FFFFFF"
+    },
+    {
+      "name": "Scrolling Layer",
+      "bounds": [800, 600],
+      "drawsContent": false
+    },
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "backgroundColor": "#FFFFFF",
+      "paintInvalidations": [
+        {
+          "object": "NGPaintFragment",
+          "rect": [8, 8, 32, 16],
+          "reason": "selection"
+        },
+        {
+          "object": "NGPaintFragment",
+          "rect": [8, 24, 16, 32],
+          "reason": "selection"
+        }
+      ]
+    }
+  ],
+  "objectPaintInvalidations": [
+    {
+      "object": "NGPaintFragment",
+      "reason": "selection"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "selection"
+    },
+    {
+      "object": "NGPaintFragment",
+      "reason": "selection"
+    }
+  ]
+}
+
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/selection/text-selection-newline-vertical-lr-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/selection/text-selection-newline-vertical-lr-expected.png
new file mode 100644
index 0000000..b1ee98b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/selection/text-selection-newline-vertical-lr-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/mouseevent_fractional/fast/events/selectstart-by-drag-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/mouseevent_fractional/fast/events/selectstart-by-drag-expected.txt
index 5684177..b2ca3dec 100644
--- a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/mouseevent_fractional/fast/events/selectstart-by-drag-expected.txt
+++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/virtual/mouseevent_fractional/fast/events/selectstart-by-drag-expected.txt
@@ -5,9 +5,9 @@
 Moving slightly to the right: PASS
 Moving slightly to the left: PASS
 Moving to the right: PASS
-Moving further to the right: FAIL - expected selection to be range but was caret
+Moving further to the right: PASS
 Moving back to the left: PASS
-Moving to the right again: FAIL - expected selection to be range but was caret
+Moving to the right again: PASS
 Mouse down on the right: PASS
 Moving to the left: PASS
 Done.
diff --git a/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/.htaccess b/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/.htaccess
new file mode 100644
index 0000000..995b6e0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/.htaccess
@@ -0,0 +1 @@
+AddType application/cert-chain+cbor .cbor
diff --git a/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/README.md b/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/README.md
index 9a38297..492a4b2f 100644
--- a/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/README.md
+++ b/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/README.md
@@ -2,23 +2,16 @@
 (\*.htxg) in this directory are generated using the following commands.
 
 gen-certurl and gen-signedexchange are available in [webpackage repository][1].
-We're using a fork of [this repository][2] that implements the "Implementation
-Checkpoints" of [the signed-exchange spec][3].
+Revision 01e618f6af is used to generate these files.
 
 [1]: https://github.com/WICG/webpackage
-[2]: https://github.com/nyaxt/webpackage
-[3]: https://wicg.github.io/webpackage/draft-yasskin-httpbis-origin-signed-exchanges-impl.html
 
 ```
-# Install gen-certurl command from [1]
+# Install gen-certurl command.
 go get github.com/WICG/webpackage/go/signedexchange/cmd/gen-certurl
 
-# Install gen-signedexchange command from [2],
-go get github.com/nyaxt/webpackage/go/signedexchange/cmd/gen-signedexchange
-# and cherry-pick the following changes from [1].
-https://github.com/WICG/webpackage/commit/c173772a4fb3c923d705a319e5e9f2fb1fd569d7
-https://github.com/WICG/webpackage/commit/2635cc5d8fc3177092806ce19826e9cd8f8461c9
-https://github.com/WICG/webpackage/commit/2e88a4422a565221178891f50ed68c71cbcb6086
+# Install gen-signedexchange command.
+go get github.com/WICG/webpackage/go/signedexchange/cmd/gen-signedexchange
 
 # Make dummy OCSP data for cbor certificate chains.
 echo -n OCSP >/tmp/ocsp
diff --git a/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-cert-not-found.sxg b/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-cert-not-found.sxg
index d974d06..2a65b58 100644
--- a/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-cert-not-found.sxg
+++ b/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-cert-not-found.sxg
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-location.sxg b/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-location.sxg
index 38769cdb..aa13c56 100644
--- a/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-location.sxg
+++ b/third_party/WebKit/LayoutTests/http/tests/loading/htxg/resources/htxg-location.sxg
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/http/tests/notifications/serviceworkerregistration-document-no-permission.html b/third_party/WebKit/LayoutTests/http/tests/notifications/serviceworkerregistration-document-no-permission.html
index f510251e..bea8176 100644
--- a/third_party/WebKit/LayoutTests/http/tests/notifications/serviceworkerregistration-document-no-permission.html
+++ b/third_party/WebKit/LayoutTests/http/tests/notifications/serviceworkerregistration-document-no-permission.html
@@ -30,7 +30,7 @@
                   assert_unreached('showNotification() is expected to reject.');
               }).catch(function(error) {
                   assert_equals(error.name, 'TypeError');
-                  assert_equals(error.message, 'No notification permission has been granted for this origin.');
+                  assert_equals(error.message, "Failed to execute 'showNotification' on 'ServiceWorkerRegistration': No notification permission has been granted for this origin.");
                   test.done();
               });
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/notifications/serviceworkerregistration-document-not-activated.html b/third_party/WebKit/LayoutTests/http/tests/notifications/serviceworkerregistration-document-not-activated.html
index 158bed0c..e82911c 100644
--- a/third_party/WebKit/LayoutTests/http/tests/notifications/serviceworkerregistration-document-not-activated.html
+++ b/third_party/WebKit/LayoutTests/http/tests/notifications/serviceworkerregistration-document-not-activated.html
@@ -26,7 +26,7 @@
                   assert_unreached('showNotification() is expected to reject.');
               }).catch(function(error) {
                   assert_equals(error.name, 'TypeError');
-                  assert_equals(error.message, 'No active registration available on the ServiceWorkerRegistration.');
+                  assert_equals(error.message, "Failed to execute 'showNotification' on 'ServiceWorkerRegistration': No active registration available on the ServiceWorkerRegistration.");
                   test.done();
               });
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/notifications/serviceworkerregistration-service-worker-no-permission.html b/third_party/WebKit/LayoutTests/http/tests/notifications/serviceworkerregistration-service-worker-no-permission.html
index 94008cb..ba33369 100644
--- a/third_party/WebKit/LayoutTests/http/tests/notifications/serviceworkerregistration-service-worker-no-permission.html
+++ b/third_party/WebKit/LayoutTests/http/tests/notifications/serviceworkerregistration-service-worker-no-permission.html
@@ -28,7 +28,7 @@
               // (2) Confirm that the service worker could not display the notification due to a
               // permission error.
               assert_false(data.success);
-              assert_equals(data.message, 'No notification permission has been granted for this origin.');
+              assert_equals(data.message, "Failed to execute 'showNotification' on 'ServiceWorkerRegistration': No notification permission has been granted for this origin.");
 
               test.done();
           }).catch(unreached_rejection(test));
diff --git a/third_party/WebKit/LayoutTests/http/tests/priority-hints/image-dynamic-insertion.html b/third_party/WebKit/LayoutTests/http/tests/priority-hints/image-dynamic-insertion.html
new file mode 100644
index 0000000..19e55c9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/priority-hints/image-dynamic-insertion.html
@@ -0,0 +1,22 @@
+<script src=resources/common.js></script>
+<script src=../resources/testharness.js></script>
+<script src=../resources/testharnessreport.js></script>
+
+<script>
+  const tests = [
+    {test: async_test('high importance on <img>s not fetched by the preload scanner must translate to kHigh resource load priority'), importance: 'high', expected_priority: kHigh},
+    {test: async_test('low importance on <img>s not fetched by the preload scanner must translate to kLow resource load priority'), importance: 'low', expected_priority: kLow},
+    {test: async_test('auto importance on <img>s not fetched by the preload scanner must have no effect on resource load priority'), importance: 'auto', expected_priority: kLow},
+    {test: async_test('invalid importance on <img>s not fetched by the preload scanner must have no effect on resource load priority'), importance: 'xyz', expected_priority: kLow},
+    {test: async_test('missing importance on <img>s not fetched by the preload scanner must have no effect on resource load priority'), expected_priority: kLow}
+  ];
+
+  let iteration = 0;
+  for (const test of tests) {
+    const img = document.createElement('img');
+    img.alt = 'img';
+    if (test.importance) img.importance = test.importance;
+    img.src = `../resources/square.png?${iteration++}`;
+    img.onload = assert_priority_onload(img.src, test.expected_priority, test.test);
+  }
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/priority-hints/image-initial-load.html b/third_party/WebKit/LayoutTests/http/tests/priority-hints/image-initial-load.html
new file mode 100644
index 0000000..a00797f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/priority-hints/image-initial-load.html
@@ -0,0 +1,30 @@
+<script src=resources/common.js></script>
+<script src=../resources/testharness.js></script>
+<script src=../resources/testharnessreport.js></script>
+
+<img id=img1 importance=high src=../resources/square.png alt=img>
+<img id=img2 importance=low src=../resources/square.png?1 alt=img>
+<img id=img3 importance=auto src=../resources/square.png?2 alt=img>
+<img id=img4 importance=xyz src=../resources/square.png?3 alt=img>
+<img id=img5 src=../resources/square.png?4 alt=img>
+
+<script>
+  async_test(t => {
+    addEventListener('DOMContentLoaded', t.step_func(() => {
+      const msg = 'all images must be fetched by the preload scanner';
+      assert_true(internals.isPreloaded(img1.src), msg);
+      assert_true(internals.isPreloaded(img2.src), msg);
+      assert_true(internals.isPreloaded(img3.src), msg);
+      assert_true(internals.isPreloaded(img4.src), msg);
+      assert_true(internals.isPreloaded(img5.src), msg);
+
+      assert_equals(getPriority(img1.src), kHigh, 'high importance on <img> must translate to kHigh resource load priority');
+      assert_equals(getPriority(img2.src), kLow, 'low importance on <img> must translate to kLow resource load priority');
+      assert_equals(getPriority(img3.src), kLow, 'auto importance on <img> must translate to kLow resource load priority');
+      assert_equals(getPriority(img4.src), kLow, 'invalid importance on <img> must translate to kLow resource load priority');
+      assert_equals(getPriority(img5.src), kLow, 'missing importance on <img> must translate to kLow resource load priority');
+
+      t.done();
+    }));
+  }, 'importance attribute on <img>s fetched by the preload scanner correctly affects resource load priority');
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/priority-hints/image-low-importance-in-viewport.html b/third_party/WebKit/LayoutTests/http/tests/priority-hints/image-low-importance-in-viewport.html
new file mode 100644
index 0000000..3d6f5cc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/priority-hints/image-low-importance-in-viewport.html
@@ -0,0 +1,17 @@
+<script src=resources/common.js></script>
+<script src=../resources/testharness.js></script>
+<script src=../resources/testharnessreport.js></script>
+
+<script>
+  let t = async_test('low importance on in-viewport images must be fetched with kLow resource load priority');
+  // Synchronous wait to delay layout by .5 seconds
+  let end = Date.now() + 500;
+  while (Date.now() < end) {}
+</script>
+
+<!--
+  In-viewport images get re-prioritized if layout is computed mid-flight. With importance=low, re-prioritization should have no effect,
+  we delay both the image request (will be fetched by preload scanner) by a second, and finish layout mid-flight. As long as the final
+  resource load priority is kLow, we know the image was not re-prioritized.
+-->
+<img importance=low src="../resources/slow-image.php?sleep=1000&name=square.png" alt=img onload="assert_priority_onload(this.src, kLow, t)()">
diff --git a/third_party/WebKit/LayoutTests/http/tests/priority-hints/link-dynamic-insertion.html b/third_party/WebKit/LayoutTests/http/tests/priority-hints/link-dynamic-insertion.html
new file mode 100644
index 0000000..ec0d548de
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/priority-hints/link-dynamic-insertion.html
@@ -0,0 +1,23 @@
+<script src=resources/common.js></script>
+<script src=../resources/testharness.js></script>
+<script src=../resources/testharnessreport.js></script>
+
+<script>
+  const tests = [
+    {test: async_test('high importance on <link rel=stylesheet>s not fetched by the preload scanner must have no effect on resource load priority'), importance: 'high', expected_priority: kVeryHigh},
+    {test: async_test('low importance on <link rel=stylesheet>s not fetched by the preload scanner must have no effect on resource load priority'), importance: 'low', expected_priority: kVeryHigh},
+    {test: async_test('auto importance on <link rel=stylesheet>s not fetched by the preload scanner must have no effect on resource load priority'), importance: 'auto', expected_priority: kVeryHigh},
+    {test: async_test('invalid importance on <link rel=stylesheet>s not fetched by the preload scanner must have no effect on resource load priority'), importance: 'xyz', expected_priority: kVeryHigh},
+    {test: async_test('missing importance on <link rel=stylesheet>s not fetched by the preload scanner must have no effect on resource load priority'), expected_priority: kVeryHigh}
+  ];
+
+  let iteration = 0;
+  for (const test of tests) {
+    const link = document.createElement('link');
+    link.rel = 'stylesheet';
+    if (test.importance) link.importance = test.importance;
+    link.href = `../resources/dummy.css?${iteration++}`;
+    link.onload = assert_priority_onload(link.href, test.expected_priority, test.test);
+    document.head.appendChild(link);
+  }
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/priority-hints/link-preload-dynamic-insertion.html b/third_party/WebKit/LayoutTests/http/tests/priority-hints/link-preload-dynamic-insertion.html
new file mode 100644
index 0000000..2c21625
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/priority-hints/link-preload-dynamic-insertion.html
@@ -0,0 +1,103 @@
+<script src=resources/common.js></script>
+<script src=../resources/testharness.js></script>
+<script src=../resources/testharnessreport.js></script>
+
+<script>
+  const tests = [
+    // rel=style
+    {
+      test: async_test('low importance on <link rel=preload as=style> not fetched by the preload scanner must be fetched with kLow resource load priority'),
+      as: 'style',
+      importance: 'low',
+      resource: 'dummy.css',
+      expected_priority: kLow
+    },
+    {
+      test: async_test('missing importance on <link rel=preload as=style> not fetched by the preload scanner must have no effect on resource load priority'),
+      as: 'style',
+      resource: 'dummy.css',
+      expected_priority: kVeryHigh
+    },
+    {
+      test: async_test('high importance on <link rel=preload as=style> not fetched by the preload scanner must have no effect on resource load priority'),
+      as: 'style',
+      importance: 'high',
+      resource: 'dummy.css',
+      expected_priority: kVeryHigh
+    },
+    // rel=script
+    {
+      test: async_test('low importance on <link rel=preload as=script> not fetched by the preload scanner must be fetched with kLow resource load priority'),
+      as: 'script',
+      importance: 'low',
+      resource: 'dummy.js',
+      expected_priority: kLow
+    },
+    {
+      test: async_test('missing importance on <link rel=preload as=script> not fetched by the preload scanner must have no effect on resource load priority'),
+      as: 'script',
+      resource: 'dummy.js',
+      expected_priority: kHigh
+    },
+    {
+      test: async_test('high importance on <link rel=preload as=script> not fetched by the preload scanner must have no effect on resource load priority'),
+      as: 'script',
+      importance: 'high',
+      resource: 'dummy.js',
+      expected_priority: kHigh
+    },
+    // rel=fetch
+    {
+      test: async_test('low importance on <link rel=preload as=fetch> not fetched by the preload scanner must be fetched with kLow resource load priority'),
+      as: 'fetch',
+      importance: 'low',
+      resource: 'dummy.txt',
+      expected_priority: kLow
+    },
+    {
+      test: async_test('missing importance on <link rel=preload as=fetch> not fetched by the preload scanner must have no effect on resource load priority'),
+      as: 'fetch',
+      resource: 'dummy.txt',
+      expected_priority: kHigh
+    },
+    {
+      test: async_test('high importance on <link rel=preload as=fetch> not fetched by the preload scanner must have no effect on resource load priority'),
+      as: 'fetch',
+      importance: 'high',
+      resource: 'dummy.txt',
+      expected_priority: kHigh
+    },
+    // rel=image
+    {
+      test: async_test('low importance on <link rel=preload as=image> not fetched by the preload scanner must have no effect on resource load priority'),
+      as: 'image',
+      importance: 'low',
+      resource: 'square.png',
+      expected_priority: kLow
+    },
+    {
+      test: async_test('missing importance on <link rel=preload as=image> not fetched by the preload scanner must have no effect on resource load priority'),
+      as: 'image',
+      resource: 'square.png',
+      expected_priority: kLow
+    },
+    {
+      test: async_test('high importance on <link rel=preload as=image> not fetched by the preload scanner must be fetched with kHigh resource load priority'),
+      as: 'image',
+      importance: 'high',
+      resource: 'square.png',
+      expected_priority: kHigh
+    }
+  ];
+
+  let iteration = 0;
+  for (const test of tests) {
+    const link = document.createElement('link');
+    link.rel = 'preload';
+    link.as = test.as;
+    if (test.importance) link.importance = test.importance;
+    link.href = `../resources/${test.resource}?${iteration++}`;
+    link.onload = assert_priority_onload(link.href, test.expected_priority, test.test);
+    document.head.appendChild(link);
+  }
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/priority-hints/link-preload-initial-load.html b/third_party/WebKit/LayoutTests/http/tests/priority-hints/link-preload-initial-load.html
new file mode 100644
index 0000000..0a349ea
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/priority-hints/link-preload-initial-load.html
@@ -0,0 +1,62 @@
+<script src=resources/common.js></script>
+<script src=../resources/testharness.js></script>
+<script src=../resources/testharnessreport.js></script>
+
+<!-- as=style -->
+<!-- don't need to test for invalid and explicit auto importance here, since we already do that in the other link test -->
+<link id=link1 importance=low rel=preload as=style href=../resources/dummy.css>
+<link id=link2 rel=preload as=style href=../resources/dummy.css?1>
+<link id=link3 importance=high rel=preload as=style href=../resources/dummy.css?2>
+
+<!-- as=script-->
+<link id=link4 importance=low rel=preload as=script href=../resources/dummy.js>
+<link id=link5 rel=preload as=script href=../resources/dummy.js?1>
+<link id=link6 importance=high rel=preload as=script href=../resources/dummy.js?2>
+
+<!-- as=fetch-->
+<link id=link7 importance=low rel=preload as=fetch href=../resources/dummy.txt>
+<link id=link8 rel=preload as=fetch href=../resources/dummy.txt?1>
+<link id=link9 importance=high rel=preload as=fetch href=../resources/dummy.txt?2>
+
+<!-- as=image-->
+<link id=link10 importance=low rel=preload as=image href=../resources/square.png>
+<link id=link11 rel=preload as=image href=../resources/square.png?1>
+<link id=link12 importance=high rel=preload as=image href=../resources/square.png?2>
+
+<script>
+  async_test(t => {
+    addEventListener('DOMContentLoaded', t.step_func(() => {
+      const msg = 'all preloads must be fetched by the preload scanner';
+      assert_true(internals.isPreloaded(link1.href), msg);
+      assert_true(internals.isPreloaded(link2.href), msg);
+      assert_true(internals.isPreloaded(link3.href), msg);
+      assert_true(internals.isPreloaded(link4.href), msg);
+      assert_true(internals.isPreloaded(link5.href), msg);
+      assert_true(internals.isPreloaded(link6.href), msg);
+      assert_true(internals.isPreloaded(link7.href), msg);
+      assert_true(internals.isPreloaded(link8.href), msg);
+      assert_true(internals.isPreloaded(link9.href), msg);
+      assert_true(internals.isPreloaded(link10.href), msg);
+      assert_true(internals.isPreloaded(link11.href), msg);
+      assert_true(internals.isPreloaded(link12.href), msg);
+
+      assert_equals(getPriority(link1.href), kLow, 'low importance on <link rel=preload as=style> must be fetched with kLow resource load priority');
+      assert_equals(getPriority(link2.href), kVeryHigh, 'missing importance on <link rel=preload as=style> must have no effect on resource load priority');
+      assert_equals(getPriority(link3.href), kVeryHigh, 'high importance on <link rel=preload as=style> must have no effect on resource load priority');
+
+      assert_equals(getPriority(link4.href), kLow, 'low importance on <link rel=preload as=script> must be fetched with kLow resource load priority');
+      assert_equals(getPriority(link5.href), kHigh, 'missing importance on <link rel=preload as=script> must have no effect on resource load priority');
+      assert_equals(getPriority(link6.href), kHigh, 'high importance on <link rel=preload as=script> must have no effect on resource load priority');
+
+      assert_equals(getPriority(link7.href), kLow, 'low importance on <link rel=preload as=fetch> must be fetched with kLow resource load priority');
+      assert_equals(getPriority(link8.href), kHigh, 'missing importance on <link rel=preload as=fetch> must have no effect on resource load priority');
+      assert_equals(getPriority(link9.href), kHigh, 'high importance on <link rel=preload as=fetch> must have no effect on resource load priority');
+
+      assert_equals(getPriority(link10.href), kLow, 'low importance on <link rel=preload as=image> must have no effect on resource load priority');
+      assert_equals(getPriority(link11.href), kLow, 'missing importance on <link rel=preload as=image> must have no effect on resource load priority');
+      assert_equals(getPriority(link12.href), kHigh, 'high importance on <link rel=preload as=image> must be fetched with kHigh resource load priority');
+
+      t.done();
+    }));
+  }, 'importance attribute on <link rel=preload>s with supported as= values fetched by the preload scanner correctly influences resource load priority');
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/priority-hints/link-stylesheet-initial-load.html b/third_party/WebKit/LayoutTests/http/tests/priority-hints/link-stylesheet-initial-load.html
new file mode 100644
index 0000000..bb83c0d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/priority-hints/link-stylesheet-initial-load.html
@@ -0,0 +1,30 @@
+<script src=resources/common.js></script>
+<script src=../resources/testharness.js></script>
+<script src=../resources/testharnessreport.js></script>
+
+<link id=link1 importance=low rel=stylesheet href=../resources/dummy.css>
+<link id=link2 importance=high rel=stylesheet href=../resources/dummy.css?1>
+<link id=link3 importance=auto rel=stylesheet href=../resources/dummy.css?2>
+<link id=link4 importance=xyz rel=stylesheet href=../resources/dummy.css?3>
+<link id=link5 rel=stylesheet href=../resources/dummy.css?4>
+
+<script>
+  async_test(t => {
+    addEventListener('DOMContentLoaded', t.step_func(() => {
+      const msg = 'all stylesheets must be fetched by the preload scanner';
+      assert_true(internals.isPreloaded(link1.href), msg);
+      assert_true(internals.isPreloaded(link2.href), msg);
+      assert_true(internals.isPreloaded(link3.href), msg);
+      assert_true(internals.isPreloaded(link4.href), msg);
+      assert_true(internals.isPreloaded(link5.href), msg);
+
+      assert_equals(getPriority(link1.href), kVeryHigh, 'low importance on <link rel=stylesheet> must have no effect on resource load priority');
+      assert_equals(getPriority(link2.href), kVeryHigh, 'high importance on <link rel=stylesheet> must have no effect on resource load priority');
+      assert_equals(getPriority(link3.href), kVeryHigh, 'auto importance on <link rel=stylesheet> must have no effect on resource load priority');
+      assert_equals(getPriority(link4.href), kVeryHigh, 'invalid importance on <link rel=stylesheet> must have no effect on resource load priority');
+      assert_equals(getPriority(link5.href), kVeryHigh, 'missing importance on <link rel=stylesheet> must have no effect on resource load priority');
+
+      t.done();
+    }));
+  }, 'importance attribute on <link rel=stylesheet>s fetched by the preload scanner does not effect the resource load priority');
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/priority-hints/resources/common.js b/third_party/WebKit/LayoutTests/http/tests/priority-hints/resources/common.js
new file mode 100644
index 0000000..70a30f4c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/priority-hints/resources/common.js
@@ -0,0 +1,22 @@
+/**
+ * These values map to some of the the current
+ * priority enum members in blink::ResourceLoadPriority.
+ * The values are exposed through window.internals
+ * and in these tests, we use the below variables to represent
+ * the exposed values in a readable way.
+ */
+const kLow = 1,
+      kMedium = 2,
+      kHigh = 3,
+      kVeryHigh = 4;
+
+function assert_priority_onload(url, expected_priority, test) {
+  return test.step_func(e => {
+    assert_equals(expected_priority, getPriority(url, document));
+    test.done();
+  });
+}
+
+function getPriority(url) {
+  return internals.getResourcePriority(url, document);
+}
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/gradients/unprefixed-repeating-linear-gradient-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/gradients/unprefixed-repeating-linear-gradient-expected.png
deleted file mode 100644
index 1339796..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/gradients/unprefixed-repeating-linear-gradient-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt
index f7318aa..db787c8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt
@@ -1,5 +1,6 @@
 This is a testharness.js-based test.
-Found 583 tests; 405 PASS, 178 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 584 tests; 406 PASS, 178 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS Setup
 PASS align-content (type: discrete) has testAccumulation function
 PASS align-content: "flex-end" onto "flex-start"
 PASS align-content: "flex-start" onto "flex-end"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt
index ba3a083..dede9a2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt
@@ -1,5 +1,6 @@
 This is a testharness.js-based test.
-Found 579 tests; 537 PASS, 42 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 580 tests; 538 PASS, 42 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS Setup
 PASS align-content (type: discrete) has testAddition function
 PASS align-content: "flex-end" onto "flex-start"
 PASS align-content: "flex-start" onto "flex-end"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt
index 1abce08..0ef9c47 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt
@@ -1,5 +1,6 @@
 This is a testharness.js-based test.
-Found 723 tests; 646 PASS, 77 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 724 tests; 647 PASS, 77 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS Setup
 PASS align-content (type: discrete) has testInterpolation function
 PASS align-content uses discrete animation when animating between "flex-start" and "flex-end" with linear easing
 PASS align-content uses discrete animation when animating between "flex-start" and "flex-end" with effect easing
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt
index fadcbc7..66670b8 100644
--- a/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/accumulation-per-property-expected.txt
@@ -1,5 +1,6 @@
 This is a testharness.js-based test.
-Found 583 tests; 404 PASS, 179 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 584 tests; 405 PASS, 179 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS Setup
 PASS align-content (type: discrete) has testAccumulation function
 PASS align-content: "flex-end" onto "flex-start"
 PASS align-content: "flex-start" onto "flex-end"
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt
index 66ccba8..47996ff 100644
--- a/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/addition-per-property-expected.txt
@@ -1,5 +1,6 @@
 This is a testharness.js-based test.
-Found 579 tests; 536 PASS, 43 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 580 tests; 537 PASS, 43 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS Setup
 PASS align-content (type: discrete) has testAddition function
 PASS align-content: "flex-end" onto "flex-start"
 PASS align-content: "flex-start" onto "flex-end"
diff --git a/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt b/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt
index a9f5d1d8..3d743ab 100644
--- a/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/external/wpt/web-animations/animation-model/animation-types/interpolation-per-property-expected.txt
@@ -1,5 +1,6 @@
 This is a testharness.js-based test.
-Found 723 tests; 643 PASS, 80 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 724 tests; 644 PASS, 80 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS Setup
 PASS align-content (type: discrete) has testInterpolation function
 PASS align-content uses discrete animation when animating between "flex-start" and "flex-end" with linear easing
 PASS align-content uses discrete animation when animating between "flex-start" and "flex-end" with effect easing
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/gradients/unprefixed-repeating-linear-gradient-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/gradients/unprefixed-repeating-linear-gradient-expected.png
index 8d83c85..1339796 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/gradients/unprefixed-repeating-linear-gradient-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/gradients/unprefixed-repeating-linear-gradient-expected.png
Binary files differ
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 a8f0e19..db53b48e 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
@@ -646,6 +646,7 @@
     property decoding
     property height
     property hspace
+    property importance
     property isMap
     property longDesc
     property lowsrc
@@ -743,6 +744,7 @@
     property href
     property hreflang
     property import
+    property importance
     property integrity
     property media
     property referrerPolicy
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 269fb2c..de3486cc 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -2932,6 +2932,7 @@
     getter decoding
     getter height
     getter hspace
+    getter importance
     getter isMap
     getter longDesc
     getter lowsrc
@@ -2956,6 +2957,7 @@
     setter decoding
     setter height
     setter hspace
+    setter importance
     setter isMap
     setter longDesc
     setter lowsrc
@@ -3098,6 +3100,7 @@
     getter href
     getter hreflang
     getter import
+    getter importance
     getter integrity
     getter media
     getter referrerPolicy
@@ -3115,6 +3118,7 @@
     setter disabled
     setter href
     setter hreflang
+    setter importance
     setter integrity
     setter media
     setter referrerPolicy
@@ -3961,6 +3965,7 @@
     getter decoding
     getter height
     getter hspace
+    getter importance
     getter isMap
     getter longDesc
     getter lowsrc
@@ -3985,6 +3990,7 @@
     setter decoding
     setter height
     setter hspace
+    setter importance
     setter isMap
     setter longDesc
     setter lowsrc
diff --git a/third_party/blink/public/platform/web_media_constraints.h b/third_party/blink/public/platform/web_media_constraints.h
index 85b38dc..3151e624 100644
--- a/third_party/blink/public/platform/web_media_constraints.h
+++ b/third_party/blink/public/platform/web_media_constraints.h
@@ -41,6 +41,10 @@
 
 namespace blink {
 
+// Possible values of the echo canceller type constraint.
+BLINK_PLATFORM_EXPORT extern const char kEchoCancellationTypeBrowser[];
+BLINK_PLATFORM_EXPORT extern const char kEchoCancellationTypeSystem[];
+
 class WebMediaConstraintsPrivate;
 
 class BLINK_PLATFORM_EXPORT BaseConstraint {
diff --git a/third_party/blink/public/platform/web_media_stream_source.h b/third_party/blink/public/platform/web_media_stream_source.h
index d5e1502..dd2a5b81 100644
--- a/third_party/blink/public/platform/web_media_stream_source.h
+++ b/third_party/blink/public/platform/web_media_stream_source.h
@@ -82,6 +82,7 @@
     WebVector<double> aspect_ratio;
     WebVector<double> frame_rate;
     WebVector<bool> echo_cancellation;
+    WebVector<WebString> echo_cancellation_type;
     WebVector<bool> auto_gain_control;
     WebVector<bool> noise_suppression;
 
diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h
index 2245bb92..fcf2b4f 100644
--- a/third_party/blink/public/platform/web_runtime_features.h
+++ b/third_party/blink/public/platform/web_runtime_features.h
@@ -115,6 +115,7 @@
   BLINK_PLATFORM_EXPORT static void EnableOverflowIconsForMediaControls(bool);
   BLINK_PLATFORM_EXPORT static void EnableOverlayScrollbars(bool);
   BLINK_PLATFORM_EXPORT static void EnableOutOfBlinkCORS(bool);
+  BLINK_PLATFORM_EXPORT static void EnablePageLifecycle(bool);
   BLINK_PLATFORM_EXPORT static void EnablePagePopup(bool);
   BLINK_PLATFORM_EXPORT static void EnablePassiveDocumentEventListeners(bool);
   BLINK_PLATFORM_EXPORT static void EnablePaymentApp(bool);
diff --git a/third_party/blink/public/platform/web_security_origin.h b/third_party/blink/public/platform/web_security_origin.h
index 7945147..c462349 100644
--- a/third_party/blink/public/platform/web_security_origin.h
+++ b/third_party/blink/public/platform/web_security_origin.h
@@ -59,7 +59,9 @@
   BLINK_PLATFORM_EXPORT static WebSecurityOrigin CreateFromString(
       const WebString&);
   BLINK_PLATFORM_EXPORT static WebSecurityOrigin Create(const WebURL&);
-  BLINK_PLATFORM_EXPORT static WebSecurityOrigin CreateUnique();
+  BLINK_PLATFORM_EXPORT static WebSecurityOrigin CreateUniqueOpaque();
+  // TODO(dcheng): Remove this. https://crbug.com/695622
+  static WebSecurityOrigin CreateUnique() { return CreateUniqueOpaque(); }
 
   BLINK_PLATFORM_EXPORT void Reset();
   BLINK_PLATFORM_EXPORT void Assign(const WebSecurityOrigin&);
diff --git a/third_party/blink/renderer/bindings/core/v8/exception_state.cc b/third_party/blink/renderer/bindings/core/v8/exception_state.cc
index 72a54bb..b06db42 100644
--- a/third_party/blink/renderer/bindings/core/v8/exception_state.cc
+++ b/third_party/blink/renderer/bindings/core/v8/exception_state.cc
@@ -98,12 +98,6 @@
   exception_.Clear();
 }
 
-ScriptPromise ExceptionState::Reject(ScriptState* script_state) {
-  ScriptPromise promise = ScriptPromise::Reject(script_state, GetException());
-  ClearException();
-  return promise;
-}
-
 void ExceptionState::SetException(ExceptionCode ec,
                                   const String& message,
                                   v8::Local<v8::Value> exception) {
diff --git a/third_party/blink/renderer/bindings/core/v8/exception_state.h b/third_party/blink/renderer/bindings/core/v8/exception_state.h
index bacd3c5..af170ed0 100644
--- a/third_party/blink/renderer/bindings/core/v8/exception_state.h
+++ b/third_party/blink/renderer/bindings/core/v8/exception_state.h
@@ -31,7 +31,6 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_EXCEPTION_STATE_H_
 #define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_EXCEPTION_STATE_H_
 
-#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/dom/exception_code.h"
 #include "third_party/blink/renderer/platform/bindings/scoped_persistent.h"
@@ -44,7 +43,6 @@
 namespace blink {
 
 typedef int ExceptionCode;
-class ScriptState;
 
 // ExceptionState is a scope-like class and provides a way to throw an exception
 // with an option to cancel it.  An exception message may be auto-generated.
@@ -126,9 +124,6 @@
     return exception_.NewLocal(isolate_);
   }
 
-  // This method clears out the exception which |this| has.
-  ScriptPromise Reject(ScriptState*);
-
   ContextType Context() const { return context_; }
   const char* PropertyName() const { return property_name_; }
   const char* InterfaceName() const { return interface_name_; }
diff --git a/third_party/blink/renderer/bindings/core/v8/generated_code_helper.h b/third_party/blink/renderer/bindings/core/v8/generated_code_helper.h
index 15442f0..06b1753 100644
--- a/third_party/blink/renderer/bindings/core/v8/generated_code_helper.h
+++ b/third_party/blink/renderer/bindings/core/v8/generated_code_helper.h
@@ -11,10 +11,10 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_GENERATED_CODE_HELPER_H_
 #define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_GENERATED_CODE_HELPER_H_
 
-#include "base/memory/scoped_refptr.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
 #include "v8/include/v8.h"
 
 namespace blink {
@@ -51,7 +51,8 @@
     // promises must also be created in the current realm while regular promises
     // are created in the relevant realm of the context object.
     ScriptState* script_state = ScriptState::ForCurrentRealm(info_);
-    V8SetReturnValue(info_, exception_state_.Reject(script_state).V8Value());
+    V8SetReturnValue(
+        info_, ScriptPromise::Reject(script_state, exception_state_).V8Value());
   }
 
  private:
diff --git a/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h b/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h
index f940ddd..ac4a9d0 100644
--- a/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h
+++ b/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h
@@ -7,6 +7,7 @@
 
 #include "third_party/blink/renderer/bindings/core/v8/idl_types.h"
 #include "third_party/blink/renderer/bindings/core/v8/native_value_traits.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
diff --git a/third_party/blink/renderer/bindings/core/v8/script_promise.cc b/third_party/blink/renderer/bindings/core/v8/script_promise.cc
index 9da06cc..4f7c4126 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_promise.cc
+++ b/third_party/blink/renderer/bindings/core/v8/script_promise.cc
@@ -299,6 +299,14 @@
   return promise;
 }
 
+ScriptPromise ScriptPromise::Reject(ScriptState* script_state,
+                                    ExceptionState& exception_state) {
+  DCHECK(exception_state.HadException());
+  ScriptPromise promise = Reject(script_state, exception_state.GetException());
+  exception_state.ClearException();
+  return promise;
+}
+
 ScriptPromise ScriptPromise::RejectWithDOMException(ScriptState* script_state,
                                                     DOMException* exception) {
   DCHECK(script_state->GetIsolate()->InContext());
diff --git a/third_party/blink/renderer/bindings/core/v8/script_promise.h b/third_party/blink/renderer/bindings/core/v8/script_promise.h
index ec16cea..09df0a12 100644
--- a/third_party/blink/renderer/bindings/core/v8/script_promise.h
+++ b/third_party/blink/renderer/bindings/core/v8/script_promise.h
@@ -43,6 +43,7 @@
 namespace blink {
 
 class DOMException;
+class ExceptionState;
 
 // ScriptPromise is the class for representing Promise values in C++ world.
 // ScriptPromise holds a Promise.
@@ -106,6 +107,8 @@
 
   static ScriptPromise Reject(ScriptState*, const ScriptValue&);
   static ScriptPromise Reject(ScriptState*, v8::Local<v8::Value>);
+  // Rejects with a given exception. The ExceptionState gets cleared.
+  static ScriptPromise Reject(ScriptState*, ExceptionState&);
 
   static ScriptPromise RejectWithDOMException(ScriptState*, DOMException*);
 
diff --git a/third_party/blink/renderer/core/css/css_primitive_value.cc b/third_party/blink/renderer/core/css/css_primitive_value.cc
index 9f75a4d..f035707 100644
--- a/third_party/blink/renderer/core/css/css_primitive_value.cc
+++ b/third_party/blink/renderer/core/css/css_primitive_value.cc
@@ -380,7 +380,7 @@
       factor = kCssPixelsPerPica;
       break;
     case UnitType::kRadians:
-      factor = 180 / piDouble;
+      factor = 180 / kPiDouble;
       break;
     case UnitType::kGradians:
       factor = 0.9;
diff --git a/third_party/blink/renderer/core/dom/BUILD.gn b/third_party/blink/renderer/core/dom/BUILD.gn
index 96fea020ee..d869bde 100644
--- a/third_party/blink/renderer/core/dom/BUILD.gn
+++ b/third_party/blink/renderer/core/dom/BUILD.gn
@@ -119,8 +119,6 @@
     "events/add_event_listener_options_resolved.h",
     "events/custom_event.cc",
     "events/custom_event.h",
-    "events/dom_window_event_queue.cc",
-    "events/dom_window_event_queue.h",
     "events/event.cc",
     "events/event.h",
     "events/event_dispatch_result.h",
@@ -132,6 +130,8 @@
     "events/event_path.cc",
     "events/event_path.h",
     "events/event_queue.h",
+    "events/event_queue_impl.cc",
+    "events/event_queue_impl.h",
     "events/event_target.cc",
     "events/event_target.h",
     "events/event_target_impl.cc",
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index 0df22c6..f90934a 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -6097,7 +6097,7 @@
     // No source for a security context.
     // This can occur via document.implementation.createDocument().
     cookie_url_ = KURL(g_empty_string);
-    SetSecurityOrigin(SecurityOrigin::CreateUnique());
+    SetSecurityOrigin(SecurityOrigin::CreateUniqueOpaque());
     InitContentSecurityPolicy();
     ApplyFeaturePolicy({});
     return;
@@ -6128,7 +6128,7 @@
   if (IsSandboxed(kSandboxOrigin)) {
     cookie_url_ = url_;
     scoped_refptr<SecurityOrigin> security_origin =
-        SecurityOrigin::CreateUnique();
+        SecurityOrigin::CreateUniqueOpaque();
     // If we're supposed to inherit our security origin from our
     // owner, but we're also sandboxed, the only things we inherit are
     // the origin's potential trustworthiness and the ability to
diff --git a/third_party/blink/renderer/core/dom/document_test.cc b/third_party/blink/renderer/core/dom/document_test.cc
index 2a52cff..bbf5589e 100644
--- a/third_party/blink/renderer/core/dom/document_test.cc
+++ b/third_party/blink/renderer/core/dom/document_test.cc
@@ -537,7 +537,7 @@
 
 TEST_F(DocumentTest, OutgoingReferrerWithUniqueOrigin) {
   GetDocument().SetURL(KURL("https://www.example.com/hoge#fuga?piyo"));
-  GetDocument().SetSecurityOrigin(SecurityOrigin::CreateUnique());
+  GetDocument().SetSecurityOrigin(SecurityOrigin::CreateUniqueOpaque());
   EXPECT_EQ(String(), GetDocument().OutgoingReferrer());
 }
 
diff --git a/third_party/blink/renderer/core/dom/events/dom_window_event_queue.cc b/third_party/blink/renderer/core/dom/events/event_queue_impl.cc
similarity index 73%
rename from third_party/blink/renderer/core/dom/events/dom_window_event_queue.cc
rename to third_party/blink/renderer/core/dom/events/event_queue_impl.cc
index 29fe5d3..c40446a 100644
--- a/third_party/blink/renderer/core/dom/events/dom_window_event_queue.cc
+++ b/third_party/blink/renderer/core/dom/events/event_queue_impl.cc
@@ -24,7 +24,7 @@
  *
  */
 
-#include "third_party/blink/renderer/core/dom/events/dom_window_event_queue.h"
+#include "third_party/blink/renderer/core/dom/events/event_queue_impl.h"
 
 #include "base/macros.h"
 #include "third_party/blink/public/platform/task_type.h"
@@ -34,23 +34,24 @@
 
 namespace blink {
 
-DOMWindowEventQueue* DOMWindowEventQueue::Create(ExecutionContext* context) {
-  return new DOMWindowEventQueue(context);
+EventQueueImpl* EventQueueImpl::Create(ExecutionContext* context,
+                                       TaskType task_type) {
+  return new EventQueueImpl(context, task_type);
 }
 
-DOMWindowEventQueue::DOMWindowEventQueue(ExecutionContext* context)
-    : context_(context), is_closed_(false) {}
+EventQueueImpl::EventQueueImpl(ExecutionContext* context, TaskType task_type)
+    : context_(context), task_type_(task_type), is_closed_(false) {}
 
-DOMWindowEventQueue::~DOMWindowEventQueue() = default;
+EventQueueImpl::~EventQueueImpl() = default;
 
-void DOMWindowEventQueue::Trace(blink::Visitor* visitor) {
+void EventQueueImpl::Trace(blink::Visitor* visitor) {
   visitor->Trace(context_);
   visitor->Trace(queued_events_);
   EventQueue::Trace(visitor);
 }
 
-bool DOMWindowEventQueue::EnqueueEvent(const base::Location& from_here,
-                                       Event* event) {
+bool EventQueueImpl::EnqueueEvent(const base::Location& from_here,
+                                  Event* event) {
   if (is_closed_)
     return false;
 
@@ -61,29 +62,26 @@
   bool was_added = queued_events_.insert(event).is_new_entry;
   DCHECK(was_added);  // It should not have already been in the list.
 
-  // This queue is unthrottled because throttling IndexedDB events may break
-  // scenarios where several tabs, some of which are backgrounded, access
-  // the same database concurrently.
   scoped_refptr<base::SingleThreadTaskRunner> task_runner =
-      context_->GetTaskRunner(TaskType::kUnthrottled);
+      context_->GetTaskRunner(task_type_);
 
   // Pass the event as a weak persistent so that GC can collect an event-related
   // object like IDBTransaction as soon as possible.
   task_runner->PostTask(
-      FROM_HERE, WTF::Bind(&DOMWindowEventQueue::DispatchEvent,
-                           WrapPersistent(this), WrapWeakPersistent(event)));
+      FROM_HERE, WTF::Bind(&EventQueueImpl::DispatchEvent, WrapPersistent(this),
+                           WrapWeakPersistent(event)));
 
   return true;
 }
 
-bool DOMWindowEventQueue::CancelEvent(Event* event) {
+bool EventQueueImpl::CancelEvent(Event* event) {
   if (!RemoveEvent(event))
     return false;
   probe::AsyncTaskCanceled(event->target()->GetExecutionContext(), event);
   return true;
 }
 
-void DOMWindowEventQueue::Close() {
+void EventQueueImpl::Close() {
   is_closed_ = true;
   for (const auto& queued_event : queued_events_) {
     if (queued_event) {
@@ -94,7 +92,7 @@
   queued_events_.clear();
 }
 
-bool DOMWindowEventQueue::RemoveEvent(Event* event) {
+bool EventQueueImpl::RemoveEvent(Event* event) {
   auto found = queued_events_.find(event);
   if (found == queued_events_.end())
     return false;
@@ -102,7 +100,7 @@
   return true;
 }
 
-void DOMWindowEventQueue::DispatchEvent(Event* event) {
+void EventQueueImpl::DispatchEvent(Event* event) {
   if (!event || !RemoveEvent(event))
     return;
 
diff --git a/third_party/blink/renderer/core/dom/events/dom_window_event_queue.h b/third_party/blink/renderer/core/dom/events/event_queue_impl.h
similarity index 76%
rename from third_party/blink/renderer/core/dom/events/dom_window_event_queue.h
rename to third_party/blink/renderer/core/dom/events/event_queue_impl.h
index c03e731..7dbff48 100644
--- a/third_party/blink/renderer/core/dom/events/dom_window_event_queue.h
+++ b/third_party/blink/renderer/core/dom/events/event_queue_impl.h
@@ -24,22 +24,24 @@
  *
  */
 
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_DOM_WINDOW_EVENT_QUEUE_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_DOM_WINDOW_EVENT_QUEUE_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_EVENT_QUEUE_IMPL_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_EVENT_QUEUE_IMPL_H_
 
+#include "third_party/blink/public/platform/task_type.h"
 #include "third_party/blink/renderer/core/dom/events/event_queue.h"
 #include "third_party/blink/renderer/platform/wtf/linked_hash_set.h"
 
 namespace blink {
 
 class Event;
-class DOMWindowEventQueueTimer;
 class ExecutionContext;
 
-class DOMWindowEventQueue final : public EventQueue {
+class EventQueueImpl final : public EventQueue {
  public:
-  static DOMWindowEventQueue* Create(ExecutionContext*);
-  ~DOMWindowEventQueue() override;
+  // TODO(hajimehoshi): TaskType should be determined based on an event instead
+  // of specifying here.
+  static EventQueueImpl* Create(ExecutionContext*, TaskType);
+  ~EventQueueImpl() override;
 
   // EventQueue
   void Trace(blink::Visitor*) override;
@@ -48,18 +50,17 @@
   void Close() override;
 
  private:
-  explicit DOMWindowEventQueue(ExecutionContext*);
+  EventQueueImpl(ExecutionContext*, TaskType);
 
   bool RemoveEvent(Event*);
   void DispatchEvent(Event*);
 
   Member<ExecutionContext> context_;
+  const TaskType task_type_;
   HeapLinkedHashSet<Member<Event>> queued_events_;
   bool is_closed_;
-
-  friend class DOMWindowEventQueueTimer;
 };
 
 }  // namespace blink
 
-#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_DOM_WINDOW_EVENT_QUEUE_H_
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_EVENT_QUEUE_IMPL_H_
diff --git a/third_party/blink/renderer/core/editing/BUILD.gn b/third_party/blink/renderer/core/editing/BUILD.gn
index 2db2e5e..a51b166f 100644
--- a/third_party/blink/renderer/core/editing/BUILD.gn
+++ b/third_party/blink/renderer/core/editing/BUILD.gn
@@ -307,6 +307,8 @@
     "text_granularity.h",
     "text_offset_mapping.cc",
     "text_offset_mapping.h",
+    "text_segments.cc",
+    "text_segments.h",
     "visible_position.cc",
     "visible_position.h",
     "visible_selection.cc",
diff --git a/third_party/blink/renderer/core/editing/text_offset_mapping.cc b/third_party/blink/renderer/core/editing/text_offset_mapping.cc
index edddf12..b507f7b 100644
--- a/third_party/blink/renderer/core/editing/text_offset_mapping.cc
+++ b/third_party/blink/renderer/core/editing/text_offset_mapping.cc
@@ -196,8 +196,7 @@
 PositionInFlatTree TextOffsetMapping::GetPositionAfter(unsigned offset) const {
   DCHECK_LE(offset, text16_.length());
   CharacterIteratorInFlatTree iterator(range_, behavior_);
-  if (offset > 0)
-    iterator.Advance(offset - 1);
+  iterator.Advance(offset);
   return iterator.GetPositionAfter();
 }
 
diff --git a/third_party/blink/renderer/core/editing/text_offset_mapping_test.cc b/third_party/blink/renderer/core/editing/text_offset_mapping_test.cc
index 7976375..7730e281 100644
--- a/third_party/blink/renderer/core/editing/text_offset_mapping_test.cc
+++ b/third_party/blink/renderer/core/editing/text_offset_mapping_test.cc
@@ -348,13 +348,13 @@
 
 TEST_P(ParameterizedTextOffsetMappingTest, GetPositionAfter) {
   EXPECT_EQ("  0|12  456  ", GetPositionAfter("  012  456  ", 0));
-  EXPECT_EQ("  0|12  456  ", GetPositionAfter("  012  456  ", 1));
-  EXPECT_EQ("  01|2  456  ", GetPositionAfter("  012  456  ", 2));
-  EXPECT_EQ("  012|  456  ", GetPositionAfter("  012  456  ", 3));
-  EXPECT_EQ("  012 | 456  ", GetPositionAfter("  012  456  ", 4));
-  EXPECT_EQ("  012  4|56  ", GetPositionAfter("  012  456  ", 5));
-  EXPECT_EQ("  012  45|6  ", GetPositionAfter("  012  456  ", 6));
-  EXPECT_EQ("  012  456|  ", GetPositionAfter("  012  456  ", 7));
+  EXPECT_EQ("  01|2  456  ", GetPositionAfter("  012  456  ", 1));
+  EXPECT_EQ("  012|  456  ", GetPositionAfter("  012  456  ", 2));
+  EXPECT_EQ("  012 | 456  ", GetPositionAfter("  012  456  ", 3));
+  EXPECT_EQ("  012  4|56  ", GetPositionAfter("  012  456  ", 4));
+  EXPECT_EQ("  012  45|6  ", GetPositionAfter("  012  456  ", 5));
+  EXPECT_EQ("  012  456|  ", GetPositionAfter("  012  456  ", 6));
+  EXPECT_EQ("  012  456  |", GetPositionAfter("  012  456  ", 7));
   // We hit DCHECK for offset 8, because we walk on "012 456".
 }
 
diff --git a/third_party/blink/renderer/core/editing/text_segments.cc b/third_party/blink/renderer/core/editing/text_segments.cc
new file mode 100644
index 0000000..4f3e19f7
--- /dev/null
+++ b/third_party/blink/renderer/core/editing/text_segments.cc
@@ -0,0 +1,59 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/editing/text_segments.h"
+
+#include "third_party/blink/renderer/core/editing/position.h"
+#include "third_party/blink/renderer/core/editing/text_offset_mapping.h"
+
+namespace blink {
+
+TextSegments::Finder::Position::Position() = default;
+
+TextSegments::Finder::Position::Position(unsigned offset, Type type)
+    : offset_(offset), type_(type) {
+  DCHECK_NE(type, kNone);
+}
+
+// static
+TextSegments::Finder::Position TextSegments::Finder::Position::Before(
+    unsigned offset) {
+  return Position(offset, kBefore);
+}
+
+// static
+TextSegments::Finder::Position TextSegments::Finder::Position::After(
+    unsigned offset) {
+  return Position(offset, kAfter);
+}
+
+unsigned TextSegments::Finder::Position::Offset() const {
+  DCHECK(type_ == kBefore || type_ == kAfter) << type_;
+  return offset_;
+}
+
+// static
+PositionInFlatTree TextSegments::FindBoundaryForward(
+    const PositionInFlatTree& position,
+    Finder* finder) {
+  DCHECK(position.IsNotNull());
+  PositionInFlatTree last_position = position;
+  for (const auto& inline_contents :
+       TextOffsetMapping::ForwardRangeOf(position)) {
+    const TextOffsetMapping mapping(inline_contents);
+    const String text = mapping.GetText();
+    const unsigned offset =
+        last_position == position ? mapping.ComputeTextOffset(position) : 0;
+    const TextSegments::Finder::Position result = finder->Find(text, offset);
+    if (result.IsBefore())
+      return mapping.GetPositionBefore(result.Offset());
+    if (result.IsAfter())
+      return mapping.GetPositionAfter(result.Offset());
+    DCHECK(result.IsNone());
+    last_position = mapping.GetRange().EndPosition();
+  }
+  return last_position;
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/editing/text_segments.h b/third_party/blink/renderer/core/editing/text_segments.h
new file mode 100644
index 0000000..f8813fc
--- /dev/null
+++ b/third_party/blink/renderer/core/editing/text_segments.h
@@ -0,0 +1,65 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_TEXT_SEGMENTS_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_TEXT_SEGMENTS_H_
+
+#include "base/optional.h"
+#include "third_party/blink/renderer/core/editing/forward.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
+#include "third_party/blink/renderer/platform/wtf/forward.h"
+
+namespace blink {
+
+// Provides functions for finding boundary of text segments.
+class TextSegments final {
+  STATIC_ONLY(TextSegments);
+
+ public:
+  // The interface to find boundary of text segment.
+  class Finder {
+   public:
+    class Position final {
+      STACK_ALLOCATED();
+
+     public:
+      Position();
+
+      static Position Before(unsigned offset);
+      static Position After(unsigned offset);
+
+      bool IsAfter() const { return type_ == kAfter; }
+      bool IsBefore() const { return type_ == kBefore; }
+      bool IsNone() const { return type_ == kNone; }
+
+      unsigned Offset() const;
+
+     private:
+      enum Type { kNone, kBefore, kAfter };
+
+      Position(unsigned value, Type type);
+
+      const unsigned offset_ = 0;
+      const Type type_ = kNone;
+    };
+
+    // Returns a text segment boundary position in |text| from |offset|.
+    // Note: |text| must contains character 16.
+    // Note: Since implementations can have state, |Find()| function isn't
+    // marked |const| intentionally.
+    virtual Position Find(const String text, unsigned offset) = 0;
+  };
+
+  // TODO(editing-dev): We should have |FindBoundaryBackward()|.
+
+  // Returns a boundary position found by |finder| followed by |position|
+  // (inclusive). |finder| can be stateful or stateless.
+  static PositionInFlatTree FindBoundaryForward(
+      const PositionInFlatTree& position,
+      Finder* finder);
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_TEXT_SEGMENTS_H_
diff --git a/third_party/blink/renderer/core/editing/visible_units.cc b/third_party/blink/renderer/core/editing/visible_units.cc
index 91361dd1..9d2d5ff 100644
--- a/third_party/blink/renderer/core/editing/visible_units.cc
+++ b/third_party/blink/renderer/core/editing/visible_units.cc
@@ -45,7 +45,6 @@
 #include "third_party/blink/renderer/core/editing/position_iterator.h"
 #include "third_party/blink/renderer/core/editing/position_with_affinity.h"
 #include "third_party/blink/renderer/core/editing/text_affinity.h"
-#include "third_party/blink/renderer/core/editing/text_offset_mapping.h"
 #include "third_party/blink/renderer/core/editing/visible_position.h"
 #include "third_party/blink/renderer/core/editing/visible_selection.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -558,26 +557,6 @@
   return PreviousBoundaryAlgorithm(visible_position, search_function);
 }
 
-// Note: This function is used for finding word and sentence boundary.
-PositionInFlatTree FindBoundaryForward(
-    const PositionInFlatTree& position,
-    std::function<int(const UChar*, int length, int offset)> find_forward) {
-  DCHECK(position.IsNotNull());
-  PositionInFlatTree last_position = position;
-  for (const auto& inline_contents :
-       TextOffsetMapping::ForwardRangeOf(position)) {
-    const TextOffsetMapping mapping(inline_contents);
-    const String text = mapping.GetText();
-    const int offset =
-        last_position == position ? mapping.ComputeTextOffset(position) : 0;
-    const int result = find_forward(text.Characters16(), text.length(), offset);
-    if (offset < result)
-      return mapping.GetPositionAfter(result);
-    last_position = mapping.GetRange().EndPosition();
-  }
-  return last_position;
-}
-
 // ---------
 
 template <typename Strategy>
diff --git a/third_party/blink/renderer/core/editing/visible_units.h b/third_party/blink/renderer/core/editing/visible_units.h
index 75316d3..80e867d 100644
--- a/third_party/blink/renderer/core/editing/visible_units.h
+++ b/third_party/blink/renderer/core/editing/visible_units.h
@@ -283,13 +283,6 @@
 PositionInFlatTree PreviousBoundary(const VisiblePositionInFlatTree&,
                                     BoundarySearchFunction);
 
-// Returns a boundary position after position or |position|. A boundary is
-// defined by |find_function|.
-// Note: |position| cannot be null position.
-PositionInFlatTree FindBoundaryForward(
-    const PositionInFlatTree& position,
-    std::function<int(const UChar*, int length, int offset)> find_function);
-
 CORE_EXPORT PositionWithAffinity
 AdjustForwardPositionToAvoidCrossingEditingBoundaries(
     const PositionWithAffinity&,
diff --git a/third_party/blink/renderer/core/editing/visible_units_sentence.cc b/third_party/blink/renderer/core/editing/visible_units_sentence.cc
index 288f2afc..7e38f34 100644
--- a/third_party/blink/renderer/core/editing/visible_units_sentence.cc
+++ b/third_party/blink/renderer/core/editing/visible_units_sentence.cc
@@ -32,7 +32,7 @@
 
 #include "third_party/blink/renderer/core/editing/editing_utilities.h"
 #include "third_party/blink/renderer/core/editing/ephemeral_range.h"
-#include "third_party/blink/renderer/core/editing/text_offset_mapping.h"
+#include "third_party/blink/renderer/core/editing/text_segments.h"
 #include "third_party/blink/renderer/core/editing/visible_position.h"
 #include "third_party/blink/renderer/platform/text/text_break_iterator.h"
 
@@ -40,34 +40,6 @@
 
 namespace {
 
-// TODO(editing-dev): We should move |FindNonSpaceCharacter()| to
-// "text_boundaries.cc" with |FindNextSentenceBoundaryForward|.
-int FindNonSpaceCharacter(const UChar* characters16,
-                          int length,
-                          int passed_offset) {
-  for (int offset = passed_offset; offset < length; ++offset) {
-    if (characters16[offset] != ' ')
-      return offset;
-  }
-  return length;
-}
-
-// TODO(editing-dev): We should move |FindNonSpaceCharacter()| to
-// "text_boundaries.cc" like |FindWordEndBoundary()|.
-int FindNextSentenceBoundaryForward(const UChar* characters16,
-                                    int length,
-                                    int passed_offset) {
-  DCHECK_GE(length, 0);
-  DCHECK_GE(passed_offset, 0);
-  DCHECK_LE(passed_offset, length);
-  TextBreakIterator* iterator = SentenceBreakIterator(characters16, length);
-  // "move_by_sentence_boundary.html" requires to skip a space characters
-  // between sentences.
-  const int offset = FindNonSpaceCharacter(characters16, length, passed_offset);
-  const int result = iterator->following(offset);
-  return result == kTextBreakDone ? length : result;
-}
-
 unsigned NextSentencePositionBoundary(const UChar* characters,
                                       unsigned length,
                                       unsigned,
@@ -104,7 +76,34 @@
 // TODO(yosin) This includes the space after the punctuation that marks the end
 // of the sentence.
 PositionInFlatTree EndOfSentenceInternal(const PositionInFlatTree& position) {
-  return FindBoundaryForward(position, FindNextSentenceBoundaryForward);
+  class Finder final : public TextSegments::Finder {
+    STACK_ALLOCATED();
+
+   public:
+    Position Find(const String text, unsigned passed_offset) final {
+      DCHECK_LE(passed_offset, text.length());
+      TextBreakIterator* iterator =
+          SentenceBreakIterator(text.Characters16(), text.length());
+      // "move_by_sentence_boundary.html" requires to skip a space characters
+      // between sentences.
+      const unsigned offset = FindNonSpaceCharacter(text, passed_offset);
+      const int result = iterator->following(offset);
+      if (result == kTextBreakDone)
+        return Position();
+      return result == 0 ? Position::Before(0) : Position::After(result - 1);
+    }
+
+   private:
+    static unsigned FindNonSpaceCharacter(const String text,
+                                          unsigned passed_offset) {
+      for (unsigned offset = passed_offset; offset < text.length(); ++offset) {
+        if (text[offset] != ' ')
+          return offset;
+      }
+      return text.length();
+    }
+  } finder;
+  return TextSegments::FindBoundaryForward(position, &finder);
 }
 
 template <typename Strategy>
diff --git a/third_party/blink/renderer/core/editing/visible_units_word.cc b/third_party/blink/renderer/core/editing/visible_units_word.cc
index f961c35..37b2e545 100644
--- a/third_party/blink/renderer/core/editing/visible_units_word.cc
+++ b/third_party/blink/renderer/core/editing/visible_units_word.cc
@@ -32,10 +32,12 @@
 
 #include "third_party/blink/renderer/core/editing/editing_utilities.h"
 #include "third_party/blink/renderer/core/editing/ephemeral_range.h"
+#include "third_party/blink/renderer/core/editing/text_segments.h"
 #include "third_party/blink/renderer/core/editing/visible_position.h"
 #include "third_party/blink/renderer/core/layout/layout_block_flow.h"
 #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
 #include "third_party/blink/renderer/platform/text/text_boundaries.h"
+#include "third_party/blink/renderer/platform/text/text_break_iterator.h"
 
 namespace blink {
 
@@ -80,7 +82,29 @@
 
 PositionInFlatTree NextWordPositionInternal(
     const PositionInFlatTree& position) {
-  return FindBoundaryForward(position, FindNextWordForward);
+  class Finder final : public TextSegments::Finder {
+    STACK_ALLOCATED();
+
+   private:
+    Position Find(const String text, unsigned offset) final {
+      DCHECK_LE(offset, text.length());
+      if (offset == text.length() || text.length() == 0)
+        return Position();
+      TextBreakIterator* it =
+          WordBreakIterator(text.Characters16(), text.length());
+      for (int runner = it->following(offset); runner != kTextBreakDone;
+           runner = it->following(runner)) {
+        // We stop searching when the character preceding the break is
+        // alphanumeric or underscore.
+        if (static_cast<unsigned>(runner) < text.length() &&
+            (WTF::Unicode::IsAlphanumeric(text[runner - 1]) ||
+             text[runner - 1] == kLowLineCharacter))
+          return Position::After(runner - 1);
+      }
+      return Position::After(text.length() - 1);
+    }
+  } finder;
+  return TextSegments::FindBoundaryForward(position, &finder);
 }
 
 unsigned PreviousWordPositionBoundary(
diff --git a/third_party/blink/renderer/core/exported/web_frame_test.cc b/third_party/blink/renderer/core/exported/web_frame_test.cc
index c29fa7c..d3d1a9b 100644
--- a/third_party/blink/renderer/core/exported/web_frame_test.cc
+++ b/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -9712,7 +9712,7 @@
   WebFrame* target_frame = MainFrame()->FirstChild();
   target_frame->Swap(remote_frame);
   remote_frame->SetReplicatedOrigin(
-      WebSecurityOrigin(SecurityOrigin::CreateUnique()), false);
+      WebSecurityOrigin(SecurityOrigin::CreateUniqueOpaque()), false);
 
   // Invoking setTimeout should throw a security error.
   {
@@ -9794,7 +9794,7 @@
   WebRemoteFrame* remote_frame = FrameTestHelpers::CreateRemote();
   LastChild(MainFrame())->Swap(remote_frame);
   remote_frame->SetReplicatedOrigin(
-      WebSecurityOrigin(SecurityOrigin::CreateUnique()), false);
+      WebSecurityOrigin(SecurityOrigin::CreateUniqueOpaque()), false);
   v8::Local<v8::Value> remote_window_property =
       MainFrame()->ExecuteScriptAndReturnValue(
           WebScriptSource("window[2].foo"));
@@ -9824,7 +9824,7 @@
   WebRemoteFrame* remote_parent_frame = FrameTestHelpers::CreateRemote();
   MainFrame()->Swap(remote_parent_frame);
   remote_parent_frame->SetReplicatedOrigin(
-      WebSecurityOrigin(SecurityOrigin::CreateUnique()), false);
+      WebSecurityOrigin(SecurityOrigin::CreateUniqueOpaque()), false);
 
   WebLocalFrame* child_frame =
       FrameTestHelpers::CreateLocalChild(*remote_parent_frame);
@@ -9852,7 +9852,7 @@
   WebRemoteFrame* remote_parent_frame = FrameTestHelpers::CreateRemote();
   MainFrame()->Swap(remote_parent_frame);
   remote_parent_frame->SetReplicatedOrigin(
-      WebSecurityOrigin(SecurityOrigin::CreateUnique()), false);
+      WebSecurityOrigin(SecurityOrigin::CreateUniqueOpaque()), false);
 
   WebLocalFrame* child_frame =
       FrameTestHelpers::CreateLocalChild(*remote_parent_frame);
@@ -9981,7 +9981,7 @@
   WebRemoteFrame* remote_frame = FrameTestHelpers::CreateRemote(&remote_client);
   MainFrame()->FirstChild()->Swap(remote_frame);
   remote_frame->SetReplicatedOrigin(
-      WebSecurityOrigin(SecurityOrigin::CreateUnique()), false);
+      WebSecurityOrigin(SecurityOrigin::CreateUniqueOpaque()), false);
 
   ASSERT_TRUE(MainFrame()->FirstChild()->IsWebRemoteFrame());
   LocalDOMWindow* main_window =
diff --git a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
index 0895b17..bf6387b 100644
--- a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
@@ -458,9 +458,6 @@
 void WebPluginContainerImpl::EnqueueMessageEvent(
     const WebDOMMessageEvent& event) {
   static_cast<Event*>(event)->SetTarget(element_);
-  CHECK(element_);
-  CHECK(element_->GetExecutionContext());
-  CHECK(element_->GetExecutionContext()->GetEventQueue());
   element_->GetExecutionContext()->GetEventQueue()->EnqueueEvent(FROM_HERE,
                                                                  event);
 }
diff --git a/third_party/blink/renderer/core/frame/frame_test_helpers.cc b/third_party/blink/renderer/core/frame/frame_test_helpers.cc
index db80576..5325cfd 100644
--- a/third_party/blink/renderer/core/frame/frame_test_helpers.cc
+++ b/third_party/blink/renderer/core/frame/frame_test_helpers.cc
@@ -248,7 +248,7 @@
       ParsedFeaturePolicy(), client, nullptr));
   client->Bind(frame, std::move(owned_client));
   if (!security_origin)
-    security_origin = SecurityOrigin::CreateUnique();
+    security_origin = SecurityOrigin::CreateUniqueOpaque();
   frame->GetFrame()->GetSecurityContext()->SetReplicatedOrigin(
       std::move(security_origin));
   return frame;
@@ -332,7 +332,7 @@
   web_remote_frame_client->Bind(frame,
                                 std::move(owned_web_remote_frame_client));
   if (!security_origin)
-    security_origin = SecurityOrigin::CreateUnique();
+    security_origin = SecurityOrigin::CreateUniqueOpaque();
   frame->GetFrame()->GetSecurityContext()->SetReplicatedOrigin(
       std::move(security_origin));
   return web_view_;
diff --git a/third_party/blink/renderer/core/frame/history_test.cc b/third_party/blink/renderer/core/frame/history_test.cc
index d56b90db..0dfee51 100644
--- a/third_party/blink/renderer/core/frame/history_test.cc
+++ b/third_party/blink/renderer/core/frame/history_test.cc
@@ -109,7 +109,7 @@
     KURL url(test.url);
     KURL document_url(test.document_url);
     scoped_refptr<const SecurityOrigin> document_origin =
-        SecurityOrigin::CreateUnique();
+        SecurityOrigin::CreateUniqueOpaque();
     EXPECT_EQ(test.expected, History::CanChangeToUrl(url, document_origin.get(),
                                                      document_url));
   }
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
index 6b2b011c..093f2cd3 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -47,7 +47,7 @@
 #include "third_party/blink/renderer/core/css/style_media.h"
 #include "third_party/blink/renderer/core/dom/computed_accessible_node.h"
 #include "third_party/blink/renderer/core/dom/dom_implementation.h"
-#include "third_party/blink/renderer/core/dom/events/dom_window_event_queue.h"
+#include "third_party/blink/renderer/core/dom/events/event_queue_impl.h"
 #include "third_party/blink/renderer/core/dom/events/scoped_event_queue.h"
 #include "third_party/blink/renderer/core/dom/frame_request_callback_collection.h"
 #include "third_party/blink/renderer/core/dom/scripted_idle_task_controller.h"
@@ -319,7 +319,14 @@
   ClearDocument();
 
   document_ = CreateDocument(mime_type, init, force_xhtml);
-  event_queue_ = DOMWindowEventQueue::Create(document_.Get());
+
+  // This queue is unthrottled because throttling IndexedDB events may break
+  // scenarios where several tabs, some of which are backgrounded, access
+  // the same database concurrently.
+  // TODO(hajimehoshi): Task type should be determined by a posted event instead
+  // of specifying here.
+  event_queue_ =
+      EventQueueImpl::Create(document_.Get(), TaskType::kUnthrottled);
   document_->Initialize();
 
   if (!GetFrame())
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.h b/third_party/blink/renderer/core/frame/local_dom_window.h
index 5dafab5..3648e72 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.h
+++ b/third_party/blink/renderer/core/frame/local_dom_window.h
@@ -50,9 +50,9 @@
 class DocumentInit;
 class DOMSelection;
 class DOMVisualViewport;
-class DOMWindowEventQueue;
 class Element;
 class EventQueue;
+class EventQueueImpl;
 class ExceptionState;
 class External;
 class FrameConsole;
@@ -381,7 +381,7 @@
 
   mutable Member<ApplicationCache> application_cache_;
 
-  Member<DOMWindowEventQueue> event_queue_;
+  Member<EventQueueImpl> event_queue_;
   scoped_refptr<SerializedScriptValue> pending_state_object_;
 
   HeapHashSet<Member<PostMessageTimer>> post_message_timers_;
diff --git a/third_party/blink/renderer/core/fullscreen/fullscreen.h b/third_party/blink/renderer/core/fullscreen/fullscreen.h
index ac2a76f..38fea66 100644
--- a/third_party/blink/renderer/core/fullscreen/fullscreen.h
+++ b/third_party/blink/renderer/core/fullscreen/fullscreen.h
@@ -31,6 +31,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_FULLSCREEN_FULLSCREEN_H_
 
 #include "base/memory/scoped_refptr.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h"
 #include "third_party/blink/renderer/core/dom/document.h"
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc
index e10a7577..bd561ab7 100644
--- a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc
+++ b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc
@@ -96,26 +96,26 @@
   if (this->IsOffscreenCanvas() && this->IsNeutered()) {
     exception_state.ThrowDOMException(kInvalidStateError,
                                       "OffscreenCanvas object is detached.");
-    return exception_state.Reject(script_state);
+    return ScriptPromise();
   }
 
   if (!this->OriginClean()) {
     error_msg << "Tainted " << object_name << " may not be exported.";
     exception_state.ThrowSecurityError(error_msg.str().c_str());
-    return exception_state.Reject(script_state);
+    return ScriptPromise();
   }
 
   if (!this->IsPaintable() || Size().IsEmpty()) {
     error_msg << "The size of " << object_name << " iz zero.";
     exception_state.ThrowDOMException(kIndexSizeError, error_msg.str().c_str());
-    return exception_state.Reject(script_state);
+    return ScriptPromise();
   }
 
   if (!RenderingContext()) {
     error_msg << object_name << " has no rendering context.";
     exception_state.ThrowDOMException(kInvalidStateError,
                                       error_msg.str().c_str());
-    return exception_state.Reject(script_state);
+    return ScriptPromise();
   }
 
   double start_time = WTF::CurrentTimeTicksInSeconds();
@@ -138,7 +138,7 @@
   }
   exception_state.ThrowDOMException(kNotReadableError,
                                     "Readback of the source image has failed.");
-  return exception_state.Reject(script_state);
+  return ScriptPromise();
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/html_attribute_names.json5 b/third_party/blink/renderer/core/html/html_attribute_names.json5
index d7d223e..7e379723 100644
--- a/third_party/blink/renderer/core/html/html_attribute_names.json5
+++ b/third_party/blink/renderer/core/html/html_attribute_names.json5
@@ -96,6 +96,7 @@
     "http-equiv",
     "id",
     "imgsizes",
+    "importance",
     "incremental",
     "inert",
     "inputmode",
diff --git a/third_party/blink/renderer/core/html/html_frame_element_base.cc b/third_party/blink/renderer/core/html/html_frame_element_base.cc
index 3ec1385c..e770805 100644
--- a/third_party/blink/renderer/core/html/html_frame_element_base.cc
+++ b/third_party/blink/renderer/core/html/html_frame_element_base.cc
@@ -168,7 +168,7 @@
 HTMLFrameElementBase::GetOriginForFeaturePolicy() const {
   // Sandboxed frames have a unique origin.
   if (GetSandboxFlags() & kSandboxOrigin)
-    return SecurityOrigin::CreateUnique();
+    return SecurityOrigin::CreateUniqueOpaque();
 
   // If the frame will inherit its origin from the owner, then use the owner's
   // origin when constructing the container policy.
diff --git a/third_party/blink/renderer/core/html/html_frame_owner_element.h b/third_party/blink/renderer/core/html/html_frame_owner_element.h
index 0f93046..171854f 100644
--- a/third_party/blink/renderer/core/html/html_frame_owner_element.h
+++ b/third_party/blink/renderer/core/html/html_frame_owner_element.h
@@ -140,7 +140,7 @@
   // This method is intended to be overridden by specific frame classes.
   virtual scoped_refptr<const SecurityOrigin> GetOriginForFeaturePolicy()
       const {
-    return SecurityOrigin::CreateUnique();
+    return SecurityOrigin::CreateUniqueOpaque();
   }
 
   // Return a feature policy container policy for this frame, based on the
diff --git a/third_party/blink/renderer/core/html/html_image_element.idl b/third_party/blink/renderer/core/html/html_image_element.idl
index 6e46e502..201caa6 100644
--- a/third_party/blink/renderer/core/html/html_image_element.idl
+++ b/third_party/blink/renderer/core/html/html_image_element.idl
@@ -41,6 +41,7 @@
     readonly attribute DOMString currentSrc;
     [CEReactions, Reflect, ReflectOnly=("","no-referrer","origin","no-referrer-when-downgrade","origin-when-cross-origin","unsafe-url"), ReflectMissing="", ReflectInvalid=""] attribute DOMString referrerPolicy;
     [RuntimeEnabled=ImageDecodingAttribute, CEReactions, Reflect, ReflectOnly=("async", "sync", "auto"), ReflectMissing="auto", ReflectInvalid="auto"] attribute DOMString decoding;
+    [CEReactions, RuntimeEnabled=PriorityHints, Reflect, ReflectOnly=("low", "auto", "high"), ReflectMissing="auto", ReflectInvalid="auto"] attribute DOMString importance;
 
     // obsolete members
     // https://html.spec.whatwg.org/#HTMLImageElement-partial
diff --git a/third_party/blink/renderer/core/html/html_link_element.cc b/third_party/blink/renderer/core/html/html_link_element.cc
index bc541dbe..9a6c8f4b3 100644
--- a/third_party/blink/renderer/core/html/html_link_element.cc
+++ b/third_party/blink/renderer/core/html/html_link_element.cc
@@ -105,6 +105,9 @@
     Process();
   } else if (name == integrityAttr) {
     integrity_ = value;
+  } else if (name == importanceAttr &&
+             RuntimeEnabledFeatures::PriorityHintsEnabled()) {
+    importance_ = value;
   } else if (name == disabledAttr) {
     UseCounter::Count(GetDocument(), WebFeature::kHTMLLinkElementDisabled);
     if (LinkStyle* link = GetLinkStyle())
diff --git a/third_party/blink/renderer/core/html/html_link_element.h b/third_party/blink/renderer/core/html/html_link_element.h
index 2547397..410014ec 100644
--- a/third_party/blink/renderer/core/html/html_link_element.h
+++ b/third_party/blink/renderer/core/html/html_link_element.h
@@ -60,6 +60,7 @@
   String TypeValue() const { return type_; }
   String AsValue() const { return as_; }
   String IntegrityValue() const { return integrity_; }
+  String ImportanceValue() const { return importance_; }
   ReferrerPolicy GetReferrerPolicy() const { return referrer_policy_; }
   const LinkRelAttribute& RelAttribute() const { return rel_attribute_; }
   DOMTokenList& relList() const {
@@ -154,6 +155,7 @@
   String as_;
   String media_;
   String integrity_;
+  String importance_;
   ReferrerPolicy referrer_policy_;
   Member<DOMTokenList> sizes_;
   Vector<IntSize> icon_sizes_;
diff --git a/third_party/blink/renderer/core/html/html_link_element.idl b/third_party/blink/renderer/core/html/html_link_element.idl
index 2465804..7a6b3b9 100644
--- a/third_party/blink/renderer/core/html/html_link_element.idl
+++ b/third_party/blink/renderer/core/html/html_link_element.idl
@@ -35,6 +35,7 @@
     [Reflect, ReflectOnly=("script","style","image","video", "audio", "track", "font", "fetch")] attribute DOMString as;
     [CEReactions, Reflect, ReflectOnly=("","no-referrer","origin","no-referrer-when-downgrade","origin-when-cross-origin","unsafe-url"), ReflectMissing="", ReflectInvalid=""] attribute DOMString referrerPolicy;
     [PutForwards=value] readonly attribute DOMTokenList sizes;
+    [CEReactions, RuntimeEnabled=PriorityHints, Reflect, ReflectOnly=("low", "auto", "high"), ReflectMissing="auto", ReflectInvalid="auto"] attribute DOMString importance;
 
     // obsolete members
     // https://html.spec.whatwg.org/#HTMLLinkElement-partial
diff --git a/third_party/blink/renderer/core/html/link_style.cc b/third_party/blink/renderer/core/html/link_style.cc
index 7cf0d25..2ea25b29e 100644
--- a/third_party/blink/renderer/core/html/link_style.cc
+++ b/third_party/blink/renderer/core/html/link_style.cc
@@ -12,6 +12,7 @@
 #include "third_party/blink/renderer/core/html/cross_origin_attribute.h"
 #include "third_party/blink/renderer/core/html/html_link_element.h"
 #include "third_party/blink/renderer/core/html_names.h"
+#include "third_party/blink/renderer/core/loader/importance_attribute.h"
 #include "third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.h"
 #include "third_party/blink/renderer/core/loader/subresource_integrity_helper.h"
 #include "third_party/blink/renderer/platform/histogram.h"
@@ -300,6 +301,11 @@
         referrer_policy, url, GetDocument().OutgoingReferrer()));
   }
 
+  if (RuntimeEnabledFeatures::PriorityHintsEnabled()) {
+    resource_request.SetFetchImportanceMode(
+        GetFetchImportanceAttributeValue(owner_->ImportanceValue()));
+  }
+
   ResourceLoaderOptions options;
   options.initiator_info.name = owner_->localName();
   FetchParameters params(resource_request, options);
@@ -352,7 +358,8 @@
       GetCrossOriginAttributeValue(owner_->FastGetAttribute(crossoriginAttr)),
       owner_->TypeValue().DeprecatedLower(),
       owner_->AsValue().DeprecatedLower(), owner_->Media().DeprecatedLower(),
-      owner_->nonce(), owner_->IntegrityValue(), owner_->GetReferrerPolicy(),
+      owner_->nonce(), owner_->IntegrityValue(),
+      owner_->ImportanceValue().LowerASCII(), owner_->GetReferrerPolicy(),
       owner_->GetNonEmptyURLAttribute(hrefAttr),
       owner_->FastGetAttribute(srcsetAttr),
       owner_->FastGetAttribute(imgsizesAttr));
diff --git a/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc b/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc
index aa1b940..d9b7c61c 100644
--- a/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc
+++ b/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc
@@ -29,6 +29,7 @@
 
 #include <memory>
 #include "base/optional.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom-shared.h"
 #include "third_party/blink/renderer/core/css/media_list.h"
 #include "third_party/blink/renderer/core/css/media_query_evaluator.h"
 #include "third_party/blink/renderer/core/css/media_values_cached.h"
@@ -45,6 +46,7 @@
 #include "third_party/blink/renderer/core/html/parser/html_tokenizer.h"
 #include "third_party/blink/renderer/core/html_names.h"
 #include "third_party/blink/renderer/core/input_type_names.h"
+#include "third_party/blink/renderer/core/loader/importance_attribute.h"
 #include "third_party/blink/renderer/core/loader/link_loader.h"
 #include "third_party/blink/renderer/core/loader/subresource_integrity_helper.h"
 #include "third_party/blink/renderer/core/script/script_loader.h"
@@ -132,6 +134,8 @@
         source_size_set_(false),
         defer_(FetchParameters::kNoDefer),
         cross_origin_(kCrossOriginAttributeNotSet),
+        importance_(mojom::FetchImportanceMode::kImportanceAuto),
+        importance_mode_set_(false),
         media_values_(media_values),
         referrer_policy_set_(false),
         referrer_policy_(kReferrerPolicyDefault),
@@ -262,6 +266,7 @@
     }
 
     request->SetCrossOrigin(cross_origin_);
+    request->SetImportance(importance_);
     request->SetNonce(nonce_);
     request->SetCharset(Charset());
     request->SetDefer(defer_);
@@ -321,6 +326,9 @@
                Match(attribute_name, referrerpolicyAttr) &&
                !attribute_value.IsNull()) {
       SetReferrerPolicy(attribute_value, kSupportReferrerPolicyLegacyKeywords);
+    } else if (!importance_mode_set_ && Match(attribute_name, importanceAttr) &&
+               RuntimeEnabledFeatures::PriorityHintsEnabled()) {
+      SetImportance(attribute_value);
     }
   }
 
@@ -375,6 +383,9 @@
       srcset_attribute_value_ = attribute_value;
     } else if (Match(attribute_name, imgsizesAttr) && !source_size_set_) {
       ParseSourceSize(attribute_value);
+    } else if (!importance_mode_set_ && Match(attribute_name, importanceAttr) &&
+               RuntimeEnabledFeatures::PriorityHintsEnabled()) {
+      SetImportance(attribute_value);
     }
   }
 
@@ -569,6 +580,12 @@
         attribute_value, legacy_keywords_support, &referrer_policy_);
   }
 
+  void SetImportance(const String& importance) {
+    DCHECK(RuntimeEnabledFeatures::PriorityHintsEnabled());
+    importance_mode_set_ = true;
+    importance_ = GetFetchImportanceAttributeValue(importance);
+  }
+
   void SetNonce(const String& nonce) { nonce_ = nonce; }
 
   void SetDefer(FetchParameters::DeferOption defer) { defer_ = defer; }
@@ -596,6 +613,8 @@
   bool source_size_set_;
   FetchParameters::DeferOption defer_;
   CrossOriginAttributeValue cross_origin_;
+  mojom::FetchImportanceMode importance_;
+  bool importance_mode_set_;
   String nonce_;
   Member<MediaValuesCached> media_values_;
   bool referrer_policy_set_;
diff --git a/third_party/blink/renderer/core/html/parser/preload_request.cc b/third_party/blink/renderer/core/html/parser/preload_request.cc
index ff177dd..37d3d70 100644
--- a/third_party/blink/renderer/core/html/parser/preload_request.cc
+++ b/third_party/blink/renderer/core/html/parser/preload_request.cc
@@ -13,6 +13,7 @@
 #include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
+#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 #include "third_party/blink/renderer/platform/weborigin/security_policy.h"
 
 namespace blink {
@@ -44,6 +45,8 @@
   resource_request.SetRequestContext(ResourceFetcher::DetermineRequestContext(
       resource_type_, is_image_set_, false));
 
+  resource_request.SetFetchImportanceMode(importance_);
+
   ResourceLoaderOptions options;
   options.initiator_info = initiator_info;
   FetchParameters params(resource_request, options);
diff --git a/third_party/blink/renderer/core/html/parser/preload_request.h b/third_party/blink/renderer/core/html/parser/preload_request.h
index 17555a7..04d1ac5 100644
--- a/third_party/blink/renderer/core/html/parser/preload_request.h
+++ b/third_party/blink/renderer/core/html/parser/preload_request.h
@@ -8,6 +8,7 @@
 #include <memory>
 
 #include "base/memory/ptr_util.h"
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom-shared.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/script/script.h"
 #include "third_party/blink/renderer/platform/cross_origin_attribute_value.h"
@@ -76,6 +77,11 @@
   }
   CrossOriginAttributeValue CrossOrigin() const { return cross_origin_; }
 
+  void SetImportance(mojom::FetchImportanceMode importance) {
+    importance_ = importance;
+  }
+  mojom::FetchImportanceMode Importance() const { return importance_; }
+
   void SetNonce(const String& nonce) { nonce_ = nonce; }
   const String& Nonce() const { return nonce_; }
 
@@ -134,6 +140,7 @@
         resource_type_(resource_type),
         script_type_(ScriptType::kClassic),
         cross_origin_(kCrossOriginAttributeNotSet),
+        importance_(mojom::FetchImportanceMode::kImportanceAuto),
         defer_(FetchParameters::kNoDefer),
         resource_width_(resource_width),
         client_hints_preferences_(client_hints_preferences),
@@ -153,6 +160,7 @@
   Resource::Type resource_type_;
   ScriptType script_type_;
   CrossOriginAttributeValue cross_origin_;
+  mojom::FetchImportanceMode importance_;
   String nonce_;
   FetchParameters::DeferOption defer_;
   FetchParameters::ResourceWidth resource_width_;
diff --git a/third_party/blink/renderer/core/inspector/browser_protocol.pdl b/third_party/blink/renderer/core/inspector/browser_protocol.pdl
index f5325d47..ff0867f 100644
--- a/third_party/blink/renderer/core/inspector/browser_protocol.pdl
+++ b/third_party/blink/renderer/core/inspector/browser_protocol.pdl
@@ -5742,6 +5742,15 @@
     parameters
       TargetID targetId
 
+  # Issued when a target has crashed.
+  event targetCrashed
+    parameters
+      TargetID targetId
+      # Termination status type.
+      string status
+      # Termination error code.
+      integer errorCode
+
   # Issued when some information about a target has changed. This only happens between
   # `targetCreated` and `targetDestroyed`.
   event targetInfoChanged
diff --git a/third_party/blink/renderer/core/layout/layout_block.cc b/third_party/blink/renderer/core/layout/layout_block.cc
index 1deea79f..0081faf 100644
--- a/third_party/blink/renderer/core/layout/layout_block.cc
+++ b/third_party/blink/renderer/core/layout/layout_block.cc
@@ -1322,7 +1322,7 @@
     LayoutUnit& min_logical_width,
     LayoutUnit& max_logical_width) const {
   // Size-contained elements don't consider their contents for preferred sizing.
-  if (Style()->ContainsSize())
+  if (ShouldApplySizeContainment())
     return;
 
   if (ChildrenInline()) {
@@ -1716,7 +1716,7 @@
   // ancestors or siblings.
   return (!Style()->IsOverflowVisible() &&
           !ShouldIgnoreOverflowPropertyForInlineBlockBaseline()) ||
-         Style()->ContainsSize();
+         ShouldApplySizeContainment();
 }
 
 LayoutUnit LayoutBlock::InlineBlockBaseline(
@@ -1945,24 +1945,23 @@
 LayoutBlock* LayoutBlock::CreateAnonymousWithParentAndDisplay(
     const LayoutObject* parent,
     EDisplay display) {
-  // FIXME: Do we need to convert all our inline displays to block-type in the
-  // anonymous logic ?
-  EDisplay new_display;
-  LayoutBlock* new_box = nullptr;
-  if (display == EDisplay::kFlex || display == EDisplay::kInlineFlex) {
-    new_box = LayoutFlexibleBox::CreateAnonymous(&parent->GetDocument());
-    new_display = EDisplay::kFlex;
-  } else {
-    new_box = LayoutBlockFlow::CreateAnonymous(&parent->GetDocument());
-    new_display = EDisplay::kBlock;
-  }
-
+  // TODO(layout-dev): Do we need to convert all our inline displays to block
+  // type in the anonymous logic?
+  const EDisplay new_display =
+      display == EDisplay::kFlex || display == EDisplay::kInlineFlex
+          ? EDisplay::kFlex
+          : EDisplay::kBlock;
   scoped_refptr<ComputedStyle> new_style =
       ComputedStyle::CreateAnonymousStyleWithDisplay(parent->StyleRef(),
                                                      new_display);
-  parent->UpdateAnonymousChildStyle(*new_box, *new_style);
-  new_box->SetStyle(std::move(new_style));
-  return new_box;
+  parent->UpdateAnonymousChildStyle(nullptr, *new_style);
+  if (new_display == EDisplay::kFlex) {
+    return LayoutFlexibleBox::CreateAnonymous(&parent->GetDocument(),
+                                              std::move(new_style));
+  }
+  DCHECK_EQ(new_display, EDisplay::kBlock);
+  return LayoutBlockFlow::CreateAnonymous(&parent->GetDocument(),
+                                          std::move(new_style));
 }
 
 bool LayoutBlock::RecalcNormalFlowChildOverflowIfNeeded(
diff --git a/third_party/blink/renderer/core/layout/layout_block_flow.cc b/third_party/blink/renderer/core/layout/layout_block_flow.cc
index c30ee0d..b20801d 100644
--- a/third_party/blink/renderer/core/layout/layout_block_flow.cc
+++ b/third_party/blink/renderer/core/layout/layout_block_flow.cc
@@ -272,12 +272,15 @@
 
 LayoutBlockFlow::~LayoutBlockFlow() = default;
 
-LayoutBlockFlow* LayoutBlockFlow::CreateAnonymous(Document* document) {
-  // TODO(layout-ng): Find a way to check style.ForceLegacyLayout() Here
-  LayoutBlockFlow* layout_block_flow = RuntimeEnabledFeatures::LayoutNGEnabled()
-                                           ? new LayoutNGBlockFlow(nullptr)
-                                           : new LayoutBlockFlow(nullptr);
+LayoutBlockFlow* LayoutBlockFlow::CreateAnonymous(
+    Document* document,
+    scoped_refptr<ComputedStyle> style) {
+  LayoutBlockFlow* layout_block_flow =
+      RuntimeEnabledFeatures::LayoutNGEnabled() && !style->ForceLegacyLayout()
+          ? new LayoutNGBlockFlow(nullptr)
+          : new LayoutBlockFlow(nullptr);
   layout_block_flow->SetDocumentForAnonymous(document);
+  layout_block_flow->SetStyle(style);
   return layout_block_flow;
 }
 
diff --git a/third_party/blink/renderer/core/layout/layout_block_flow.h b/third_party/blink/renderer/core/layout/layout_block_flow.h
index 0bb09ec..028c1fcd 100644
--- a/third_party/blink/renderer/core/layout/layout_block_flow.h
+++ b/third_party/blink/renderer/core/layout/layout_block_flow.h
@@ -102,7 +102,8 @@
   explicit LayoutBlockFlow(ContainerNode*);
   ~LayoutBlockFlow() override;
 
-  static LayoutBlockFlow* CreateAnonymous(Document*);
+  static LayoutBlockFlow* CreateAnonymous(Document*,
+                                          scoped_refptr<ComputedStyle>);
   bool BeingDestroyed() const { return being_destroyed_; }
 
   bool IsLayoutBlockFlow() const final { return true; }
diff --git a/third_party/blink/renderer/core/layout/layout_block_test.cc b/third_party/blink/renderer/core/layout/layout_block_test.cc
index a3e9500..a4fb4c98 100644
--- a/third_party/blink/renderer/core/layout/layout_block_test.cc
+++ b/third_party/blink/renderer/core/layout/layout_block_test.cc
@@ -15,7 +15,9 @@
 class LayoutBlockTest : public RenderingTest {};
 
 TEST_F(LayoutBlockTest, LayoutNameCalledWithNullStyle) {
-  LayoutObject* obj = LayoutBlockFlow::CreateAnonymous(&GetDocument());
+  scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
+  LayoutObject* obj = LayoutBlockFlow::CreateAnonymous(&GetDocument(), style);
+  obj->SetStyleInternal(nullptr);
   EXPECT_FALSE(obj->Style());
   EXPECT_STREQ("LayoutBlockFlow (anonymous)",
                obj->DecoratedName().Ascii().data());
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc
index b2057c6f..80b0aedf 100644
--- a/third_party/blink/renderer/core/layout/layout_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -2642,8 +2642,9 @@
 DISABLE_CFI_PERF
 void LayoutBox::ComputeLogicalWidth(
     LogicalExtentComputedValues& computed_values) const {
-  computed_values.extent_ =
-      Style()->ContainsSize() ? BorderAndPaddingLogicalWidth() : LogicalWidth();
+  computed_values.extent_ = ShouldApplySizeContainment()
+                                ? BorderAndPaddingLogicalWidth()
+                                : LogicalWidth();
   computed_values.position_ = LogicalLeft();
   computed_values.margins_.start_ = MarginStart();
   computed_values.margins_.end_ = MarginEnd();
@@ -3118,8 +3119,9 @@
 
 void LayoutBox::ComputeLogicalHeight(
     LogicalExtentComputedValues& computed_values) const {
-  LayoutUnit height = Style()->ContainsSize() ? BorderAndPaddingLogicalHeight()
-                                              : LogicalHeight();
+  LayoutUnit height = ShouldApplySizeContainment()
+                          ? BorderAndPaddingLogicalHeight()
+                          : LogicalHeight();
   ComputeLogicalHeight(height, LogicalTop(), computed_values);
 }
 
diff --git a/third_party/blink/renderer/core/layout/layout_button.cc b/third_party/blink/renderer/core/layout/layout_button.cc
index b249dc7..054433df 100644
--- a/third_party/blink/renderer/core/layout/layout_button.cc
+++ b/third_party/blink/renderer/core/layout/layout_button.cc
@@ -56,10 +56,9 @@
   }
 }
 
-void LayoutButton::UpdateAnonymousChildStyle(const LayoutObject& child,
+void LayoutButton::UpdateAnonymousChildStyle(const LayoutObject* child,
                                              ComputedStyle& child_style) const {
-  DCHECK(!inner_ || &child == inner_);
-
+  DCHECK_EQ(inner_, child);
   child_style.SetFlexGrow(1.0f);
   // min-width: 0; is needed for correct shrinking.
   child_style.SetMinWidth(Length(0, kFixed));
diff --git a/third_party/blink/renderer/core/layout/layout_button.h b/third_party/blink/renderer/core/layout/layout_button.h
index c2b1e5c..a3846ca3 100644
--- a/third_party/blink/renderer/core/layout/layout_button.h
+++ b/third_party/blink/renderer/core/layout/layout_button.h
@@ -57,7 +57,7 @@
                               LinePositionMode) const override;
 
  private:
-  void UpdateAnonymousChildStyle(const LayoutObject& child,
+  void UpdateAnonymousChildStyle(const LayoutObject* child,
                                  ComputedStyle& child_style) const override;
 
   bool HasLineIfEmpty() const override { return IsHTMLInputElement(GetNode()); }
diff --git a/third_party/blink/renderer/core/layout/layout_flexible_box.cc b/third_party/blink/renderer/core/layout/layout_flexible_box.cc
index a29fc81..ad2dcd3 100644
--- a/third_party/blink/renderer/core/layout/layout_flexible_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_flexible_box.cc
@@ -65,9 +65,12 @@
 
 LayoutFlexibleBox::~LayoutFlexibleBox() = default;
 
-LayoutFlexibleBox* LayoutFlexibleBox::CreateAnonymous(Document* document) {
+LayoutFlexibleBox* LayoutFlexibleBox::CreateAnonymous(
+    Document* document,
+    scoped_refptr<ComputedStyle> style) {
   LayoutFlexibleBox* layout_object = new LayoutFlexibleBox(nullptr);
   layout_object->SetDocumentForAnonymous(document);
+  layout_object->SetStyle(style);
   return layout_object;
 }
 
@@ -510,7 +513,7 @@
   DCHECK(!HasOrthogonalFlow(child));
   if (NeedToStretchChildLogicalHeight(child)) {
     LayoutUnit child_intrinsic_content_logical_height;
-    if (!child.StyleRef().ContainsSize()) {
+    if (!child.ShouldApplySizeContainment()) {
       child_intrinsic_content_logical_height =
           child.IntrinsicContentLogicalHeight();
     }
@@ -866,7 +869,7 @@
     return std::max(LayoutUnit(), ComputeMainAxisExtentForChild(
                                       child, kMainOrPreferredSize, flex_basis));
 
-  if (child.StyleRef().ContainsSize())
+  if (child.ShouldApplySizeContainment())
     return LayoutUnit();
 
   // The flex basis is indefinite (=auto), so we need to compute the actual
@@ -1094,7 +1097,7 @@
     // computeMainAxisExtentForChild can return -1 when the child has a
     // percentage min size, but we have an indefinite size in that axis.
     sizes.min_size = std::max(LayoutUnit(), sizes.min_size);
-  } else if (min.IsAuto() && !child.StyleRef().ContainsSize() &&
+  } else if (min.IsAuto() && !child.ShouldApplySizeContainment() &&
              MainAxisOverflowForChild(child) == EOverflow::kVisible &&
              !(IsColumnFlow() && child.IsFlexibleBox())) {
     // TODO(cbiesinger): For now, we do not handle min-height: auto for nested
diff --git a/third_party/blink/renderer/core/layout/layout_flexible_box.h b/third_party/blink/renderer/core/layout/layout_flexible_box.h
index def9538..76b3066 100644
--- a/third_party/blink/renderer/core/layout/layout_flexible_box.h
+++ b/third_party/blink/renderer/core/layout/layout_flexible_box.h
@@ -46,7 +46,8 @@
   LayoutFlexibleBox(Element*);
   ~LayoutFlexibleBox() override;
 
-  static LayoutFlexibleBox* CreateAnonymous(Document*);
+  static LayoutFlexibleBox* CreateAnonymous(Document*,
+                                            scoped_refptr<ComputedStyle>);
 
   const char* GetName() const override { return "LayoutFlexibleBox"; }
 
diff --git a/third_party/blink/renderer/core/layout/layout_inline.cc b/third_party/blink/renderer/core/layout/layout_inline.cc
index 6cd2207..9fe495e 100644
--- a/third_party/blink/renderer/core/layout/layout_inline.cc
+++ b/third_party/blink/renderer/core/layout/layout_inline.cc
@@ -396,8 +396,8 @@
             InFlowPositionedInlineAncestor(this))
       new_style->SetPosition(positioned_ancestor->Style()->GetPosition());
 
-    LayoutBlockFlow* new_box = LayoutBlockFlow::CreateAnonymous(&GetDocument());
-    new_box->SetStyle(std::move(new_style));
+    LayoutBlockFlow* new_box =
+        LayoutBlockFlow::CreateAnonymous(&GetDocument(), std::move(new_style));
     LayoutBoxModelObject* old_continuation = Continuation();
     SetContinuation(new_box);
 
diff --git a/third_party/blink/renderer/core/layout/layout_menu_list.cc b/third_party/blink/renderer/core/layout/layout_menu_list.cc
index 0f83f310..6513923 100644
--- a/third_party/blink/renderer/core/layout/layout_menu_list.cc
+++ b/third_party/blink/renderer/core/layout/layout_menu_list.cc
@@ -88,8 +88,8 @@
 
   // Create an anonymous block.
   DCHECK(!FirstChild());
-  inner_block_ = LayoutBlockFlow::CreateAnonymous(&GetDocument());
-  inner_block_->SetStyle(CreateInnerStyle());
+  inner_block_ =
+      LayoutBlockFlow::CreateAnonymous(&GetDocument(), CreateInnerStyle());
 
   button_text_ = LayoutText::CreateEmptyAnonymous(GetDocument());
   // We need to set the text explicitly though it was specified in the
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc
index 37dd5d2..d9f2396 100644
--- a/third_party/blink/renderer/core/layout/layout_object.cc
+++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -810,7 +810,7 @@
     return false;
 
   const ComputedStyle* style = object->Style();
-  if (style->ContainsLayout() && style->ContainsSize())
+  if (style->ContainsLayout() && object->ShouldApplySizeContainment())
     return true;
 
   if (!object->HasOverflowClip())
@@ -2304,7 +2304,7 @@
         ToLayoutBlockFlow(child)->IsAnonymousBlockContinuation())
       new_style->SetPosition(child->Style()->GetPosition());
 
-    UpdateAnonymousChildStyle(*child, *new_style);
+    UpdateAnonymousChildStyle(child, *new_style);
 
     child->SetStyle(std::move(new_style));
   }
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h
index 744f7df4..fc143fe 100644
--- a/third_party/blink/renderer/core/layout/layout_object.h
+++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -429,6 +429,12 @@
            (!IsTablePart() || IsLayoutBlockFlow());
   }
 
+  inline bool ShouldApplySizeContainment() const {
+    return StyleRef().ContainsSize() &&
+           (!IsInline() || IsAtomicInlineLevel()) && !IsRubyText() &&
+           (!IsTablePart() || IsTableCaption());
+  }
+
  private:
   //////////////////////////////////////////
   // Helper functions. Dangerous to use!
@@ -1751,9 +1757,9 @@
 
   virtual bool HasNonCompositedScrollbars() const { return false; }
 
-  // Called before anonymousChild.setStyle(). Override to set custom styles for
-  // the child.
-  virtual void UpdateAnonymousChildStyle(const LayoutObject& anonymous_child,
+  // Called before setting style for existing/new anonymous child. Override to
+  // set custom styles for the child. For new anonymous child, |child| is null.
+  virtual void UpdateAnonymousChildStyle(const LayoutObject* child,
                                          ComputedStyle& style) const {}
 
   // Returns a rect corresponding to this LayoutObject's bounds for use in
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
index baa5f80..766026e 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
@@ -135,7 +135,7 @@
   MinMaxSize sizes;
 
   // Size-contained elements don't consider their contents for intrinsic sizing.
-  if (Style().ContainsSize())
+  if (node_.ShouldApplySizeContainment())
     return sizes;
 
   const TextDirection direction = Style().Direction();
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc
index aaa31f91..592f7bd 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc
@@ -191,6 +191,10 @@
   return box_->StyleRef();
 }
 
+bool NGLayoutInputNode::ShouldApplySizeContainment() const {
+  return box_->ShouldApplySizeContainment();
+}
+
 String NGLayoutInputNode::ToString() const {
   return IsInline() ? ToNGInlineNode(*this).ToString()
                     : ToNGBlockNode(*this).ToString();
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h
index 4ac0d3e..6f95a47 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h
@@ -98,6 +98,8 @@
 
   const ComputedStyle& Style() const;
 
+  bool ShouldApplySizeContainment() const;
+
   String ToString() const;
 
   explicit operator bool() const { return box_ != nullptr; }
diff --git a/third_party/blink/renderer/core/loader/BUILD.gn b/third_party/blink/renderer/core/loader/BUILD.gn
index affe947..4a6d8cba 100644
--- a/third_party/blink/renderer/core/loader/BUILD.gn
+++ b/third_party/blink/renderer/core/loader/BUILD.gn
@@ -44,6 +44,8 @@
     "idleness_detector.h",
     "image_loader.cc",
     "image_loader.h",
+    "importance_attribute.cc",
+    "importance_attribute.h",
     "interactive_detector.cc",
     "interactive_detector.h",
     "link_loader.cc",
diff --git a/third_party/blink/renderer/core/loader/document_threadable_loader.cc b/third_party/blink/renderer/core/loader/document_threadable_loader.cc
index 511e86bc..d536bc36 100644
--- a/third_party/blink/renderer/core/loader/document_threadable_loader.cc
+++ b/third_party/blink/renderer/core/loader/document_threadable_loader.cc
@@ -724,7 +724,7 @@
     scoped_refptr<const SecurityOrigin> new_origin =
         SecurityOrigin::Create(new_url);
     if (!original_origin->IsSameSchemeHostPort(new_origin.get()))
-      security_origin_ = SecurityOrigin::CreateUnique();
+      security_origin_ = SecurityOrigin::CreateUniqueOpaque();
   }
 
   // Set |cors_flag_| so that further logic (corresponds to the main fetch in
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context.cc b/third_party/blink/renderer/core/loader/frame_fetch_context.cc
index ff40bb5..debf792 100644
--- a/third_party/blink/renderer/core/loader/frame_fetch_context.cc
+++ b/third_party/blink/renderer/core/loader/frame_fetch_context.cc
@@ -1395,7 +1395,7 @@
         kReferrerPolicyDefault, String(), NullURL(), GetSecurityOrigin(),
         GetParentSecurityOrigin(), GetAddressSpace(),
         GetContentSecurityPolicy(), GetSiteForCookies(),
-        SecurityOrigin::CreateUnique(), GetClientHintsPreferences(),
+        SecurityOrigin::CreateUniqueOpaque(), GetClientHintsPreferences(),
         GetDevicePixelRatio(), GetUserAgent(), IsMainFrame(),
         IsSVGImageChromeClient());
   }
diff --git a/third_party/blink/renderer/core/loader/image_loader.cc b/third_party/blink/renderer/core/loader/image_loader.cc
index e599c1a..cd62107b0 100644
--- a/third_party/blink/renderer/core/loader/image_loader.cc
+++ b/third_party/blink/renderer/core/loader/image_loader.cc
@@ -44,6 +44,7 @@
 #include "third_party/blink/renderer/core/layout/layout_image.h"
 #include "third_party/blink/renderer/core/layout/layout_video.h"
 #include "third_party/blink/renderer/core/layout/svg/layout_svg_image.h"
+#include "third_party/blink/renderer/core/loader/importance_attribute.h"
 #include "third_party/blink/renderer/core/probe/core_probes.h"
 #include "third_party/blink/renderer/core/svg/graphics/svg_image.h"
 #include "third_party/blink/renderer/platform/bindings/microtask.h"
@@ -301,6 +302,13 @@
         element.GetDocument().GetSecurityOrigin(), cross_origin);
   }
 
+  if (RuntimeEnabledFeatures::PriorityHintsEnabled()) {
+    mojom::FetchImportanceMode importance_mode =
+        GetFetchImportanceAttributeValue(
+            element.FastGetAttribute(HTMLNames::importanceAttr));
+    params.SetFetchImportanceMode(importance_mode);
+  }
+
   if (client_hints_preferences.ShouldSend(
           mojom::WebClientHintsType::kResourceWidth) &&
       IsHTMLImageElement(element))
diff --git a/third_party/blink/renderer/core/loader/importance_attribute.cc b/third_party/blink/renderer/core/loader/importance_attribute.cc
new file mode 100644
index 0000000..d2a836df
--- /dev/null
+++ b/third_party/blink/renderer/core/loader/importance_attribute.cc
@@ -0,0 +1,18 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/loader/importance_attribute.h"
+
+namespace blink {
+
+mojom::FetchImportanceMode GetFetchImportanceAttributeValue(
+    const String& value) {
+  if (EqualIgnoringASCIICase(value, "low"))
+    return mojom::FetchImportanceMode::kImportanceLow;
+  if (EqualIgnoringASCIICase(value, "high"))
+    return mojom::FetchImportanceMode::kImportanceHigh;
+  return mojom::FetchImportanceMode::kImportanceAuto;
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/loader/importance_attribute.h b/third_party/blink/renderer/core/loader/importance_attribute.h
new file mode 100644
index 0000000..ccb1f9c
--- /dev/null
+++ b/third_party/blink/renderer/core/loader/importance_attribute.h
@@ -0,0 +1,18 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_IMPORTANCE_ATTRIBUTE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_IMPORTANCE_ATTRIBUTE_H_
+
+#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom-shared.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+
+mojom::FetchImportanceMode GetFetchImportanceAttributeValue(
+    const String& value);
+
+}  // namespace blink
+
+#endif
diff --git a/third_party/blink/renderer/core/loader/link_loader.cc b/third_party/blink/renderer/core/loader/link_loader.cc
index d1d87d4..442dbbd 100644
--- a/third_party/blink/renderer/core/loader/link_loader.cc
+++ b/third_party/blink/renderer/core/loader/link_loader.cc
@@ -47,6 +47,7 @@
 #include "third_party/blink/renderer/core/html/parser/html_srcset_parser.h"
 #include "third_party/blink/renderer/core/inspector/console_message.h"
 #include "third_party/blink/renderer/core/loader/document_loader.h"
+#include "third_party/blink/renderer/core/loader/importance_attribute.h"
 #include "third_party/blink/renderer/core/loader/modulescript/module_script_fetch_request.h"
 #include "third_party/blink/renderer/core/loader/network_hints_interface.h"
 #include "third_party/blink/renderer/core/loader/private/prerender_handle.h"
@@ -84,6 +85,11 @@
   return result;
 }
 
+// TODO(domfarolino)
+// Eventually we'll want to support an |importance| value on
+// LinkHeaders. We can communicate a header's importance value
+// to LinkLoadParameters here, likely after modifying the LinkHeader
+// class. See https://crbug.com/821464 for info on Priority Hints.
 LinkLoadParameters::LinkLoadParameters(const LinkHeader& header,
                                        const KURL& base_url)
     : rel(LinkRelAttribute(header.Rel())),
@@ -409,6 +415,9 @@
         params.referrer_policy, url, document.OutgoingReferrer()));
   }
 
+  resource_request.SetFetchImportanceMode(
+      GetFetchImportanceAttributeValue(params.importance));
+
   ResourceLoaderOptions options;
   options.initiator_info.name = FetchInitiatorTypeNames::link;
   FetchParameters link_fetch_params(resource_request, options);
@@ -566,6 +575,9 @@
           params.referrer_policy, params.href, document.OutgoingReferrer()));
     }
 
+    resource_request.SetFetchImportanceMode(
+        GetFetchImportanceAttributeValue(params.importance));
+
     ResourceLoaderOptions options;
     options.initiator_info.name = FetchInitiatorTypeNames::link;
     auto* service = document.GetFrame()->PrefetchURLLoaderService();
diff --git a/third_party/blink/renderer/core/loader/link_loader.h b/third_party/blink/renderer/core/loader/link_loader.h
index efc7836..f277a91 100644
--- a/third_party/blink/renderer/core/loader/link_loader.h
+++ b/third_party/blink/renderer/core/loader/link_loader.h
@@ -59,6 +59,7 @@
                      const String& media,
                      const String& nonce,
                      const String& integrity,
+                     const String& importance,
                      const ReferrerPolicy& referrer_policy,
                      const KURL& href,
                      const String& srcset,
@@ -70,6 +71,7 @@
         media(media),
         nonce(nonce),
         integrity(integrity),
+        importance(importance),
         referrer_policy(referrer_policy),
         href(href),
         srcset(srcset),
@@ -83,6 +85,7 @@
   String media;
   String nonce;
   String integrity;
+  String importance;
   ReferrerPolicy referrer_policy;
   KURL href;
   String srcset;
diff --git a/third_party/blink/renderer/core/loader/link_loader_test.cc b/third_party/blink/renderer/core/loader/link_loader_test.cc
index 2b9ebf64..9488dbc 100644
--- a/third_party/blink/renderer/core/loader/link_loader_test.cc
+++ b/third_party/blink/renderer/core/loader/link_loader_test.cc
@@ -186,8 +186,9 @@
   const auto& test_case = GetParam();
   LinkLoadParameters params(
       LinkRelAttribute("preload"), kCrossOriginAttributeNotSet, String(),
-      test_case.as, String(), String(), String(), kReferrerPolicyDefault,
-      KURL(NullURL(), test_case.href), String(), String());
+      test_case.as, String(), String(), String(), String(),
+      kReferrerPolicyDefault, KURL(NullURL(), test_case.href), String(),
+      String());
   Expectations expectations = {
       test_case.priority, test_case.context, test_case.expecting_load,
       test_case.expecting_load ? params.href : NullURL(),
@@ -264,8 +265,9 @@
   const auto& test_case = GetParam();
   LinkLoadParameters params(
       LinkRelAttribute("preload"), kCrossOriginAttributeNotSet, test_case.type,
-      test_case.as, String(), String(), String(), kReferrerPolicyDefault,
-      KURL(NullURL(), test_case.href), String(), String());
+      test_case.as, String(), String(), String(), String(),
+      kReferrerPolicyDefault, KURL(NullURL(), test_case.href), String(),
+      String());
   Expectations expectations = {
       test_case.priority, test_case.context, test_case.expecting_load,
       test_case.expecting_load ? params.href : NullURL(),
@@ -297,8 +299,9 @@
   const auto& test_case = GetParam();
   LinkLoadParameters params(
       LinkRelAttribute("preload"), kCrossOriginAttributeNotSet, "image/gif",
-      "image", test_case.media, String(), String(), kReferrerPolicyDefault,
-      KURL(NullURL(), "http://example.test/cat.gif"), String(), String());
+      "image", test_case.media, String(), String(), String(),
+      kReferrerPolicyDefault, KURL(NullURL(), "http://example.test/cat.gif"),
+      String(), String());
   Expectations expectations = {
       test_case.priority, WebURLRequest::kRequestContextImage,
       test_case.link_loader_should_load_value,
@@ -327,7 +330,7 @@
   const ReferrerPolicy referrer_policy = GetParam();
   LinkLoadParameters params(
       LinkRelAttribute("preload"), kCrossOriginAttributeNotSet, "image/gif",
-      "image", String(), String(), String(), referrer_policy,
+      "image", String(), String(), String(), String(), referrer_policy,
       KURL(NullURL(), "http://example.test/cat.gif"), String(), String());
   Expectations expectations = {ResourceLoadPriority::kLow,
                                WebURLRequest::kRequestContextImage, true,
@@ -364,8 +367,9 @@
                          kContentSecurityPolicyHeaderSourceHTTP);
   LinkLoadParameters params(
       LinkRelAttribute("preload"), kCrossOriginAttributeNotSet, String(),
-      "script", String(), test_case.nonce, String(), kReferrerPolicyDefault,
-      KURL(NullURL(), "http://example.test/cat.js"), String(), String());
+      "script", String(), test_case.nonce, String(), String(),
+      kReferrerPolicyDefault, KURL(NullURL(), "http://example.test/cat.js"),
+      String(), String());
   Expectations expectations = {
       ResourceLoadPriority::kHigh, WebURLRequest::kRequestContextScript,
       test_case.expecting_load,
@@ -416,7 +420,7 @@
       test_case.scale_factor);
   LinkLoadParameters params(
       LinkRelAttribute("preload"), kCrossOriginAttributeNotSet, "image/gif",
-      "image", String(), String(), String(), kReferrerPolicyDefault,
+      "image", String(), String(), String(), String(), kReferrerPolicyDefault,
       KURL(NullURL(), test_case.href), test_case.srcset, test_case.sizes);
   Expectations expectations = {
       ResourceLoadPriority::kLow, WebURLRequest::kRequestContextImage, true,
@@ -502,8 +506,8 @@
   LinkLoadParameters params(
       LinkRelAttribute("modulepreload"), test_case.cross_origin,
       String() /* type */, String() /* as */, String() /* media */,
-      test_case.nonce, test_case.integrity, test_case.referrer_policy, href_url,
-      String() /* srcset */, String() /* sizes */);
+      test_case.nonce, test_case.integrity, String(), test_case.referrer_policy,
+      href_url, String() /* srcset */, String() /* sizes */);
   loader->LoadLink(params, dummy_page_holder->GetDocument(),
                    NetworkHintsMock());
   ASSERT_EQ(test_case.expecting_load, modulator->fetched());
@@ -544,10 +548,11 @@
     LinkLoader* loader = LinkLoader::Create(loader_client.Get());
     KURL href_url = KURL(NullURL(), test_case.href);
     URLTestHelpers::RegisterMockedErrorURLLoad(href_url);
-    LinkLoadParameters params(
-        LinkRelAttribute("prefetch"), kCrossOriginAttributeNotSet,
-        test_case.type, "", test_case.media, "", "", test_case.referrer_policy,
-        href_url, String() /* srcset */, String() /* sizes */);
+    LinkLoadParameters params(LinkRelAttribute("prefetch"),
+                              kCrossOriginAttributeNotSet, test_case.type, "",
+                              test_case.media, "", "", String(),
+                              test_case.referrer_policy, href_url,
+                              String() /* srcset */, String() /* sizes */);
     loader->LoadLink(params, dummy_page_holder->GetDocument(),
                      NetworkHintsMock());
     ASSERT_TRUE(dummy_page_holder->GetDocument().Fetcher());
@@ -591,10 +596,11 @@
     LinkLoader* loader = LinkLoader::Create(loader_client.Get());
     KURL href_url = KURL(KURL(String("http://example.com")), test_case.href);
     NetworkHintsMock network_hints;
-    LinkLoadParameters params(
-        LinkRelAttribute("dns-prefetch"), kCrossOriginAttributeNotSet, String(),
-        String(), String(), String(), String(), kReferrerPolicyDefault,
-        href_url, String() /* srcset */, String() /* sizes */);
+    LinkLoadParameters params(LinkRelAttribute("dns-prefetch"),
+                              kCrossOriginAttributeNotSet, String(), String(),
+                              String(), String(), String(), String(),
+                              kReferrerPolicyDefault, href_url,
+                              String() /* srcset */, String() /* sizes */);
     loader->LoadLink(params, dummy_page_holder->GetDocument(), network_hints);
     EXPECT_FALSE(network_hints.DidPreconnect());
     EXPECT_EQ(test_case.should_load, network_hints.DidDnsPrefetch());
@@ -626,10 +632,11 @@
     LinkLoader* loader = LinkLoader::Create(loader_client.Get());
     KURL href_url = KURL(KURL(String("http://example.com")), test_case.href);
     NetworkHintsMock network_hints;
-    LinkLoadParameters params(
-        LinkRelAttribute("preconnect"), test_case.cross_origin, String(),
-        String(), String(), String(), String(), kReferrerPolicyDefault,
-        href_url, String() /* srcset */, String() /* sizes */);
+    LinkLoadParameters params(LinkRelAttribute("preconnect"),
+                              test_case.cross_origin, String(), String(),
+                              String(), String(), String(), String(),
+                              kReferrerPolicyDefault, href_url,
+                              String() /* srcset */, String() /* sizes */);
     loader->LoadLink(params, dummy_page_holder->GetDocument(), network_hints);
     EXPECT_EQ(test_case.should_load, network_hints.DidPreconnect());
     EXPECT_EQ(test_case.is_https, network_hints.IsHTTPS());
@@ -648,10 +655,11 @@
   LinkLoader* loader = LinkLoader::Create(loader_client.Get());
   KURL href_url = KURL(KURL(), "https://www.example.com/");
   URLTestHelpers::RegisterMockedErrorURLLoad(href_url);
-  LinkLoadParameters params(
-      LinkRelAttribute("preload prefetch"), kCrossOriginAttributeNotSet,
-      "application/javascript", "script", "", "", "", kReferrerPolicyDefault,
-      href_url, String() /* srcset */, String() /* sizes */);
+  LinkLoadParameters params(LinkRelAttribute("preload prefetch"),
+                            kCrossOriginAttributeNotSet,
+                            "application/javascript", "script", "", "", "",
+                            String(), kReferrerPolicyDefault, href_url,
+                            String() /* srcset */, String() /* sizes */);
   loader->LoadLink(params, dummy_page_holder->GetDocument(),
                    NetworkHintsMock());
   ASSERT_EQ(1, fetcher->CountPreloads());
diff --git a/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc b/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc
index 6813686..fd756375 100644
--- a/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc
+++ b/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc
@@ -800,7 +800,7 @@
     WebRemoteFrameImpl* remote_main_frame = FrameTestHelpers::CreateRemote();
     helper_.LocalMainFrame()->Swap(remote_main_frame);
     remote_main_frame->SetReplicatedOrigin(
-        WebSecurityOrigin(SecurityOrigin::CreateUnique()), false);
+        WebSecurityOrigin(SecurityOrigin::CreateUniqueOpaque()), false);
     local_frame = FrameTestHelpers::CreateLocalChild(*remote_main_frame);
 
     FrameTestHelpers::LoadFrame(local_frame,
@@ -872,7 +872,7 @@
         ToWebLocalFrameImpl(helper_.LocalMainFrame()->FirstChild());
     child->Swap(remote_frame);
     remote_frame->SetReplicatedOrigin(
-        WebSecurityOrigin(SecurityOrigin::CreateUnique()), false);
+        WebSecurityOrigin(SecurityOrigin::CreateUniqueOpaque()), false);
 
     non_main_local_root = FrameTestHelpers::CreateLocalChild(*remote_frame);
     ASSERT_EQ(non_main_local_root->LocalRoot(), non_main_local_root);
diff --git a/third_party/blink/renderer/core/svg/svg_path_parser.cc b/third_party/blink/renderer/core/svg/svg_path_parser.cc
index 0c842666..447adfb 100644
--- a/third_party/blink/renderer/core/svg/svg_path_parser.cc
+++ b/third_party/blink/renderer/core/svg/svg_path_parser.cc
@@ -234,9 +234,9 @@
 
   float theta_arc = theta2 - theta1;
   if (theta_arc < 0 && arc_segment.arc_sweep)
-    theta_arc += twoPiFloat;
+    theta_arc += kTwoPiFloat;
   else if (theta_arc > 0 && !arc_segment.arc_sweep)
-    theta_arc -= twoPiFloat;
+    theta_arc -= kTwoPiFloat;
 
   point_transform.MakeIdentity();
   point_transform.Rotate(angle);
@@ -245,7 +245,7 @@
   // Some results of atan2 on some platform implementations are not exact
   // enough. So that we get more cubic curves than expected here. Adding 0.001f
   // reduces the count of sgements to the correct count.
-  int segments = ceilf(fabsf(theta_arc / (piOverTwoFloat + 0.001f)));
+  int segments = ceilf(fabsf(theta_arc / (kPiOverTwoFloat + 0.001f)));
   for (int i = 0; i < segments; ++i) {
     float start_theta = theta1 + i * theta_arc / segments;
     float end_theta = theta1 + (i + 1) * theta_arc / segments;
diff --git a/third_party/blink/renderer/core/workers/BUILD.gn b/third_party/blink/renderer/core/workers/BUILD.gn
index 986a81c2..57a95632 100644
--- a/third_party/blink/renderer/core/workers/BUILD.gn
+++ b/third_party/blink/renderer/core/workers/BUILD.gn
@@ -62,8 +62,6 @@
     "worker_clients.h",
     "worker_content_settings_client.cc",
     "worker_content_settings_client.h",
-    "worker_event_queue.cc",
-    "worker_event_queue.h",
     "worker_global_scope.cc",
     "worker_global_scope.h",
     "worker_inspector_proxy.cc",
diff --git a/third_party/blink/renderer/core/workers/worker_event_queue.cc b/third_party/blink/renderer/core/workers/worker_event_queue.cc
deleted file mode 100644
index a9dfe08..0000000
--- a/third_party/blink/renderer/core/workers/worker_event_queue.cc
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "third_party/blink/renderer/core/workers/worker_event_queue.h"
-
-#include "third_party/blink/public/platform/task_type.h"
-#include "third_party/blink/renderer/core/dom/events/event.h"
-#include "third_party/blink/renderer/core/probe/core_probes.h"
-#include "third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h"
-#include "third_party/blink/renderer/core/workers/worker_thread.h"
-
-namespace blink {
-
-WorkerEventQueue* WorkerEventQueue::Create(
-    WorkerOrWorkletGlobalScope* global_scope) {
-  return new WorkerEventQueue(global_scope);
-}
-
-WorkerEventQueue::WorkerEventQueue(WorkerOrWorkletGlobalScope* global_scope)
-    : global_scope_(global_scope) {}
-
-WorkerEventQueue::~WorkerEventQueue() {
-  DCHECK(pending_events_.IsEmpty());
-}
-
-void WorkerEventQueue::Trace(blink::Visitor* visitor) {
-  visitor->Trace(global_scope_);
-  visitor->Trace(pending_events_);
-  EventQueue::Trace(visitor);
-}
-
-bool WorkerEventQueue::EnqueueEvent(const base::Location& from_here,
-                                    Event* event) {
-  if (is_closed_)
-    return false;
-  probe::AsyncTaskScheduled(event->target()->GetExecutionContext(),
-                            event->type(), event);
-  pending_events_.insert(event);
-  // This queue is unthrottled because throttling event tasks may break existing
-  // web pages. For example, throttling IndexedDB events may break scenarios
-  // where several tabs, some of which are backgrounded, access the same
-  // database concurrently. See also comments in the ctor of
-  // DOMWindowEventQueueTimer.
-  // TODO(nhiroki): Callers of enqueueEvent() should specify the task type.
-  global_scope_->GetTaskRunner(TaskType::kInternalWorker)
-      ->PostTask(from_here,
-                 WTF::Bind(&WorkerEventQueue::DispatchEvent,
-                           WrapPersistent(this), WrapWeakPersistent(event)));
-  return true;
-}
-
-bool WorkerEventQueue::CancelEvent(Event* event) {
-  if (!RemoveEvent(event))
-    return false;
-  probe::AsyncTaskCanceled(event->target()->GetExecutionContext(), event);
-  return true;
-}
-
-void WorkerEventQueue::Close() {
-  is_closed_ = true;
-  for (const auto& event : pending_events_)
-    probe::AsyncTaskCanceled(event->target()->GetExecutionContext(), event);
-  pending_events_.clear();
-}
-
-bool WorkerEventQueue::RemoveEvent(Event* event) {
-  auto found = pending_events_.find(event);
-  if (found == pending_events_.end())
-    return false;
-  pending_events_.erase(found);
-  return true;
-}
-
-void WorkerEventQueue::DispatchEvent(Event* event) {
-  if (!event || !RemoveEvent(event))
-    return;
-
-  probe::AsyncTask async_task(global_scope_, event);
-  event->target()->DispatchEvent(event);
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/workers/worker_event_queue.h b/third_party/blink/renderer/core/workers/worker_event_queue.h
deleted file mode 100644
index 23b1664..0000000
--- a/third_party/blink/renderer/core/workers/worker_event_queue.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_WORKERS_WORKER_EVENT_QUEUE_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_WORKERS_WORKER_EVENT_QUEUE_H_
-
-#include "third_party/blink/renderer/core/dom/events/event_queue.h"
-#include "third_party/blink/renderer/platform/wtf/hash_set.h"
-
-namespace blink {
-
-class Event;
-class WorkerOrWorkletGlobalScope;
-
-// TODO(nhiroki): Rename this class to WorkerOrWorkletEventQueue and add
-// class-level comments.
-class WorkerEventQueue final : public EventQueue {
- public:
-  static WorkerEventQueue* Create(WorkerOrWorkletGlobalScope*);
-  ~WorkerEventQueue() override;
-  void Trace(blink::Visitor*) override;
-
-  // EventQueue
-  bool EnqueueEvent(const base::Location&, Event*) override;
-  bool CancelEvent(Event*) override;
-  void Close() override;
-
- private:
-  explicit WorkerEventQueue(WorkerOrWorkletGlobalScope*);
-  bool RemoveEvent(Event*);
-  void DispatchEvent(Event*);
-
-  Member<WorkerOrWorkletGlobalScope> global_scope_;
-  bool is_closed_ = false;
-
-  HeapHashSet<Member<Event>> pending_events_;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_WORKERS_WORKER_EVENT_QUEUE_H_
diff --git a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc
index 85cff03..bed279d 100644
--- a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc
+++ b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc
@@ -7,6 +7,7 @@
 #include "third_party/blink/public/platform/task_type.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.h"
 #include "third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h"
+#include "third_party/blink/renderer/core/dom/events/event_queue_impl.h"
 #include "third_party/blink/renderer/core/frame/deprecation.h"
 #include "third_party/blink/renderer/core/inspector/console_message.h"
 #include "third_party/blink/renderer/core/loader/modulescript/module_script_fetch_request.h"
@@ -29,7 +30,7 @@
     : worker_clients_(worker_clients),
       script_controller_(
           WorkerOrWorkletScriptController::Create(this, isolate)),
-      event_queue_(WorkerEventQueue::Create(this)),
+      event_queue_(EventQueueImpl::Create(this, TaskType::kInternalWorker)),
       reporting_proxy_(reporting_proxy),
       used_features_(static_cast<int>(WebFeature::kNumberOfFeatures)) {
   if (worker_clients_)
diff --git a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h
index e81b7b8..3438baee 100644
--- a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h
+++ b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h
@@ -15,12 +15,13 @@
 #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
 #include "third_party/blink/renderer/core/frame/web_feature_forward.h"
 #include "third_party/blink/renderer/core/workers/worker_clients.h"
-#include "third_party/blink/renderer/core/workers/worker_event_queue.h"
 #include "third_party/blink/renderer/platform/scheduler/child/worker_scheduler.h"
 #include "third_party/blink/renderer/platform/wtf/bit_vector.h"
 
 namespace blink {
 
+class EventQueue;
+class EventQueueImpl;
 class Modulator;
 class ModuleTreeClient;
 class ResourceFetcher;
@@ -123,7 +124,7 @@
   CrossThreadPersistent<WorkerClients> worker_clients_;
   Member<ResourceFetcher> resource_fetcher_;
   Member<WorkerOrWorkletScriptController> script_controller_;
-  Member<WorkerEventQueue> event_queue_;
+  Member<EventQueueImpl> event_queue_;
 
   WorkerReportingProxy& reporting_proxy_;
 
diff --git a/third_party/blink/renderer/core/workers/worklet_global_scope.cc b/third_party/blink/renderer/core/workers/worklet_global_scope.cc
index 6e17c05f..f93dd49 100644
--- a/third_party/blink/renderer/core/workers/worklet_global_scope.cc
+++ b/third_party/blink/renderer/core/workers/worklet_global_scope.cc
@@ -44,7 +44,7 @@
   // |url_| is the inheritedAPIBaseURL passed from the parent Document.
 
   // Step 3: "Let origin be a unique opaque origin."
-  SetSecurityOrigin(SecurityOrigin::CreateUnique());
+  SetSecurityOrigin(SecurityOrigin::CreateUniqueOpaque());
 
   // Step 5: "Let inheritedReferrerPolicy be outsideSettings's referrer policy."
   SetReferrerPolicy(creation_params->referrer_policy);
diff --git a/third_party/blink/renderer/core/xml/xpath_evaluator.cc b/third_party/blink/renderer/core/xml/xpath_evaluator.cc
index 280c034..3fe930e5 100644
--- a/third_party/blink/renderer/core/xml/xpath_evaluator.cc
+++ b/third_party/blink/renderer/core/xml/xpath_evaluator.cc
@@ -27,6 +27,7 @@
 #include "third_party/blink/renderer/core/xml/xpath_evaluator.h"
 
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
 #include "third_party/blink/renderer/core/dom/exception_code.h"
 #include "third_party/blink/renderer/core/dom/node.h"
 #include "third_party/blink/renderer/core/xml/native_xpath_ns_resolver.h"
diff --git a/third_party/blink/renderer/devtools/front_end/sdk/ChildTargetManager.js b/third_party/blink/renderer/devtools/front_end/sdk/ChildTargetManager.js
index 938c219..2142c20 100644
--- a/third_party/blink/renderer/devtools/front_end/sdk/ChildTargetManager.js
+++ b/third_party/blink/renderer/devtools/front_end/sdk/ChildTargetManager.js
@@ -107,6 +107,15 @@
     this._fireAvailableTargetsChanged();
   }
 
+  /**
+   * @override
+   * @param {string} targetId
+   * @param {string} status
+   * @param {number} errorCode
+   */
+  targetCrashed(targetId, status, errorCode) {
+  }
+
   _fireAvailableTargetsChanged() {
     SDK.targetManager.dispatchEventToListeners(
         SDK.TargetManager.Events.AvailableTargetsChanged, this._targetInfos.valuesArray());
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
index 431c2bf7..15e3ac83 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
@@ -195,7 +195,7 @@
   ConvertRequestDeviceOptions(options, device_options, exception_state);
 
   if (exception_state.HadException())
-    return exception_state.Reject(script_state);
+    return ScriptPromise();
 
   // Record the eTLD+1 of the frame using the API.
   Document* document = ToDocument(context);
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.cc
index 7693e1e..dbfe208 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.cc
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.cc
@@ -300,7 +300,7 @@
   String descriptor =
       BluetoothUUID::getDescriptor(descriptor_uuid, exception_state);
   if (exception_state.HadException())
-    return exception_state.Reject(script_state);
+    return ScriptPromise();
 
   return GetDescriptorsImpl(script_state,
                             mojom::blink::WebBluetoothGATTQueryQuantity::SINGLE,
@@ -321,7 +321,7 @@
   String descriptor =
       BluetoothUUID::getDescriptor(descriptor_uuid, exception_state);
   if (exception_state.HadException())
-    return exception_state.Reject(script_state);
+    return ScriptPromise();
 
   return GetDescriptorsImpl(
       script_state, mojom::blink::WebBluetoothGATTQueryQuantity::MULTIPLE,
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.h b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.h
index a6ab54b7..8a9c2b4 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.h
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.h
@@ -21,6 +21,7 @@
 
 class BluetoothCharacteristicProperties;
 class BluetoothDevice;
+class DOMException;
 class ExecutionContext;
 class ScriptPromise;
 class ScriptState;
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc
index 415c692..3dee7b14 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.cc
@@ -190,7 +190,7 @@
     ExceptionState& exception_state) {
   String service_uuid = BluetoothUUID::getService(service, exception_state);
   if (exception_state.HadException())
-    return exception_state.Reject(script_state);
+    return ScriptPromise();
 
   return GetPrimaryServicesImpl(
       script_state, mojom::blink::WebBluetoothGATTQueryQuantity::SINGLE,
@@ -203,7 +203,7 @@
     ExceptionState& exception_state) {
   String service_uuid = BluetoothUUID::getService(service, exception_state);
   if (exception_state.HadException())
-    return exception_state.Reject(script_state);
+    return ScriptPromise();
 
   return GetPrimaryServicesImpl(
       script_state, mojom::blink::WebBluetoothGATTQueryQuantity::MULTIPLE,
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.cc
index 422cb70..e13f8fce 100644
--- a/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.cc
+++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.cc
@@ -93,7 +93,7 @@
   String characteristic_uuid =
       BluetoothUUID::getCharacteristic(characteristic, exception_state);
   if (exception_state.HadException())
-    return exception_state.Reject(script_state);
+    return ScriptPromise();
 
   return GetCharacteristicsImpl(
       script_state, mojom::blink::WebBluetoothGATTQueryQuantity::SINGLE,
@@ -107,7 +107,7 @@
   String characteristic_uuid =
       BluetoothUUID::getCharacteristic(characteristic, exception_state);
   if (exception_state.HadException())
-    return exception_state.Reject(script_state);
+    return ScriptPromise();
 
   return GetCharacteristicsImpl(
       script_state, mojom::blink::WebBluetoothGATTQueryQuantity::MULTIPLE,
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
index 357d8c5..938be70 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
@@ -470,7 +470,7 @@
   ModifiableState().SetTransform(new_transform);
   if (!GetState().IsTransformInvertible())
     return;
-  c->rotate(clampTo<float>(angle_in_radians * (180.0 / piFloat)));
+  c->rotate(clampTo<float>(angle_in_radians * (180.0 / kPiFloat)));
   path_.Transform(AffineTransform().RotateRadians(-angle_in_radians));
 }
 
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc
index 9790fb6..8cd1aeb 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.cc
@@ -154,10 +154,10 @@
    * from the ellipse's semi-major axis, acts as both the start point and the
    * end point.
    */
-  if (!anticlockwise && end_angle - start_angle >= twoPiFloat) {
-    new_end_angle = start_angle + twoPiFloat;
-  } else if (anticlockwise && start_angle - end_angle >= twoPiFloat) {
-    new_end_angle = start_angle - twoPiFloat;
+  if (!anticlockwise && end_angle - start_angle >= kTwoPiFloat) {
+    new_end_angle = start_angle + kTwoPiFloat;
+  } else if (anticlockwise && start_angle - end_angle >= kTwoPiFloat) {
+    new_end_angle = start_angle - kTwoPiFloat;
 
     /*
      * Otherwise, the arc is the path along the circumference of this ellipse
@@ -173,11 +173,11 @@
      * We preserve backward-compatibility.
      */
   } else if (!anticlockwise && start_angle > end_angle) {
-    new_end_angle =
-        start_angle + (twoPiFloat - fmodf(start_angle - end_angle, twoPiFloat));
+    new_end_angle = start_angle +
+                    (kTwoPiFloat - fmodf(start_angle - end_angle, kTwoPiFloat));
   } else if (anticlockwise && start_angle < end_angle) {
-    new_end_angle =
-        start_angle - (twoPiFloat - fmodf(end_angle - start_angle, twoPiFloat));
+    new_end_angle = start_angle -
+                    (kTwoPiFloat - fmodf(end_angle - start_angle, kTwoPiFloat));
   }
 
   DCHECK(EllipseIsRenderable(start_angle, new_end_angle));
@@ -196,21 +196,22 @@
 
 void CanonicalizeAngle(float* start_angle, float* end_angle) {
   // Make 0 <= startAngle < 2*PI
-  float new_start_angle = fmodf(*start_angle, twoPiFloat);
+  float new_start_angle = fmodf(*start_angle, kTwoPiFloat);
 
   if (new_start_angle < 0) {
-    new_start_angle += twoPiFloat;
+    new_start_angle += kTwoPiFloat;
     // Check for possible catastrophic cancellation in cases where
     // newStartAngle was a tiny negative number (c.f. crbug.com/503422)
-    if (new_start_angle >= twoPiFloat)
-      new_start_angle -= twoPiFloat;
+    if (new_start_angle >= kTwoPiFloat)
+      new_start_angle -= kTwoPiFloat;
   }
 
   float delta = new_start_angle - *start_angle;
   *start_angle = new_start_angle;
   *end_angle = *end_angle + delta;
 
-  DCHECK(new_start_angle >= 0 && new_start_angle < twoPiFloat);
+  DCHECK_GE(new_start_angle, 0);
+  DCHECK_LT(new_start_angle, kTwoPiFloat);
 }
 
 /*
@@ -256,7 +257,8 @@
                        float end_angle,
                        bool anticlockwise) {
   DCHECK(EllipseIsRenderable(start_angle, end_angle));
-  DCHECK(start_angle >= 0 && start_angle < twoPiFloat);
+  DCHECK_GE(start_angle, 0);
+  DCHECK_LT(start_angle, kTwoPiFloat);
   DCHECK((anticlockwise && (start_angle - end_angle) >= 0) ||
          (!anticlockwise && (end_angle - start_angle) >= 0));
 
@@ -272,19 +274,19 @@
     return;
 
   if (!anticlockwise) {
-    // startAngle - fmodf(startAngle, piOverTwoFloat) + piOverTwoFloat is the
-    // one of (0, 0.5Pi, Pi, 1.5Pi, 2Pi) that is the closest to startAngle on
-    // the clockwise direction.
-    for (float angle =
-             start_angle - fmodf(start_angle, piOverTwoFloat) + piOverTwoFloat;
-         angle < end_angle; angle += piOverTwoFloat) {
+    // start_angle - fmodf(start_angle, kPiOverTwoFloat) + kPiOverTwoFloat is
+    // the one of (0, 0.5Pi, Pi, 1.5Pi, 2Pi) that is the closest to start_angle
+    // on the clockwise direction.
+    for (float angle = start_angle - fmodf(start_angle, kPiOverTwoFloat) +
+                       kPiOverTwoFloat;
+         angle < end_angle; angle += kPiOverTwoFloat) {
       LineToFloatPoint(
           path, center + rotation_matrix.MapPoint(
                              GetPointOnEllipse(radius_x, radius_y, angle)));
     }
   } else {
-    for (float angle = start_angle - fmodf(start_angle, piOverTwoFloat);
-         angle > end_angle; angle -= piOverTwoFloat) {
+    for (float angle = start_angle - fmodf(start_angle, kPiOverTwoFloat);
+         angle > end_angle; angle -= kPiOverTwoFloat) {
       LineToFloatPoint(
           path, center + rotation_matrix.MapPoint(
                              GetPointOnEllipse(radius_x, radius_y, angle)));
diff --git a/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc b/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc
index 8fcc0038..ce676355 100644
--- a/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc
+++ b/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc
@@ -77,7 +77,7 @@
     info->password = password_credential->password();
     info->name = password_credential->name();
     info->icon = password_credential->iconURL();
-    info->federation = blink::SecurityOrigin::CreateUnique();
+    info->federation = blink::SecurityOrigin::CreateUniqueOpaque();
   } else {
     DCHECK(credential->IsFederatedCredential());
     ::blink::FederatedCredential* federated_credential =
diff --git a/third_party/blink/renderer/modules/credentialmanager/credentials_container_test.cc b/third_party/blink/renderer/modules/credentialmanager/credentials_container_test.cc
index a47f3e4..7d8b2c19 100644
--- a/third_party/blink/renderer/modules/credentialmanager/credentials_container_test.cc
+++ b/third_party/blink/renderer/modules/credentialmanager/credentials_container_test.cc
@@ -59,7 +59,7 @@
 
     auto info = password_manager::mojom::blink::CredentialInfo::New();
     info->type = password_manager::mojom::blink::CredentialType::EMPTY;
-    info->federation = SecurityOrigin::CreateUnique();
+    info->federation = SecurityOrigin::CreateUniqueOpaque();
     std::move(get_callback_)
         .Run(password_manager::mojom::blink::CredentialManagerError::SUCCESS,
              std::move(info));
diff --git a/third_party/blink/renderer/modules/mediastream/media_devices.cc b/third_party/blink/renderer/modules/mediastream/media_devices.cc
index 891c586..2f06c31 100644
--- a/third_party/blink/renderer/modules/mediastream/media_devices.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_devices.cc
@@ -127,7 +127,7 @@
     DCHECK(error_state.HadException());
     if (error_state.CanGenerateException()) {
       error_state.RaiseException(exception_state);
-      return exception_state.Reject(script_state);
+      return ScriptPromise();
     }
     ScriptPromise rejected_promise = resolver->Promise();
     resolver->Reject(error_state.CreateError());
diff --git a/third_party/blink/renderer/modules/mediastream/media_devices_test.cc b/third_party/blink/renderer/modules/mediastream/media_devices_test.cc
index eab5ff0..19cf1df 100644
--- a/third_party/blink/renderer/modules/mediastream/media_devices_test.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_devices_test.cc
@@ -11,6 +11,8 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/bindings/core/v8/exception_state.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_function.h"
+#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
 #include "third_party/blink/renderer/core/testing/null_execution_context.h"
 #include "third_party/blink/renderer/modules/mediastream/media_stream_constraints.h"
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_track.cc b/third_party/blink/renderer/modules/mediastream/media_stream_track.cc
index 88430ca..d87c818 100644
--- a/third_party/blink/renderer/modules/mediastream/media_stream_track.cc
+++ b/third_party/blink/renderer/modules/mediastream/media_stream_track.cc
@@ -332,6 +332,10 @@
     for (bool value : platform_capabilities.noise_suppression)
       noise_suppression.push_back(value);
     capabilities.setNoiseSuppression(noise_suppression);
+    Vector<String> echo_cancellation_type;
+    for (String value : platform_capabilities.echo_cancellation_type)
+      echo_cancellation_type.push_back(value);
+    capabilities.setEchoCancellationType(echo_cancellation_type);
   }
 
   if (component_->Source()->GetType() == MediaStreamSource::kTypeVideo) {
diff --git a/third_party/blink/renderer/modules/mediastream/media_track_capabilities.idl b/third_party/blink/renderer/modules/mediastream/media_track_capabilities.idl
index 10667aa..3a56aa44 100644
--- a/third_party/blink/renderer/modules/mediastream/media_track_capabilities.idl
+++ b/third_party/blink/renderer/modules/mediastream/media_track_capabilities.idl
@@ -9,6 +9,8 @@
     DoubleRange frameRate;
     sequence<DOMString> facingMode;
     sequence<boolean> echoCancellation;
+    // See http://crbug.com/846270.
+    [OriginTrialEnabled=ExperimentalHardwareEchoCancellation] sequence<DOMString> echoCancellationType;
     sequence<boolean> autoGainControl;
     sequence<boolean> noiseSuppression;
     DOMString deviceId;
diff --git a/third_party/blink/renderer/modules/modules_idl_files.gni b/third_party/blink/renderer/modules/modules_idl_files.gni
index ec5674b..b599bfa6 100644
--- a/third_party/blink/renderer/modules/modules_idl_files.gni
+++ b/third_party/blink/renderer/modules/modules_idl_files.gni
@@ -579,6 +579,7 @@
           "peerconnection/rtc_offer_answer_options.idl",
           "peerconnection/rtc_offer_options.idl",
           "peerconnection/rtc_peer_connection_ice_event_init.idl",
+          "peerconnection/rtc_rtcp_parameters.idl",
           "peerconnection/rtc_rtp_codec_parameters.idl",
           "peerconnection/rtc_rtp_encoding_parameters.idl",
           "peerconnection/rtc_rtp_parameters.idl",
diff --git a/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.cc b/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.cc
index 4fc5040..c59cbe58 100644
--- a/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.cc
+++ b/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.cc
@@ -39,28 +39,27 @@
 
   // If context object's active worker is null, reject the promise with a
   // TypeError exception.
-  if (!registration.active())
-    return ScriptPromise::Reject(
-        script_state,
-        V8ThrowException::CreateTypeError(script_state->GetIsolate(),
-                                          "No active registration available on "
-                                          "the ServiceWorkerRegistration."));
+  if (!registration.active()) {
+    exception_state.ThrowTypeError(
+        "No active registration available on "
+        "the ServiceWorkerRegistration.");
+    return ScriptPromise();
+  }
 
   // If permission for notification's origin is not "granted", reject the
   // promise with a TypeError exception, and terminate these substeps.
   if (NotificationManager::From(execution_context)->GetPermissionStatus() !=
-      mojom::blink::PermissionStatus::GRANTED)
-    return ScriptPromise::Reject(
-        script_state,
-        V8ThrowException::CreateTypeError(
-            script_state->GetIsolate(),
-            "No notification permission has been granted for this origin."));
+      mojom::blink::PermissionStatus::GRANTED) {
+    exception_state.ThrowTypeError(
+        "No notification permission has been granted for this origin.");
+    return ScriptPromise();
+  }
 
   // Validate the developer-provided options to get the WebNotificationData.
   WebNotificationData data = CreateWebNotificationData(
       execution_context, title, options, exception_state);
   if (exception_state.HadException())
-    return exception_state.Reject(script_state);
+    return ScriptPromise();
 
   // Log number of actions developer provided in linear histogram:
   //     0    -> underflow bucket,
diff --git a/third_party/blink/renderer/modules/payments/basic_card_helper.h b/third_party/blink/renderer/modules/payments/basic_card_helper.h
index 7b650634..4ab4164 100644
--- a/third_party/blink/renderer/modules/payments/basic_card_helper.h
+++ b/third_party/blink/renderer/modules/payments/basic_card_helper.h
@@ -11,6 +11,8 @@
 
 namespace blink {
 
+class ScriptValue;
+
 class BasicCardHelper {
   STATIC_ONLY(BasicCardHelper);
 
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
index 6d8878d..cff73cf 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -1074,18 +1074,18 @@
 
 ScriptPromise RTCPeerConnection::addIceCandidate(
     ScriptState* script_state,
-    const RTCIceCandidateInitOrRTCIceCandidate& candidate) {
+    const RTCIceCandidateInitOrRTCIceCandidate& candidate,
+    ExceptionState& exception_state) {
   if (signaling_state_ == kSignalingStateClosed)
     return ScriptPromise::RejectWithDOMException(
         script_state,
         DOMException::Create(kInvalidStateError, kSignalingStateClosedMessage));
 
-  if (IsIceCandidateMissingSdp(candidate))
-    return ScriptPromise::Reject(
-        script_state,
-        V8ThrowException::CreateTypeError(
-            script_state->GetIsolate(),
-            "Candidate missing values for both sdpMid and sdpMLineIndex"));
+  if (IsIceCandidateMissingSdp(candidate)) {
+    exception_state.ThrowTypeError(
+        "Candidate missing values for both sdpMid and sdpMLineIndex");
+    return ScriptPromise();
+  }
 
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
   ScriptPromise promise = resolver->Promise();
@@ -1105,19 +1105,19 @@
     ScriptState* script_state,
     const RTCIceCandidateInitOrRTCIceCandidate& candidate,
     V8VoidFunction* success_callback,
-    V8RTCPeerConnectionErrorCallback* error_callback) {
+    V8RTCPeerConnectionErrorCallback* error_callback,
+    ExceptionState& exception_state) {
   DCHECK(success_callback);
   DCHECK(error_callback);
 
   if (CallErrorCallbackIfSignalingStateClosed(signaling_state_, error_callback))
     return ScriptPromise::CastUndefined(script_state);
 
-  if (IsIceCandidateMissingSdp(candidate))
-    return ScriptPromise::Reject(
-        script_state,
-        V8ThrowException::CreateTypeError(
-            script_state->GetIsolate(),
-            "Candidate missing values for both sdpMid and sdpMLineIndex"));
+  if (IsIceCandidateMissingSdp(candidate)) {
+    exception_state.ThrowTypeError(
+        "Candidate missing values for both sdpMid and sdpMLineIndex");
+    return ScriptPromise();
+  }
 
   RTCVoidRequest* request = RTCVoidRequestImpl::Create(
       GetExecutionContext(), this, success_callback, error_callback);
@@ -1319,7 +1319,7 @@
   exception_state.ThrowTypeError(
       "The argument provided as parameter 1 is neither a callback (function) "
       "or selector (MediaStreamTrack or null).");
-  return exception_state.Reject(script_state);
+  return ScriptPromise::Reject(script_state, exception_state);
 }
 
 ScriptPromise RTCPeerConnection::getStats(ScriptState* script_state,
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
index faf41aeb..5f080d6 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
@@ -131,11 +131,13 @@
       ExceptionState&);
 
   ScriptPromise addIceCandidate(ScriptState*,
-                                const RTCIceCandidateInitOrRTCIceCandidate&);
+                                const RTCIceCandidateInitOrRTCIceCandidate&,
+                                ExceptionState&);
   ScriptPromise addIceCandidate(ScriptState*,
                                 const RTCIceCandidateInitOrRTCIceCandidate&,
                                 V8VoidFunction*,
-                                V8RTCPeerConnectionErrorCallback*);
+                                V8RTCPeerConnectionErrorCallback*,
+                                ExceptionState&);
 
   String iceGatheringState() const;
 
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.idl b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.idl
index 293e6f1d..323bf996 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.idl
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.idl
@@ -77,7 +77,7 @@
     readonly attribute RTCSessionDescription? remoteDescription;
     // readonly attribute RTCSessionDescription? currentRemoteDescription;
     // readonly attribute RTCSessionDescription? pendingRemoteDescription;
-    [CallWith=ScriptState, MeasureAs=RTCPeerConnectionAddIceCandidatePromise] Promise<void> addIceCandidate ((RTCIceCandidateInit or RTCIceCandidate) candidate);
+    [CallWith=ScriptState, RaisesException, MeasureAs=RTCPeerConnectionAddIceCandidatePromise] Promise<void> addIceCandidate((RTCIceCandidateInit or RTCIceCandidate) candidate);
     readonly attribute RTCSignalingState signalingState;
     readonly attribute RTCIceGatheringState iceGatheringState;
     readonly attribute RTCIceConnectionState iceConnectionState;
@@ -102,7 +102,7 @@
     // TODO(guidou): The failureCallback argument should be non-optional.
     // TODO(crbug.com/841185): |failureCallback| is not nullable in the spec.
     [CallWith=ScriptState] Promise<void> setRemoteDescription(RTCSessionDescriptionInit description, VoidFunction successCallback, optional RTCPeerConnectionErrorCallback? failureCallback);
-    [CallWith=ScriptState, MeasureAs=RTCPeerConnectionAddIceCandidateLegacy] Promise<void> addIceCandidate((RTCIceCandidateInit or RTCIceCandidate) candidate, VoidFunction successCallback, RTCPeerConnectionErrorCallback failureCallback);
+    [CallWith=ScriptState, RaisesException, MeasureAs=RTCPeerConnectionAddIceCandidateLegacy] Promise<void> addIceCandidate((RTCIceCandidateInit or RTCIceCandidate) candidate, VoidFunction successCallback, RTCPeerConnectionErrorCallback failureCallback);
 
     // Legacy getStats() API. The returned metrics are a completely different
     // set of metrics than the standard compliant version, presented in a
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtcp_parameters.idl b/third_party/blink/renderer/modules/peerconnection/rtc_rtcp_parameters.idl
new file mode 100644
index 0000000..fc0f41746
--- /dev/null
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtcp_parameters.idl
@@ -0,0 +1,9 @@
+// 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.
+
+// https://w3c.github.io/webrtc-pc/#rtcrtcpparameters*
+dictionary RTCRtcpParameters {
+    DOMString cname;
+    boolean   reducedSize;
+};
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_parameters.idl b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_parameters.idl
index d6ea3e2..d99b1f4e 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_parameters.idl
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_parameters.idl
@@ -6,5 +6,6 @@
 dictionary RTCRtpParameters {
     DOMString                                 transactionId;
     sequence<RTCRtpEncodingParameters>        encodings;
+    required RTCRtcpParameters                rtcp;
     sequence<RTCRtpCodecParameters>           codecs;
 };
\ No newline at end of file
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
index 56489c4..d9fce92 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
@@ -76,8 +76,9 @@
                             const RTCRtpParameters& new_parameters) {
   if (parameters.hasTransactionId() != new_parameters.hasTransactionId() ||
       (parameters.hasTransactionId() &&
-       parameters.transactionId() != new_parameters.transactionId()))
+       parameters.transactionId() != new_parameters.transactionId())) {
     return true;
+  }
 
   if (parameters.hasEncodings() != new_parameters.hasEncodings())
     return true;
@@ -86,6 +87,19 @@
       return true;
   }
 
+  if (parameters.hasRtcp() != new_parameters.hasRtcp() ||
+      (parameters.hasRtcp() &&
+       ((parameters.rtcp().hasCname() != new_parameters.rtcp().hasCname() ||
+         (parameters.rtcp().hasCname() &&
+          parameters.rtcp().cname() != new_parameters.rtcp().cname())) ||
+        (parameters.rtcp().hasReducedSize() !=
+             new_parameters.rtcp().hasReducedSize() ||
+         (parameters.rtcp().hasReducedSize() &&
+          parameters.rtcp().reducedSize() !=
+              new_parameters.rtcp().reducedSize()))))) {
+    return true;
+  }
+
   if (parameters.hasCodecs() != new_parameters.hasCodecs())
     return true;
 
@@ -233,6 +247,11 @@
 
   parameters.setTransactionId(webrtc_parameters->transaction_id.c_str());
 
+  RTCRtcpParameters rtcp;
+  rtcp.setCname(webrtc_parameters->rtcp.cname.c_str());
+  rtcp.setReducedSize(webrtc_parameters->rtcp.reduced_size);
+  parameters.setRtcp(rtcp);
+
   HeapVector<RTCRtpEncodingParameters> encodings;
   encodings.ReserveCapacity(webrtc_parameters->encodings.size());
   for (const auto& web_encoding : webrtc_parameters->encodings) {
diff --git a/third_party/blink/renderer/modules/permissions/permissions.cc b/third_party/blink/renderer/modules/permissions/permissions.cc
index 7e25fc4..351e2f2 100644
--- a/third_party/blink/renderer/modules/permissions/permissions.cc
+++ b/third_party/blink/renderer/modules/permissions/permissions.cc
@@ -147,14 +147,12 @@
 }  // anonymous namespace
 
 ScriptPromise Permissions::query(ScriptState* script_state,
-                                 const Dictionary& raw_permission) {
-  ExceptionState exception_state(script_state->GetIsolate(),
-                                 ExceptionState::kGetterContext, "Permissions",
-                                 "query");
+                                 const Dictionary& raw_permission,
+                                 ExceptionState& exception_state) {
   PermissionDescriptorPtr descriptor =
       ParsePermission(script_state, raw_permission, exception_state);
   if (exception_state.HadException())
-    return exception_state.Reject(script_state);
+    return ScriptPromise();
 
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
   ScriptPromise promise = resolver->Promise();
@@ -173,14 +171,12 @@
 }
 
 ScriptPromise Permissions::request(ScriptState* script_state,
-                                   const Dictionary& raw_permission) {
-  ExceptionState exception_state(script_state->GetIsolate(),
-                                 ExceptionState::kGetterContext, "Permissions",
-                                 "request");
+                                   const Dictionary& raw_permission,
+                                   ExceptionState& exception_state) {
   PermissionDescriptorPtr descriptor =
       ParsePermission(script_state, raw_permission, exception_state);
   if (exception_state.HadException())
-    return exception_state.Reject(script_state);
+    return ScriptPromise();
 
   ExecutionContext* context = ExecutionContext::From(script_state);
 
@@ -202,14 +198,12 @@
 }
 
 ScriptPromise Permissions::revoke(ScriptState* script_state,
-                                  const Dictionary& raw_permission) {
-  ExceptionState exception_state(script_state->GetIsolate(),
-                                 ExceptionState::kGetterContext, "Permissions",
-                                 "revoke");
+                                  const Dictionary& raw_permission,
+                                  ExceptionState& exception_state) {
   PermissionDescriptorPtr descriptor =
       ParsePermission(script_state, raw_permission, exception_state);
   if (exception_state.HadException())
-    return exception_state.Reject(script_state);
+    return ScriptPromise();
 
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
   ScriptPromise promise = resolver->Promise();
@@ -224,12 +218,9 @@
   return promise;
 }
 
-ScriptPromise Permissions::requestAll(
-    ScriptState* script_state,
-    const Vector<Dictionary>& raw_permissions) {
-  ExceptionState exception_state(script_state->GetIsolate(),
-                                 ExceptionState::kGetterContext, "Permissions",
-                                 "requestAll");
+ScriptPromise Permissions::requestAll(ScriptState* script_state,
+                                      const Vector<Dictionary>& raw_permissions,
+                                      ExceptionState& exception_state) {
   Vector<PermissionDescriptorPtr> internal_permissions;
   Vector<int> caller_index_to_internal_index;
   caller_index_to_internal_index.resize(raw_permissions.size());
@@ -239,7 +230,7 @@
     auto descriptor =
         ParsePermission(script_state, raw_permission, exception_state);
     if (exception_state.HadException())
-      return exception_state.Reject(script_state);
+      return ScriptPromise();
 
     // Only append permissions types that are not already present in the vector.
     size_t internal_index = kNotFound;
diff --git a/third_party/blink/renderer/modules/permissions/permissions.h b/third_party/blink/renderer/modules/permissions/permissions.h
index d9d7d71..b753e856 100644
--- a/third_party/blink/renderer/modules/permissions/permissions.h
+++ b/third_party/blink/renderer/modules/permissions/permissions.h
@@ -21,10 +21,12 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  ScriptPromise query(ScriptState*, const Dictionary&);
-  ScriptPromise request(ScriptState*, const Dictionary&);
-  ScriptPromise revoke(ScriptState*, const Dictionary&);
-  ScriptPromise requestAll(ScriptState*, const Vector<Dictionary>&);
+  ScriptPromise query(ScriptState*, const Dictionary&, ExceptionState&);
+  ScriptPromise request(ScriptState*, const Dictionary&, ExceptionState&);
+  ScriptPromise revoke(ScriptState*, const Dictionary&, ExceptionState&);
+  ScriptPromise requestAll(ScriptState*,
+                           const Vector<Dictionary>&,
+                           ExceptionState&);
 
  private:
   mojom::blink::PermissionService& GetService(ExecutionContext*);
diff --git a/third_party/blink/renderer/modules/permissions/permissions.idl b/third_party/blink/renderer/modules/permissions/permissions.idl
index 121b762..3c43fccb 100644
--- a/third_party/blink/renderer/modules/permissions/permissions.idl
+++ b/third_party/blink/renderer/modules/permissions/permissions.idl
@@ -9,8 +9,8 @@
     Exposed=(Window,Worker),
     RuntimeEnabled=Permissions
 ] interface Permissions {
-    [CallWith=ScriptState, Measure] Promise<PermissionStatus> query(Dictionary permission);
-    [RuntimeEnabled=PermissionsRequestRevoke, CallWith=ScriptState, Measure] Promise<PermissionStatus> request(Dictionary permissions);
-    [RuntimeEnabled=PermissionsRequestRevoke, CallWith=ScriptState, Measure] Promise<PermissionStatus> revoke(Dictionary permission);
-    [RuntimeEnabled=PermissionsRequestRevoke, CallWith=ScriptState, Measure] Promise<sequence<PermissionStatus>> requestAll(sequence<Dictionary> permissions);
+    [CallWith=ScriptState, RaisesException, Measure] Promise<PermissionStatus> query(Dictionary permission);
+    [RuntimeEnabled=PermissionsRequestRevoke, CallWith=ScriptState, RaisesException, Measure] Promise<PermissionStatus> request(Dictionary permissions);
+    [RuntimeEnabled=PermissionsRequestRevoke, CallWith=ScriptState, RaisesException, Measure] Promise<PermissionStatus> revoke(Dictionary permission);
+    [RuntimeEnabled=PermissionsRequestRevoke, CallWith=ScriptState, RaisesException, Measure] Promise<sequence<PermissionStatus>> requestAll(sequence<Dictionary> permissions);
 };
diff --git a/third_party/blink/renderer/modules/webaudio/periodic_wave.cc b/third_party/blink/renderer/modules/webaudio/periodic_wave.cc
index 675bf799..d18ab2d 100644
--- a/third_party/blink/renderer/modules/webaudio/periodic_wave.cc
+++ b/third_party/blink/renderer/modules/webaudio/periodic_wave.cc
@@ -319,7 +319,7 @@
   imag_p[0] = 0;
 
   for (unsigned n = 1; n < half_size; ++n) {
-    float pi_factor = 2 / (n * piFloat);
+    float pi_factor = 2 / (n * kPiFloat);
 
     // All waveforms are odd functions with a positive slope at time 0. Hence
     // the coefficients for cos() are always 0.
diff --git a/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc b/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc
index f061b2e..e6a293d 100644
--- a/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc
+++ b/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc
@@ -124,7 +124,7 @@
   for (unsigned i = 0; i < n; ++i) {
     double x = static_cast<double>(i) / static_cast<double>(n);
     double window =
-        a0 - a1 * cos(twoPiDouble * x) + a2 * cos(twoPiDouble * 2.0 * x);
+        a0 - a1 * cos(kTwoPiDouble * x) + a2 * cos(kTwoPiDouble * 2.0 * x);
     p[i] *= float(window);
   }
 }
diff --git a/third_party/blink/renderer/platform/audio/biquad.cc b/third_party/blink/renderer/platform/audio/biquad.cc
index c9a643d..a970890 100644
--- a/third_party/blink/renderer/platform/audio/biquad.cc
+++ b/third_party/blink/renderer/platform/audio/biquad.cc
@@ -276,7 +276,7 @@
 
     resonance = pow10(resonance / 20);
 
-    double theta = piDouble * cutoff;
+    double theta = kPiDouble * cutoff;
     double alpha = sin(theta) / (2 * resonance);
     double cosw = cos(theta);
     double beta = (1 - cosw) / 2;
@@ -308,7 +308,7 @@
     // Compute biquad coefficients for highpass filter
 
     resonance = pow10(resonance / 20);
-    double theta = piDouble * cutoff;
+    double theta = kPiDouble * cutoff;
     double alpha = sin(theta) / (2 * resonance);
     double cosw = cos(theta);
     double beta = (1 + cosw) / 2;
@@ -357,7 +357,7 @@
     // The z-transform is a constant gain.
     SetNormalizedCoefficients(index, a * a, 0, 0, 1, 0, 0);
   } else if (frequency > 0) {
-    double w0 = piDouble * frequency;
+    double w0 = kPiDouble * frequency;
     double s = 1;  // filter slope (1 is max value)
     double alpha = 0.5 * sin(w0) * sqrt((a + 1 / a) * (1 / s - 1) + 2);
     double k = cos(w0);
@@ -389,7 +389,7 @@
     // The z-transform is 1.
     SetNormalizedCoefficients(index, 1, 0, 0, 1, 0, 0);
   } else if (frequency > 0) {
-    double w0 = piDouble * frequency;
+    double w0 = kPiDouble * frequency;
     double s = 1;  // filter slope (1 is max value)
     double alpha = 0.5 * sin(w0) * sqrt((a + 1 / a) * (1 / s - 1) + 2);
     double k = cos(w0);
@@ -425,7 +425,7 @@
 
   if (frequency > 0 && frequency < 1) {
     if (q > 0) {
-      double w0 = piDouble * frequency;
+      double w0 = kPiDouble * frequency;
       double alpha = sin(w0) / (2 * q);
       double k = cos(w0);
 
@@ -458,7 +458,7 @@
 
   if (frequency > 0 && frequency < 1) {
     if (q > 0) {
-      double w0 = piDouble * frequency;
+      double w0 = kPiDouble * frequency;
       double alpha = sin(w0) / (2 * q);
       double k = cos(w0);
 
@@ -491,7 +491,7 @@
 
   if (frequency > 0 && frequency < 1) {
     if (q > 0) {
-      double w0 = piDouble * frequency;
+      double w0 = kPiDouble * frequency;
       double alpha = sin(w0) / (2 * q);
       double k = cos(w0);
 
@@ -523,7 +523,7 @@
   q = std::max(0.0, q);
 
   if (frequency > 0 && frequency < 1) {
-    double w0 = piDouble * frequency;
+    double w0 = kPiDouble * frequency;
     if (q > 0) {
       double alpha = sin(w0) / (2 * q);
       double k = cos(w0);
@@ -585,7 +585,7 @@
       mag_response[k] = std::nanf("");
       phase_response[k] = std::nanf("");
     } else {
-      double omega = -piDouble * frequency[k];
+      double omega = -kPiDouble * frequency[k];
       std::complex<double> z = std::complex<double>(cos(omega), sin(omega));
       std::complex<double> numerator = b0 + (b1 + b2 * z) * z;
       std::complex<double> denominator =
diff --git a/third_party/blink/renderer/platform/audio/down_sampler.cc b/third_party/blink/renderer/platform/audio/down_sampler.cc
index 9041597..ad5fb79d 100644
--- a/third_party/blink/renderer/platform/audio/down_sampler.cc
+++ b/third_party/blink/renderer/platform/audio/down_sampler.cc
@@ -60,14 +60,14 @@
   // processing after doing the main convolution using m_reducedKernel.
   for (int i = 1; i < n; i += 2) {
     // Compute the sinc() with offset.
-    double s = sinc_scale_factor * piDouble * (i - half_size);
+    double s = sinc_scale_factor * kPiDouble * (i - half_size);
     double sinc = !s ? 1.0 : sin(s) / s;
     sinc *= sinc_scale_factor;
 
     // Compute Blackman window, matching the offset of the sinc().
     double x = static_cast<double>(i) / n;
     double window =
-        a0 - a1 * cos(twoPiDouble * x) + a2 * cos(twoPiDouble * 2.0 * x);
+        a0 - a1 * cos(kTwoPiDouble * x) + a2 * cos(kTwoPiDouble * 2.0 * x);
 
     // Window the sinc() function.
     // Then store only the odd terms in the kernel.
diff --git a/third_party/blink/renderer/platform/audio/dynamics_compressor_kernel.cc b/third_party/blink/renderer/platform/audio/dynamics_compressor_kernel.cc
index 94ad47b..34a85f0 100644
--- a/third_party/blink/renderer/platform/audio/dynamics_compressor_kernel.cc
+++ b/third_party/blink/renderer/platform/audio/dynamics_compressor_kernel.cc
@@ -297,7 +297,7 @@
     float desired_gain = detector_average_;
 
     // Pre-warp so we get desiredGain after sin() warp below.
-    float scaled_desired_gain = asinf(desired_gain) / (piOverTwoFloat);
+    float scaled_desired_gain = asinf(desired_gain) / kPiOverTwoFloat;
 
     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     // Deal with envelopes
@@ -440,7 +440,7 @@
         // Warp pre-compression gain to smooth out sharp exponential transition
         // points.
         float post_warp_compressor_gain =
-            sinf(piOverTwoFloat * compressor_gain);
+            sinf(kPiOverTwoFloat * compressor_gain);
 
         // Calculate total gain using master gain and effect blend.
         float total_gain =
diff --git a/third_party/blink/renderer/platform/audio/equal_power_panner.cc b/third_party/blink/renderer/platform/audio/equal_power_panner.cc
index c6a80d7..a87f17b 100644
--- a/third_party/blink/renderer/platform/audio/equal_power_panner.cc
+++ b/third_party/blink/renderer/platform/audio/equal_power_panner.cc
@@ -101,8 +101,8 @@
     }
   }
 
-  desired_gain_l = std::cos(piOverTwoDouble * desired_pan_position);
-  desired_gain_r = std::sin(piOverTwoDouble * desired_pan_position);
+  desired_gain_l = std::cos(kPiOverTwoDouble * desired_pan_position);
+  desired_gain_r = std::sin(kPiOverTwoDouble * desired_pan_position);
 
   int n = frames_to_process;
 
@@ -170,8 +170,8 @@
     }
   }
 
-  desired_gain_l = std::cos(piOverTwoDouble * desired_pan_position);
-  desired_gain_r = std::sin(piOverTwoDouble * desired_pan_position);
+  desired_gain_l = std::cos(kPiOverTwoDouble * desired_pan_position);
+  desired_gain_r = std::sin(kPiOverTwoDouble * desired_pan_position);
 }
 
 void EqualPowerPanner::PanWithSampleAccurateValues(
diff --git a/third_party/blink/renderer/platform/audio/fft_frame.cc b/third_party/blink/renderer/platform/audio/fft_frame.cc
index bde6baf..55c658a5 100644
--- a/third_party/blink/renderer/platform/audio/fft_frame.cc
+++ b/third_party/blink/renderer/platform/audio/fft_frame.cc
@@ -139,32 +139,35 @@
     last_phase2 = phase2;
 
     // Unwrap phase deltas
-    if (delta_phase1 > piDouble)
-      delta_phase1 -= twoPiDouble;
-    if (delta_phase1 < -piDouble)
-      delta_phase1 += twoPiDouble;
-    if (delta_phase2 > piDouble)
-      delta_phase2 -= twoPiDouble;
-    if (delta_phase2 < -piDouble)
-      delta_phase2 += twoPiDouble;
+    if (delta_phase1 > kPiDouble)
+      delta_phase1 -= kTwoPiDouble;
+    if (delta_phase1 < -kPiDouble)
+      delta_phase1 += kTwoPiDouble;
+    if (delta_phase2 > kPiDouble)
+      delta_phase2 -= kTwoPiDouble;
+    if (delta_phase2 < -kPiDouble)
+      delta_phase2 += kTwoPiDouble;
 
     // Blend group-delays
     double delta_phase_blend;
 
-    if (delta_phase1 - delta_phase2 > piDouble)
-      delta_phase_blend = s1 * delta_phase1 + s2 * (twoPiDouble + delta_phase2);
-    else if (delta_phase2 - delta_phase1 > piDouble)
-      delta_phase_blend = s1 * (twoPiDouble + delta_phase1) + s2 * delta_phase2;
-    else
+    if (delta_phase1 - delta_phase2 > kPiDouble) {
+      delta_phase_blend =
+          s1 * delta_phase1 + s2 * (kTwoPiDouble + delta_phase2);
+    } else if (delta_phase2 - delta_phase1 > kPiDouble) {
+      delta_phase_blend =
+          s1 * (kTwoPiDouble + delta_phase1) + s2 * delta_phase2;
+    } else {
       delta_phase_blend = s1 * delta_phase1 + s2 * delta_phase2;
+    }
 
     phase_accum += delta_phase_blend;
 
     // Unwrap
-    if (phase_accum > piDouble)
-      phase_accum -= twoPiDouble;
-    if (phase_accum < -piDouble)
-      phase_accum += twoPiDouble;
+    if (phase_accum > kPiDouble)
+      phase_accum -= kTwoPiDouble;
+    if (phase_accum < -kPiDouble)
+      phase_accum += kTwoPiDouble;
 
     std::complex<double> c = std::polar(mag, phase_accum);
 
@@ -184,7 +187,7 @@
   int half_size = FftSize() / 2;
 
   const double sample_phase_delay =
-      (twoPiDouble) / static_cast<double>(FftSize());
+      kTwoPiDouble / static_cast<double>(FftSize());
 
   // Calculate weighted average group delay
   for (int i = 0; i < half_size; i++) {
@@ -196,10 +199,10 @@
     last_phase = phase;
 
     // Unwrap
-    if (delta_phase < -piDouble)
-      delta_phase += twoPiDouble;
-    if (delta_phase > piDouble)
-      delta_phase -= twoPiDouble;
+    if (delta_phase < -kPiDouble)
+      delta_phase += kTwoPiDouble;
+    if (delta_phase > kPiDouble)
+      delta_phase -= kTwoPiDouble;
 
     ave_sum += mag * delta_phase;
     weight_sum += mag;
@@ -230,7 +233,7 @@
   float* imag_p = ImagData();
 
   const double sample_phase_delay =
-      (twoPiDouble) / static_cast<double>(FftSize());
+      kTwoPiDouble / static_cast<double>(FftSize());
 
   double phase_adj = -sample_frame_delay * sample_phase_delay;
 
diff --git a/third_party/blink/renderer/platform/audio/iir_filter.cc b/third_party/blink/renderer/platform/audio/iir_filter.cc
index 6ce33eb..b9e435e 100644
--- a/third_party/blink/renderer/platform/audio/iir_filter.cc
+++ b/third_party/blink/renderer/platform/audio/iir_filter.cc
@@ -135,7 +135,7 @@
       phase_response[k] = std::nanf("");
     } else {
       // zRecip = 1/z = exp(-j*frequency)
-      double omega = -piDouble * frequency[k];
+      double omega = -kPiDouble * frequency[k];
       std::complex<double> z_recip =
           std::complex<double>(cos(omega), sin(omega));
 
diff --git a/third_party/blink/renderer/platform/audio/sinc_resampler.cc b/third_party/blink/renderer/platform/audio/sinc_resampler.cc
index 79a1681e..c949fa60 100644
--- a/third_party/blink/renderer/platform/audio/sinc_resampler.cc
+++ b/third_party/blink/renderer/platform/audio/sinc_resampler.cc
@@ -117,14 +117,14 @@
     for (int i = 0; i < n; ++i) {
       // Compute the sinc() with offset.
       double s =
-          sinc_scale_factor * piDouble * (i - half_size - subsample_offset);
+          sinc_scale_factor * kPiDouble * (i - half_size - subsample_offset);
       double sinc = !s ? 1.0 : std::sin(s) / s;
       sinc *= sinc_scale_factor;
 
       // Compute Blackman window, matching the offset of the sinc().
       double x = (i - subsample_offset) / n;
-      double window = a0 - a1 * std::cos(twoPiDouble * x) +
-                      a2 * std::cos(twoPiDouble * 2.0 * x);
+      double window = a0 - a1 * std::cos(kTwoPiDouble * x) +
+                      a2 * std::cos(kTwoPiDouble * 2.0 * x);
 
       // Window the sinc() function and store at the correct offset.
       kernel_storage_[i + offset_index * kernel_size_] = sinc * window;
diff --git a/third_party/blink/renderer/platform/audio/stereo_panner.cc b/third_party/blink/renderer/platform/audio/stereo_panner.cc
index 6c911eb..d375cd2 100644
--- a/third_party/blink/renderer/platform/audio/stereo_panner.cc
+++ b/third_party/blink/renderer/platform/audio/stereo_panner.cc
@@ -63,7 +63,7 @@
       float input_l = *source_l++;
       double pan = clampTo(*pan_values++, -1.0, 1.0);
       // Pan from left to right [-1; 1] will be normalized as [0; 1].
-      pan_radian = (pan * 0.5 + 0.5) * piOverTwoDouble;
+      pan_radian = (pan * 0.5 + 0.5) * kPiOverTwoDouble;
       gain_l = std::cos(pan_radian);
       gain_r = std::sin(pan_radian);
       *destination_l++ = static_cast<float>(input_l * gain_l);
@@ -75,7 +75,7 @@
       float input_r = *source_r++;
       double pan = clampTo(*pan_values++, -1.0, 1.0);
       // Normalize [-1; 0] to [0; 1]. Do nothing when [0; 1].
-      pan_radian = (pan <= 0 ? pan + 1 : pan) * piOverTwoDouble;
+      pan_radian = (pan <= 0 ? pan + 1 : pan) * kPiOverTwoDouble;
       gain_l = std::cos(pan_radian);
       gain_r = std::sin(pan_radian);
       if (pan <= 0) {
@@ -126,7 +126,7 @@
 
   if (number_of_input_channels == 1) {  // For mono source case.
     // Pan from left to right [-1; 1] will be normalized as [0; 1].
-    double pan_radian = (target_pan * 0.5 + 0.5) * piOverTwoDouble;
+    double pan_radian = (target_pan * 0.5 + 0.5) * kPiOverTwoDouble;
 
     double gain_l = std::cos(pan_radian);
     double gain_r = std::sin(pan_radian);
@@ -141,7 +141,7 @@
     // Normalize [-1; 0] to [0; 1] for the left pan position (<= 0), and
     // do nothing when [0; 1].
     double pan_radian =
-        (target_pan <= 0 ? target_pan + 1 : target_pan) * piOverTwoDouble;
+        (target_pan <= 0 ? target_pan + 1 : target_pan) * kPiOverTwoDouble;
 
     double gain_l = std::cos(pan_radian);
     double gain_r = std::sin(pan_radian);
diff --git a/third_party/blink/renderer/platform/audio/up_sampler.cc b/third_party/blink/renderer/platform/audio/up_sampler.cc
index 62eae932..6931ac09 100644
--- a/third_party/blink/renderer/platform/audio/up_sampler.cc
+++ b/third_party/blink/renderer/platform/audio/up_sampler.cc
@@ -57,13 +57,13 @@
 
   for (int i = 0; i < n; ++i) {
     // Compute the sinc() with offset.
-    double s = piDouble * (i - half_size - subsample_offset);
+    double s = kPiDouble * (i - half_size - subsample_offset);
     double sinc = !s ? 1.0 : sin(s) / s;
 
     // Compute Blackman window, matching the offset of the sinc().
     double x = (i - subsample_offset) / n;
     double window =
-        a0 - a1 * cos(twoPiDouble * x) + a2 * cos(twoPiDouble * 2.0 * x);
+        a0 - a1 * cos(kTwoPiDouble * x) + a2 * cos(kTwoPiDouble * 2.0 * x);
 
     // Window the sinc() function.
     (*kernel)[i] = sinc * window;
diff --git a/third_party/blink/renderer/platform/exported/web_cors.cc b/third_party/blink/renderer/platform/exported/web_cors.cc
index a1582c0b8..bfb5dba 100644
--- a/third_party/blink/renderer/platform/exported/web_cors.cc
+++ b/third_party/blink/renderer/platform/exported/web_cors.cc
@@ -163,7 +163,7 @@
     // Set request's origin to a globally unique identifier as specified in
     // the step 10 in https://fetch.spec.whatwg.org/#http-redirect-fetch.
     if (!last_origin->CanRequest(new_url)) {
-      options.security_origin = SecurityOrigin::CreateUnique();
+      options.security_origin = SecurityOrigin::CreateUniqueOpaque();
       new_security_origin = options.security_origin;
     }
   }
diff --git a/third_party/blink/renderer/platform/exported/web_media_constraints.cc b/third_party/blink/renderer/platform/exported/web_media_constraints.cc
index 05dade6..62855e8 100644
--- a/third_party/blink/renderer/platform/exported/web_media_constraints.cc
+++ b/third_party/blink/renderer/platform/exported/web_media_constraints.cc
@@ -72,6 +72,9 @@
 
 }  // namespace
 
+const char kEchoCancellationTypeBrowser[] = "browser";
+const char kEchoCancellationTypeSystem[] = "system";
+
 class WebMediaConstraintsPrivate final
     : public ThreadSafeRefCounted<WebMediaConstraintsPrivate> {
  public:
diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
index ed8d99b..a5d097f 100644
--- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc
+++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -252,6 +252,10 @@
   RuntimeEnabledFeatures::SetOverflowIconsForMediaControlsEnabled(enable);
 }
 
+void WebRuntimeFeatures::EnablePageLifecycle(bool enable) {
+  RuntimeEnabledFeatures::SetPageLifecycleEnabled(enable);
+}
+
 void WebRuntimeFeatures::EnablePagePopup(bool enable) {
   RuntimeEnabledFeatures::SetPagePopupEnabled(enable);
 }
diff --git a/third_party/blink/renderer/platform/exported/web_security_origin.cc b/third_party/blink/renderer/platform/exported/web_security_origin.cc
index c4d47789..b27ecac 100644
--- a/third_party/blink/renderer/platform/exported/web_security_origin.cc
+++ b/third_party/blink/renderer/platform/exported/web_security_origin.cc
@@ -45,8 +45,8 @@
   return WebSecurityOrigin(SecurityOrigin::Create(url));
 }
 
-WebSecurityOrigin WebSecurityOrigin::CreateUnique() {
-  return WebSecurityOrigin(SecurityOrigin::CreateUnique());
+WebSecurityOrigin WebSecurityOrigin::CreateUniqueOpaque() {
+  return WebSecurityOrigin(SecurityOrigin::CreateUniqueOpaque());
 }
 
 void WebSecurityOrigin::Reset() {
diff --git a/third_party/blink/renderer/platform/feature_policy/feature_policy_test.cc b/third_party/blink/renderer/platform/feature_policy/feature_policy_test.cc
index 8701132a..cf572f81 100644
--- a/third_party/blink/renderer/platform/feature_policy/feature_policy_test.cc
+++ b/third_party/blink/renderer/platform/feature_policy/feature_policy_test.cc
@@ -215,7 +215,8 @@
 TEST_F(FeaturePolicyTest, PolicyParsedCorrectlyForOpaqueOrigins) {
   Vector<String> messages;
 
-  scoped_refptr<SecurityOrigin> opaque_origin = SecurityOrigin::CreateUnique();
+  scoped_refptr<SecurityOrigin> opaque_origin =
+      SecurityOrigin::CreateUniqueOpaque();
 
   // Empty policy.
   ParsedFeaturePolicy parsed_policy =
diff --git a/third_party/blink/renderer/platform/fonts/script_run_iterator.cc b/third_party/blink/renderer/platform/fonts/script_run_iterator.cc
index df6bc30..ca054ad 100644
--- a/third_party/blink/renderer/platform/fonts/script_run_iterator.cc
+++ b/third_party/blink/renderer/platform/fonts/script_run_iterator.cc
@@ -120,6 +120,8 @@
     : text_(text),
       length_(length),
       brackets_fixup_depth_(0),
+      next_set_(std::make_unique<UScriptCodeList>()),
+      ahead_set_(std::make_unique<UScriptCodeList>()),
       // The initial value of m_aheadCharacter is not used.
       ahead_character_(0),
       ahead_pos_(0),
@@ -135,7 +137,7 @@
     // chosing the script of the first consumed character.
     current_set_.push_back(USCRIPT_COMMON);
     U16_NEXT(text_, ahead_pos_, length_, ahead_character_);
-    script_data_->GetScripts(ahead_character_, ahead_set_);
+    script_data_->GetScripts(ahead_character_, *ahead_set_);
   }
 }
 
@@ -165,7 +167,7 @@
       limit = pos;
       script = ResolveCurrentScript();
       FixupStack(script);
-      current_set_ = next_set_;
+      current_set_ = *next_set_;
       return true;
     }
   }
@@ -194,8 +196,8 @@
       if (it->ch == target) {
         // Have a match, use open paren's resolved script.
         UScriptCode script = it->script;
-        next_set_.clear();
-        next_set_.push_back(script);
+        next_set_->clear();
+        next_set_->push_back(script);
 
         // And pop stack to this point.
         int num_popped = std::distance(brackets_.rbegin(), it);
@@ -222,7 +224,7 @@
 // common, and there is no common preferred script and next has a preferred
 // script, set the common preferred script to that of next.
 bool ScriptRunIterator::MergeSets() {
-  if (next_set_.IsEmpty() || current_set_.IsEmpty()) {
+  if (next_set_->IsEmpty() || current_set_.IsEmpty()) {
     return false;
   }
 
@@ -234,24 +236,24 @@
 
   // If next is common or inherited, the only thing that might change
   // is the common preferred script.
-  if (next_set_.at(0) <= USCRIPT_INHERITED) {
-    if (next_set_.size() == 2 && priority_script <= USCRIPT_INHERITED &&
+  if (next_set_->at(0) <= USCRIPT_INHERITED) {
+    if (next_set_->size() == 2 && priority_script <= USCRIPT_INHERITED &&
         common_preferred_ == USCRIPT_COMMON) {
-      common_preferred_ = next_set_.at(1);
+      common_preferred_ = next_set_->at(1);
     }
     return true;
   }
 
   // If current is common or inherited, use the next script set.
   if (priority_script <= USCRIPT_INHERITED) {
-    current_set_ = next_set_;
+    current_set_ = *next_set_;
     return true;
   }
 
   // Neither is common or inherited. If current is a singleton,
   // just see if it exists in the next set. This is the common case.
-  auto* next_it = next_set_.begin();
-  auto* next_end = next_set_.end();
+  auto* next_it = next_set_->begin();
+  auto* next_end = next_set_->end();
   if (current_set_it == current_end) {
     return std::find(next_it, next_end, priority_script) != next_end;
   }
@@ -327,7 +329,7 @@
   *pos = ahead_pos_ - (ahead_character_ >= 0x10000 ? 2 : 1);
   *ch = ahead_character_;
 
-  next_set_.swap(ahead_set_);
+  std::swap(next_set_, ahead_set_);
   if (ahead_pos_ == length_) {
     // No more data to fetch, but last character still needs to be
     // processed. Advance m_aheadPos so that next time we will know
@@ -337,22 +339,22 @@
   }
 
   U16_NEXT(text_, ahead_pos_, length_, ahead_character_);
-  script_data_->GetScripts(ahead_character_, ahead_set_);
-  if (ahead_set_.IsEmpty()) {
+  script_data_->GetScripts(ahead_character_, *ahead_set_);
+  if (ahead_set_->IsEmpty()) {
     // No scripts for this character. This has already been logged, so
     // we just terminate processing this text.
     return false;
   }
-  if (ahead_set_[0] == USCRIPT_INHERITED && ahead_set_.size() > 1) {
-    if (next_set_[0] == USCRIPT_COMMON) {
+  if ((*ahead_set_)[0] == USCRIPT_INHERITED && ahead_set_->size() > 1) {
+    if ((*next_set_)[0] == USCRIPT_COMMON) {
       // Overwrite the next set with the non-inherited portion of the set.
-      next_set_ = ahead_set_;
-      next_set_.EraseAt(0);
+      *next_set_ = *ahead_set_;
+      next_set_->EraseAt(0);
       // Discard the remaining values, we'll inherit.
-      ahead_set_.resize(1);
+      ahead_set_->resize(1);
     } else {
       // Else, this applies to anything.
-      ahead_set_.resize(1);
+      ahead_set_->resize(1);
     }
   }
   return true;
diff --git a/third_party/blink/renderer/platform/fonts/script_run_iterator.h b/third_party/blink/renderer/platform/fonts/script_run_iterator.h
index 919863e1..6fc6095 100644
--- a/third_party/blink/renderer/platform/fonts/script_run_iterator.h
+++ b/third_party/blink/renderer/platform/fonts/script_run_iterator.h
@@ -60,8 +60,11 @@
   static const int kMaxBrackets = 32;
 
   UScriptCodeList current_set_;
-  UScriptCodeList next_set_;
-  UScriptCodeList ahead_set_;
+  // Because next_set_ and ahead_set_ are swapped as we consume characters, and
+  // swapping inlined vector is not cheap, next_set_ and ahead_set_ are
+  // pointers.
+  std::unique_ptr<UScriptCodeList> next_set_;
+  std::unique_ptr<UScriptCodeList> ahead_set_;
 
   UChar32 ahead_character_;
   size_t ahead_pos_;
diff --git a/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.cc b/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.cc
index 78384c9..a1046f3 100644
--- a/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.cc
+++ b/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.cc
@@ -84,8 +84,8 @@
 }
 
 static void HueRotateMatrix(float hue, SkScalar matrix[kColorMatrixSize]) {
-  float cos_hue = cosf(hue * piFloat / 180);
-  float sin_hue = sinf(hue * piFloat / 180);
+  float cos_hue = cosf(hue * kPiFloat / 180);
+  float sin_hue = sinf(hue * kPiFloat / 180);
   matrix[0] = 0.213f + cos_hue * 0.787f - sin_hue * 0.213f;
   matrix[1] = 0.715f - cos_hue * 0.715f - sin_hue * 0.715f;
   matrix[2] = 0.072f - cos_hue * 0.072f + sin_hue * 0.928f;
diff --git a/third_party/blink/renderer/platform/graphics/filters/fe_gaussian_blur.cc b/third_party/blink/renderer/platform/graphics/filters/fe_gaussian_blur.cc
index f04200b8..53325c61 100644
--- a/third_party/blink/renderer/platform/graphics/filters/fe_gaussian_blur.cc
+++ b/third_party/blink/renderer/platform/graphics/filters/fe_gaussian_blur.cc
@@ -37,7 +37,7 @@
 
 inline unsigned ApproximateBoxWidth(float s) {
   return static_cast<unsigned>(
-      floorf(s * (3 / 4.f * sqrtf(twoPiFloat)) + 0.5f));
+      floorf(s * (3 / 4.f * sqrtf(kTwoPiFloat)) + 0.5f));
 }
 
 IntSize CalculateKernelSize(const FloatSize& std) {
diff --git a/third_party/blink/renderer/platform/graphics/path.cc b/third_party/blink/renderer/platform/graphics/path.cc
index 3a90e06..1da4c73 100644
--- a/third_party/blink/renderer/platform/graphics/path.cc
+++ b/third_party/blink/renderer/platform/graphics/path.cc
@@ -353,7 +353,7 @@
                       bool anticlockwise) {
   DCHECK(EllipseIsRenderable(start_angle, end_angle));
   DCHECK_GE(start_angle, 0);
-  DCHECK_LT(start_angle, twoPiFloat);
+  DCHECK_LT(start_angle, kTwoPiFloat);
   DCHECK((anticlockwise && (start_angle - end_angle) >= 0) ||
          (!anticlockwise && (end_angle - start_angle) >= 0));
 
@@ -367,8 +367,8 @@
            cy + radius_y_scalar);
 
   float sweep = end_angle - start_angle;
-  SkScalar start_degrees = WebCoreFloatToSkScalar(start_angle * 180 / piFloat);
-  SkScalar sweep_degrees = WebCoreFloatToSkScalar(sweep * 180 / piFloat);
+  SkScalar start_degrees = WebCoreFloatToSkScalar(start_angle * 180 / kPiFloat);
+  SkScalar sweep_degrees = WebCoreFloatToSkScalar(sweep * 180 / kPiFloat);
   SkScalar s360 = SkIntToScalar(360);
 
   // We can't use SkPath::addOval(), because addOval() makes a new sub-path.
@@ -415,7 +415,7 @@
                       bool anticlockwise) {
   DCHECK(EllipseIsRenderable(start_angle, end_angle));
   DCHECK_GE(start_angle, 0);
-  DCHECK_LT(start_angle, twoPiFloat);
+  DCHECK_LT(start_angle, kTwoPiFloat);
   DCHECK((anticlockwise && (start_angle - end_angle) >= 0) ||
          (!anticlockwise && (end_angle - start_angle) >= 0));
 
@@ -535,8 +535,9 @@
 }
 
 bool EllipseIsRenderable(float start_angle, float end_angle) {
-  return (std::abs(end_angle - start_angle) < twoPiFloat) ||
-         WebCoreFloatNearlyEqual(std::abs(end_angle - start_angle), twoPiFloat);
+  return (std::abs(end_angle - start_angle) < kTwoPiFloat) ||
+         WebCoreFloatNearlyEqual(std::abs(end_angle - start_angle),
+                                 kTwoPiFloat);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/heap.cc b/third_party/blink/renderer/platform/heap/heap.cc
index f71f7abc..b32f34c 100644
--- a/third_party/blink/renderer/platform/heap/heap.cc
+++ b/third_party/blink/renderer/platform/heap/heap.cc
@@ -236,7 +236,7 @@
 
 HeapCompact* ThreadHeap::Compaction() {
   if (!compaction_)
-    compaction_ = HeapCompact::Create();
+    compaction_ = HeapCompact::Create(this);
   return compaction_.get();
 }
 
@@ -275,7 +275,9 @@
 
 void ThreadHeap::InvokeEphemeronCallbacks(Visitor* visitor) {
   // Mark any strong pointers that have now become reachable in ephemeron maps.
-  TRACE_EVENT0("blink_gc", "ThreadHeap::InvokeEphemeronCallbacks");
+  ThreadHeapStatsCollector::Scope stats_scope(
+      stats_collector(),
+      ThreadHeapStatsCollector::kMarkInvokeEphemeronCallbacks);
 
   // Avoid supporting a subtle scheme that allows insertion while iterating
   // by just creating temporary lists for iteration and sinking.
@@ -303,8 +305,9 @@
   do {
     {
       // Iteratively mark all objects that are reachable from the objects
-      // currently pushed onto the marking stack.
-      TRACE_EVENT0("blink_gc", "ThreadHeap::processMarkingStackSingleThreaded");
+      // currently pushed onto the marking worklist.
+      ThreadHeapStatsCollector::Scope stats_scope(
+          stats_collector(), ThreadHeapStatsCollector::kMarkProcessWorklist);
       MarkingItem item;
       while (marking_worklist_->Pop(WorklistTaskId::MainThread, &item)) {
         item.callback(visitor, item.object);
@@ -325,8 +328,8 @@
 }
 
 void ThreadHeap::WeakProcessing(Visitor* visitor) {
-  TRACE_EVENT0("blink_gc", "ThreadHeap::WeakProcessing");
-  double start_time = WTF::CurrentTimeTicksInMilliseconds();
+  ThreadHeapStatsCollector::Scope stats_scope(
+      stats_collector(), ThreadHeapStatsCollector::kMarkWeakProcessing);
 
   // Weak processing may access unmarked objects but are forbidden from
   // ressurecting them.
@@ -340,13 +343,6 @@
   }
   // Weak callbacks should not add any new objects for marking.
   DCHECK(marking_worklist_->IsGlobalEmpty());
-
-  double time_for_weak_processing =
-      WTF::CurrentTimeTicksInMilliseconds() - start_time;
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(
-      CustomCountHistogram, weak_processing_time_histogram,
-      ("BlinkGC.TimeForGlobalWeakProcessing", 1, 10 * 1000, 50));
-  weak_processing_time_histogram.Count(time_for_weak_processing);
 }
 
 void ThreadHeap::VerifyMarking() {
@@ -448,14 +444,16 @@
 }
 
 void ThreadHeap::VisitPersistentRoots(Visitor* visitor) {
+  ThreadHeapStatsCollector::Scope stats_scope(
+      stats_collector(), ThreadHeapStatsCollector::kVisitPersistentRoots);
   DCHECK(thread_state_->InAtomicMarkingPause());
-  TRACE_EVENT0("blink_gc", "ThreadHeap::visitPersistentRoots");
   thread_state_->VisitPersistents(visitor);
 }
 
 void ThreadHeap::VisitStackRoots(MarkingVisitor* visitor) {
+  ThreadHeapStatsCollector::Scope stats_scope(
+      stats_collector(), ThreadHeapStatsCollector::kVisitStackRoots);
   DCHECK(thread_state_->InAtomicMarkingPause());
-  TRACE_EVENT0("blink_gc", "ThreadHeap::visitStackRoots");
   address_cache_->FlushIfDirty();
   address_cache_->EnableLookup();
   thread_state_->VisitStack(visitor);
@@ -498,6 +496,8 @@
   if (!Compaction()->IsCompacting())
     return;
 
+  ThreadHeapStatsCollector::Scope stats_scope(
+      stats_collector(), ThreadHeapStatsCollector::kAtomicPhaseCompaction);
   // Compaction is done eagerly and before the mutator threads get
   // to run again. Doing it lazily is problematic, as the mutator's
   // references to live objects could suddenly be invalidated by
diff --git a/third_party/blink/renderer/platform/heap/heap_compact.cc b/third_party/blink/renderer/platform/heap/heap_compact.cc
index 7bff2f4..94e5923 100644
--- a/third_party/blink/renderer/platform/heap/heap_compact.cc
+++ b/third_party/blink/renderer/platform/heap/heap_compact.cc
@@ -8,6 +8,7 @@
 
 #include "base/memory/ptr_util.h"
 #include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
 #include "third_party/blink/renderer/platform/heap/sparse_heap_bitmap.h"
 #include "third_party/blink/renderer/platform/histogram.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
@@ -256,14 +257,12 @@
   std::unique_ptr<SparseHeapBitmap> interiors_;
 };
 
-HeapCompact::HeapCompact()
-    : do_compact_(false),
+HeapCompact::HeapCompact(ThreadHeap* heap)
+    : heap_(heap),
+      do_compact_(false),
       gc_count_since_last_compaction_(0),
       free_list_size_(0),
-      compactable_arenas_(0u),
-      freed_pages_(0),
-      freed_size_(0),
-      start_compaction_time_ms_(0) {
+      compactable_arenas_(0u) {
   // The heap compaction implementation assumes the contiguous range,
   //
   //   [Vector1ArenaIndex, HashTableArenaIndex]
@@ -330,7 +329,7 @@
   // TODO: add some form of compaction overhead estimate to the marking
   // time estimate.
 
-  UpdateHeapResidency(heap);
+  UpdateHeapResidency();
 
 #if STRESS_TEST_HEAP_COMPACTION
   // Exercise the handling of object movement by compacting as
@@ -348,8 +347,6 @@
   DCHECK(RuntimeEnabledFeatures::HeapCompactionEnabled());
   LOG_HEAP_COMPACTION() << "Compacting: free=" << free_list_size_;
   do_compact_ = true;
-  freed_pages_ = 0;
-  freed_size_ = 0;
   fixups_.reset();
   gc_count_since_last_compaction_ = 0;
   force_compaction_gc_ = false;
@@ -371,7 +368,7 @@
   Fixups().AddFixupCallback(reference, callback, callback_data);
 }
 
-void HeapCompact::UpdateHeapResidency(ThreadHeap* heap) {
+void HeapCompact::UpdateHeapResidency() {
   size_t total_arena_size = 0;
   size_t total_free_list_size = 0;
 
@@ -381,7 +378,7 @@
 #endif
   for (int i = BlinkGC::kVector1ArenaIndex; i <= BlinkGC::kHashTableArenaIndex;
        ++i) {
-    NormalPageArena* arena = static_cast<NormalPageArena*>(heap->Arena(i));
+    NormalPageArena* arena = static_cast<NormalPageArena*>(heap_->Arena(i));
     size_t arena_size = arena->ArenaSize();
     size_t free_list_size = arena->FreeListSize();
     total_arena_size += arena_size;
@@ -412,8 +409,8 @@
   if (!do_compact_)
     return;
 
-  freed_pages_ += freed_pages;
-  freed_size_ += freed_size;
+  heap_->stats_collector()->IncreaseCompactionFreedPages(freed_pages);
+  heap_->stats_collector()->IncreaseCompactionFreedSize(freed_size);
 }
 
 void HeapCompact::Relocate(Address from, Address to) {
@@ -424,9 +421,6 @@
 void HeapCompact::StartThreadCompaction() {
   if (!do_compact_)
     return;
-
-  if (!start_compaction_time_ms_)
-    start_compaction_time_ms_ = WTF::CurrentTimeTicksInMilliseconds();
 }
 
 void HeapCompact::FinishThreadCompaction() {
@@ -439,28 +433,6 @@
 #endif
   fixups_.reset();
   do_compact_ = false;
-
-  double time_for_heap_compaction =
-      WTF::CurrentTimeTicksInMilliseconds() - start_compaction_time_ms_;
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(
-      CustomCountHistogram, time_for_heap_compaction_histogram,
-      ("BlinkGC.TimeForHeapCompaction", 1, 10 * 1000, 50));
-  time_for_heap_compaction_histogram.Count(time_for_heap_compaction);
-  start_compaction_time_ms_ = 0;
-
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(
-      CustomCountHistogram, object_size_freed_by_heap_compaction,
-      ("BlinkGC.ObjectSizeFreedByHeapCompaction", 1, 4 * 1024 * 1024, 50));
-  object_size_freed_by_heap_compaction.Count(freed_size_ / 1024);
-
-#if DEBUG_LOG_HEAP_COMPACTION_RUNNING_TIME
-  LOG_HEAP_COMPACTION_INTERNAL()
-      << "Compaction stats: time=" << time_for_heap_compaction
-      << "ms, pages freed=" << freed_pages_ << ", size=" << freed_size_;
-#else
-  LOG_HEAP_COMPACTION() << "Compaction stats: freed pages=" << freed_pages_
-                        << " size=" << freed_size_;
-#endif
 }
 
 void HeapCompact::AddCompactingPage(BasePage* page) {
diff --git a/third_party/blink/renderer/platform/heap/heap_compact.h b/third_party/blink/renderer/platform/heap/heap_compact.h
index 30d489e..dc32e77b 100644
--- a/third_party/blink/renderer/platform/heap/heap_compact.h
+++ b/third_party/blink/renderer/platform/heap/heap_compact.h
@@ -42,8 +42,8 @@
 
 class PLATFORM_EXPORT HeapCompact final {
  public:
-  static std::unique_ptr<HeapCompact> Create() {
-    return base::WrapUnique(new HeapCompact);
+  static std::unique_ptr<HeapCompact> Create(ThreadHeap* heap) {
+    return base::WrapUnique(new HeapCompact(heap));
   }
 
   ~HeapCompact();
@@ -129,13 +129,13 @@
  private:
   class MovableObjectFixups;
 
-  HeapCompact();
+  explicit HeapCompact(ThreadHeap*);
 
   // Sample the amount of fragmentation and heap memory currently residing
   // on the freelists of the arenas we're able to compact. The computed
   // numbers will be subsequently used to determine if a heap compaction
   // is on order (shouldCompact().)
-  void UpdateHeapResidency(ThreadHeap*);
+  void UpdateHeapResidency();
 
   // Parameters controlling when compaction should be done:
 
@@ -146,6 +146,8 @@
   // should be considered.
   static const size_t kFreeListSizeThreshold = 512 * 1024;
 
+  ThreadHeap* const heap_;
+
   MovableObjectFixups& Fixups();
 
   std::unique_ptr<MovableObjectFixups> fixups_;
@@ -162,13 +164,6 @@
   // the range of BlinkGC::ArenaIndices.
   unsigned compactable_arenas_;
 
-  // Stats, number of (complete) pages freed/decommitted +
-  // bytes freed (which will include partial pages.)
-  size_t freed_pages_;
-  size_t freed_size_;
-
-  double start_compaction_time_ms_;
-
   static bool force_compaction_gc_;
 };
 
diff --git a/third_party/blink/renderer/platform/heap/heap_stats_collector.cc b/third_party/blink/renderer/platform/heap/heap_stats_collector.cc
index b55da843..297c2db 100644
--- a/third_party/blink/renderer/platform/heap/heap_stats_collector.cc
+++ b/third_party/blink/renderer/platform/heap/heap_stats_collector.cc
@@ -13,6 +13,16 @@
   current_.marked_object_size += size;
 }
 
+void ThreadHeapStatsCollector::IncreaseCompactionFreedSize(size_t size) {
+  DCHECK(is_started_);
+  current_.compaction_freed_bytes += size;
+}
+
+void ThreadHeapStatsCollector::IncreaseCompactionFreedPages(size_t pages) {
+  DCHECK(is_started_);
+  current_.compaction_freed_pages += pages;
+}
+
 void ThreadHeapStatsCollector::Start(BlinkGC::GCReason reason) {
   DCHECK(!is_started_);
   is_started_ = true;
@@ -27,6 +37,8 @@
 
 void ThreadHeapStatsCollector::Event::reset() {
   marked_object_size = 0;
+  compaction_freed_pages = 0;
+  compaction_freed_bytes = 0;
   memset(scope_data, 0, sizeof(scope_data));
   reason = BlinkGC::kTesting;
 }
diff --git a/third_party/blink/renderer/platform/heap/heap_stats_collector.h b/third_party/blink/renderer/platform/heap/heap_stats_collector.h
index cfc392f3..1837280c 100644
--- a/third_party/blink/renderer/platform/heap/heap_stats_collector.h
+++ b/third_party/blink/renderer/platform/heap/heap_stats_collector.h
@@ -27,6 +27,9 @@
  public:
   // These ids will form human readable names when used in Scopes.
   enum Id {
+    kAtomicPhase,
+    kAtomicPhaseCompaction,
+    kAtomicPhaseMarking,
     kCompleteSweep,
     kEagerSweep,
     kIncrementalMarkingStartMarking,
@@ -36,9 +39,14 @@
     kInvokePreFinalizers,
     kLazySweepInIdle,
     kLazySweepOnAllocation,
-    kAtomicPhase,
-    kAtomicPhaseMarking,
+    kMarkInvokeEphemeronCallbacks,
+    kMarkProcessWorklist,
+    kMarkWeakProcessing,
+    kVisitCrossThreadPersistents,
     kVisitDOMWrappers,
+    kVisitPersistentRoots,
+    kVisitPersistents,
+    kVisitStackRoots,
     kNumScopeIds,
   };
 
@@ -46,6 +54,8 @@
     switch (id) {
       case Id::kAtomicPhase:
         return "BlinkGC.AtomicPhase";
+      case Id::kAtomicPhaseCompaction:
+        return "BlinkGC.AtomicPhaseCompaction";
       case Id::kAtomicPhaseMarking:
         return "BlinkGC.AtomicPhaseMarking";
       case Id::kCompleteSweep:
@@ -66,8 +76,22 @@
         return "BlinkGC.LazySweepInIdle";
       case Id::kLazySweepOnAllocation:
         return "BlinkGC.LazySweepOnAllocation";
+      case Id::kMarkInvokeEphemeronCallbacks:
+        return "BlinkGC.MarkInvokeEphemeronCallbacks";
+      case Id::kMarkProcessWorklist:
+        return "BlinkGC.MarkProcessWorklist";
+      case Id::kMarkWeakProcessing:
+        return "BlinkGC.MarkWeakProcessing";
+      case Id::kVisitCrossThreadPersistents:
+        return "BlinkGC.VisitCrossThreadPersistents";
       case Id::kVisitDOMWrappers:
         return "BlinkGC.VisitDOMWrappers";
+      case Id::kVisitPersistentRoots:
+        return "BlinkGC.VisitPersistentRoots";
+      case Id::kVisitPersistents:
+        return "BlinkGC.VisitPersistents";
+      case Id::kVisitStackRoots:
+        return "BlinkGC.VisitStackRoots";
       case Id::kNumScopeIds:
         break;
     }
@@ -84,16 +108,19 @@
   // the corresponding ThreadHeapStatsCollector.
   template <TraceDefaultBehavior default_behavior = kDisabled>
   class PLATFORM_EXPORT InternalScope {
+    DISALLOW_NEW();
+    DISALLOW_COPY_AND_ASSIGN(InternalScope);
+
    public:
     template <typename... Args>
-    InternalScope(ThreadHeapStatsCollector* tracer, Id id, Args... args)
+    inline InternalScope(ThreadHeapStatsCollector* tracer, Id id, Args... args)
         : tracer_(tracer),
           start_time_(WTF::CurrentTimeTicksInMilliseconds()),
           id_(id) {
       StartTrace(args...);
     }
 
-    ~InternalScope() {
+    inline ~InternalScope() {
       TRACE_EVENT_END0(TraceCategory(), ToString(id_));
       tracer_->IncreaseScopeTime(
           id_, WTF::CurrentTimeTicksInMilliseconds() - start_time_);
@@ -134,6 +161,8 @@
     double sweeping_time_in_ms() const;
 
     size_t marked_object_size = 0;
+    size_t compaction_freed_bytes = 0;
+    size_t compaction_freed_pages = 0;
     double scope_data[kNumScopeIds] = {0};
     BlinkGC::GCReason reason;
   };
@@ -147,6 +176,8 @@
   }
 
   void IncreaseMarkedObjectSize(size_t);
+  void IncreaseCompactionFreedSize(size_t);
+  void IncreaseCompactionFreedPages(size_t);
 
   bool is_started() const { return is_started_; }
   const Event& current() const { return current_; }
diff --git a/third_party/blink/renderer/platform/heap/thread_state.cc b/third_party/blink/renderer/platform/heap/thread_state.cc
index 5bf94ff7..771ad89 100644
--- a/third_party/blink/renderer/platform/heap/thread_state.cc
+++ b/third_party/blink/renderer/platform/heap/thread_state.cc
@@ -344,12 +344,19 @@
 
 void ThreadState::VisitPersistents(Visitor* visitor) {
   {
+    ThreadHeapStatsCollector::Scope stats_scope(
+        Heap().stats_collector(),
+        ThreadHeapStatsCollector::kVisitCrossThreadPersistents);
     // See ProcessHeap::CrossThreadPersistentMutex().
     RecursiveMutexLocker persistent_lock(
         ProcessHeap::CrossThreadPersistentMutex());
     ProcessHeap::GetCrossThreadPersistentRegion().TracePersistentNodes(visitor);
   }
-  persistent_region_->TracePersistentNodes(visitor);
+  {
+    ThreadHeapStatsCollector::Scope stats_scope(
+        Heap().stats_collector(), ThreadHeapStatsCollector::kVisitPersistents);
+    persistent_region_->TracePersistentNodes(visitor);
+  }
   if (trace_dom_wrappers_) {
     ThreadHeapStatsCollector::Scope stats_scope(
         Heap().stats_collector(), ThreadHeapStatsCollector::kVisitDOMWrappers);
@@ -1013,6 +1020,22 @@
       ("BlinkGC.TimeForInvokingPreFinalizers", 1, 10 * 1000, 50));
   pre_finalizers_histogram.Count(
       event.scope_data[ThreadHeapStatsCollector::kInvokePreFinalizers]);
+
+  DEFINE_STATIC_LOCAL(CustomCountHistogram, time_for_heap_compaction_histogram,
+                      ("BlinkGC.TimeForHeapCompaction", 1, 10 * 1000, 50));
+  time_for_heap_compaction_histogram.Count(
+      event.scope_data[ThreadHeapStatsCollector::kAtomicPhaseCompaction]);
+
+  DEFINE_STATIC_LOCAL(
+      CustomCountHistogram, object_size_freed_by_heap_compaction,
+      ("BlinkGC.ObjectSizeFreedByHeapCompaction", 1, 4 * 1024 * 1024, 50));
+  object_size_freed_by_heap_compaction.Count(event.compaction_freed_bytes /
+                                             1024);
+  DEFINE_THREAD_SAFE_STATIC_LOCAL(
+      CustomCountHistogram, weak_processing_time_histogram,
+      ("BlinkGC.TimeForGlobalWeakProcessing", 1, 10 * 1000, 50));
+  weak_processing_time_histogram.Count(
+      event.scope_data[ThreadHeapStatsCollector::kMarkWeakProcessing]);
 }
 
 }  // namespace
diff --git a/third_party/blink/renderer/platform/loader/cors/cors_error_string.cc b/third_party/blink/renderer/platform/loader/cors/cors_error_string.cc
index 03a485a..29ddc6a 100644
--- a/third_party/blink/renderer/platform/loader/cors/cors_error_string.cc
+++ b/third_party/blink/renderer/platform/loader/cors/cors_error_string.cc
@@ -29,7 +29,7 @@
 ErrorParameter CreateWrongParameter(network::mojom::CORSError error) {
   return ErrorParameter(
       error, GetInvalidURL(), GetInvalidURL(), 0 /* status_code */,
-      HTTPHeaderMap(), *SecurityOrigin::CreateUnique(),
+      HTTPHeaderMap(), *SecurityOrigin::CreateUniqueOpaque(),
       WebURLRequest::kRequestContextUnspecified, String(), true);
 }
 
@@ -63,7 +63,7 @@
     const KURL& request_url) {
   return ErrorParameter(network::mojom::CORSError::kDisallowedByMode,
                         request_url, GetInvalidURL(), 0 /* status_code */,
-                        HTTPHeaderMap(), *SecurityOrigin::CreateUnique(),
+                        HTTPHeaderMap(), *SecurityOrigin::CreateUniqueOpaque(),
                         WebURLRequest::kRequestContextUnspecified, String(),
                         false);
 }
@@ -115,17 +115,18 @@
     int response_status_code) {
   return ErrorParameter(network::mojom::CORSError::kPreflightInvalidStatus,
                         GetInvalidURL(), GetInvalidURL(), response_status_code,
-                        HTTPHeaderMap(), *SecurityOrigin::CreateUnique(),
+                        HTTPHeaderMap(), *SecurityOrigin::CreateUniqueOpaque(),
                         WebURLRequest::kRequestContextUnspecified, String(),
                         false);
 }
 
 // static
 ErrorParameter ErrorParameter::CreateForDisallowedRedirect() {
-  return ErrorParameter(
-      network::mojom::CORSError::kPreflightDisallowedRedirect, GetInvalidURL(),
-      GetInvalidURL(), 0, HTTPHeaderMap(), *SecurityOrigin::CreateUnique(),
-      WebURLRequest::kRequestContextUnspecified, String(), false);
+  return ErrorParameter(network::mojom::CORSError::kPreflightDisallowedRedirect,
+                        GetInvalidURL(), GetInvalidURL(), 0, HTTPHeaderMap(),
+                        *SecurityOrigin::CreateUniqueOpaque(),
+                        WebURLRequest::kRequestContextUnspecified, String(),
+                        false);
 }
 
 // static
@@ -137,7 +138,7 @@
     case network::mojom::CORSError::kPreflightInvalidAllowExternal:
       return ErrorParameter(
           error, GetInvalidURL(), GetInvalidURL(), 0 /* status_code */,
-          response_header_map, *SecurityOrigin::CreateUnique(),
+          response_header_map, *SecurityOrigin::CreateUniqueOpaque(),
           WebURLRequest::kRequestContextUnspecified, String(), false);
     default:
       NOTREACHED();
@@ -156,7 +157,7 @@
     case network::mojom::CORSError::kHeaderDisallowedByPreflightResponse:
       return ErrorParameter(
           error, GetInvalidURL(), GetInvalidURL(), 0 /* status_code */,
-          HTTPHeaderMap(), *SecurityOrigin::CreateUnique(),
+          HTTPHeaderMap(), *SecurityOrigin::CreateUniqueOpaque(),
           WebURLRequest::kRequestContextUnspecified, hint, false);
     default:
       NOTREACHED();
@@ -174,7 +175,7 @@
     case network::mojom::CORSError::kRedirectContainsCredentials:
       return ErrorParameter(
           error, request_url, redirect_url, 0 /* status_code */,
-          HTTPHeaderMap(), *SecurityOrigin::CreateUnique(),
+          HTTPHeaderMap(), *SecurityOrigin::CreateUniqueOpaque(),
           WebURLRequest::kRequestContextUnspecified, String(), false);
     default:
       NOTREACHED();
diff --git a/third_party/blink/renderer/platform/loader/fetch/memory_cache_correctness_test.cc b/third_party/blink/renderer/platform/loader/fetch/memory_cache_correctness_test.cc
index 75a0e6c1..56f751b6 100644
--- a/third_party/blink/renderer/platform/loader/fetch/memory_cache_correctness_test.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/memory_cache_correctness_test.cc
@@ -108,7 +108,7 @@
 
     MockFetchContext* context =
         MockFetchContext::Create(MockFetchContext::kShouldNotLoadNewResource);
-    security_origin_ = SecurityOrigin::CreateUnique();
+    security_origin_ = SecurityOrigin::CreateUniqueOpaque();
     context->SetSecurityOrigin(security_origin_);
 
     fetcher_ = ResourceFetcher::Create(context);
diff --git a/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc b/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc
index 9d75c8f..906e8cb 100644
--- a/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc
@@ -66,7 +66,7 @@
   jpeg_request.SetHTTPAccept("image/jpeg");
 
   scoped_refptr<const SecurityOrigin> source_origin =
-      SecurityOrigin::CreateUnique();
+      SecurityOrigin::CreateUniqueOpaque();
 
   RawResource* jpeg_resource(
       RawResource::CreateForTest(jpeg_request, Resource::kRaw));
@@ -217,7 +217,7 @@
 TEST_F(RawResourceTest,
        CanReuseDevToolsEmulateNetworkConditionsClientIdHeader) {
   scoped_refptr<const SecurityOrigin> source_origin =
-      SecurityOrigin::CreateUnique();
+      SecurityOrigin::CreateUniqueOpaque();
   ResourceRequest request("data:text/html,");
   request.SetHTTPHeaderField(
       HTTPNames::X_DevTools_Emulate_Network_Conditions_Client_Id, "Foo");
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
index d5874be..879df2d 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -177,6 +177,9 @@
   mojom::FetchImportanceMode importance_mode =
       resource_request.GetFetchImportanceMode();
 
+  DCHECK(importance_mode == mojom::FetchImportanceMode::kImportanceAuto ||
+         RuntimeEnabledFeatures::PriorityHintsEnabled());
+
   ResourceLoadPriority new_priority = priority_so_far;
 
   switch (importance_mode) {
@@ -274,10 +277,8 @@
     priority = ResourceLoadPriority::kVeryLow;
   }
 
-  if (RuntimeEnabledFeatures::PriorityHintsEnabled()) {
-    priority = AdjustPriorityWithPriorityHint(priority, type, resource_request,
-                                              defer_option, is_link_preload);
-  }
+  priority = AdjustPriorityWithPriorityHint(priority, type, resource_request,
+                                            defer_option, is_link_preload);
 
   // A manually set priority acts as a floor. This is used to ensure that
   // synchronous requests are always given the highest possible priority, as
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
index c39486b7e..810010b9 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
@@ -155,7 +155,7 @@
 TEST_F(ResourceFetcherTest, WillSendRequestAdBit) {
   // Add a resource to the memory cache.
   scoped_refptr<const SecurityOrigin> source_origin =
-      SecurityOrigin::CreateUnique();
+      SecurityOrigin::CreateUniqueOpaque();
   Context()->SetSecurityOrigin(source_origin);
   KURL url("http://127.0.0.1:8000/foo.html");
   Resource* resource = RawResource::CreateForTest(url, Resource::kRaw);
@@ -185,7 +185,7 @@
 
 TEST_F(ResourceFetcherTest, Vary) {
   scoped_refptr<const SecurityOrigin> source_origin =
-      SecurityOrigin::CreateUnique();
+      SecurityOrigin::CreateUniqueOpaque();
   Context()->SetSecurityOrigin(source_origin);
 
   KURL url("http://127.0.0.1:8000/foo.html");
@@ -249,7 +249,7 @@
 
 TEST_F(ResourceFetcherTest, VaryOnBack) {
   scoped_refptr<const SecurityOrigin> source_origin =
-      SecurityOrigin::CreateUnique();
+      SecurityOrigin::CreateUniqueOpaque();
   Context()->SetSecurityOrigin(source_origin);
 
   ResourceFetcher* fetcher = ResourceFetcher::Create(Context());
@@ -338,7 +338,7 @@
 
 TEST_F(ResourceFetcherTest, RevalidateWhileFinishingLoading) {
   scoped_refptr<const SecurityOrigin> source_origin =
-      SecurityOrigin::CreateUnique();
+      SecurityOrigin::CreateUniqueOpaque();
   Context()->SetSecurityOrigin(source_origin);
 
   KURL url("http://127.0.0.1:8000/foo.png");
@@ -754,7 +754,7 @@
 
 TEST_F(ResourceFetcherTest, Revalidate304) {
   scoped_refptr<const SecurityOrigin> source_origin =
-      SecurityOrigin::CreateUnique();
+      SecurityOrigin::CreateUniqueOpaque();
   Context()->SetSecurityOrigin(source_origin);
 
   KURL url("http://127.0.0.1:8000/foo.html");
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
index 6c83b189..8cc736b 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
@@ -113,11 +113,13 @@
   // Synchronous requests should not work with a throttling. Also, disables
   // throttling for the case that can be used for aka long-polling requests.
   // Allow top level frame main resource loads in paused frames as well.
+  // We also disable throttling for non-http[s] requests.
   if (resource_->Options().synchronous_policy == kRequestSynchronously ||
       !IsThrottlableRequestContext(request.GetRequestContext()) ||
       (request.GetFrameType() ==
            network::mojom::RequestContextFrameType::kTopLevel &&
-       resource_->GetType() == Resource::kMainResource)) {
+       resource_->GetType() == Resource::kMainResource) ||
+      !request.Url().ProtocolIsInHTTPFamily()) {
     throttle_option = ResourceLoadScheduler::ThrottleOption::kCanNotBeThrottled;
   }
 
diff --git a/third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h b/third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h
index b22a12d..84937eb9 100644
--- a/third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h
+++ b/third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h
@@ -147,7 +147,7 @@
         runner_(loading_task_runner
                     ? std::move(loading_task_runner)
                     : base::MakeRefCounted<scheduler::FakeTaskRunner>()),
-        security_origin_(SecurityOrigin::CreateUnique()),
+        security_origin_(SecurityOrigin::CreateUniqueOpaque()),
         frame_scheduler_(new MockFrameScheduler(runner_)),
         complete_(false),
         transfer_size_(-1) {}
diff --git a/third_party/blink/renderer/platform/mojo/kurl_security_origin_test.cc b/third_party/blink/renderer/platform/mojo/kurl_security_origin_test.cc
index 926078de..db429023 100644
--- a/third_party/blink/renderer/platform/mojo/kurl_security_origin_test.cc
+++ b/third_party/blink/renderer/platform/mojo/kurl_security_origin_test.cc
@@ -81,7 +81,8 @@
   EXPECT_TRUE(non_unique->IsSameSchemeHostPort(output.get()));
   EXPECT_FALSE(output->IsOpaque());
 
-  scoped_refptr<const SecurityOrigin> unique = SecurityOrigin::CreateUnique();
+  scoped_refptr<const SecurityOrigin> unique =
+      SecurityOrigin::CreateUniqueOpaque();
   EXPECT_TRUE(proxy->BounceOrigin(unique, &output));
   EXPECT_TRUE(output->IsOpaque());
 }
diff --git a/third_party/blink/renderer/platform/mojo/security_origin_struct_traits.h b/third_party/blink/renderer/platform/mojo/security_origin_struct_traits.h
index d674695..3785ab7 100644
--- a/third_party/blink/renderer/platform/mojo/security_origin_struct_traits.h
+++ b/third_party/blink/renderer/platform/mojo/security_origin_struct_traits.h
@@ -33,7 +33,7 @@
   static bool Read(url::mojom::blink::Origin::DataView data,
                    scoped_refptr<const ::blink::SecurityOrigin>* out) {
     if (data.unique()) {
-      *out = ::blink::SecurityOrigin::CreateUnique();
+      *out = ::blink::SecurityOrigin::CreateUniqueOpaque();
     } else {
       WTF::String scheme;
       WTF::String host;
diff --git a/third_party/blink/renderer/platform/plugins/plugin_data.cc b/third_party/blink/renderer/platform/plugins/plugin_data.cc
index 73d10a1..a06a41f 100644
--- a/third_party/blink/renderer/platform/plugins/plugin_data.cc
+++ b/third_party/blink/renderer/platform/plugins/plugin_data.cc
@@ -83,8 +83,8 @@
 // static
 void PluginData::RefreshBrowserSidePluginCache() {
   PluginListBuilder builder(nullptr);
-  Platform::Current()->GetPluginList(true, WebSecurityOrigin::CreateUnique(),
-                                     &builder);
+  Platform::Current()->GetPluginList(
+      true, WebSecurityOrigin::CreateUniqueOpaque(), &builder);
 }
 
 void PluginData::UpdatePluginList(const SecurityOrigin* main_frame_origin) {
diff --git a/third_party/blink/renderer/platform/scheduler/base/enqueue_order.h b/third_party/blink/renderer/platform/scheduler/base/enqueue_order.h
index 933455a..e2a686c 100644
--- a/third_party/blink/renderer/platform/scheduler/base/enqueue_order.h
+++ b/third_party/blink/renderer/platform/scheduler/base/enqueue_order.h
@@ -41,7 +41,7 @@
   }
 
  private:
-  std::atomic_uint64_t enqueue_order_;
+  std::atomic<EnqueueOrder> enqueue_order_;
 };
 
 }  // namespace internal
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
index d456a38d0..ad1766a 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
@@ -311,14 +311,15 @@
     // Media events should not be deferred to ensure that media playback is
     // smooth.
     case TaskType::kMediaElementEvent:
+    case TaskType::kInternalTest:
+    case TaskType::kInternalWebCrypto:
     case TaskType::kInternalIndexedDB:
     case TaskType::kInternalMedia:
     case TaskType::kInternalMediaRealTime:
     case TaskType::kInternalUserInteraction:
+    case TaskType::kInternalIntersectionObserver:
     case TaskType::kUnthrottled:
       return TaskQueueWithTaskType::Create(PausableTaskQueue(), type);
-    case TaskType::kInternalTest:
-    case TaskType::kInternalWebCrypto:
     case TaskType::kInternalIPC:
     // The TaskType of Inspector tasks needs to be unpausable because they need
     // to run even on a paused page.
@@ -327,7 +328,6 @@
     // unthrottled and undeferred) not to prevent service workers that may
     // control browser navigation on multiple tabs.
     case TaskType::kInternalWorker:
-    case TaskType::kInternalIntersectionObserver:
       return TaskQueueWithTaskType::Create(UnpausableTaskQueue(), type);
     case TaskType::kDeprecatedNone:
     case TaskType::kMainThreadTaskQueueV8:
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
index 754958c..1bba0e28 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl_unittest.cc
@@ -15,9 +15,9 @@
 #include "base/test/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/simple_test_tick_clock.h"
+#include "base/test/test_mock_time_task_runner.h"
 #include "build/build_config.h"
 #include "components/viz/common/frame_sinks/begin_frame_args.h"
-#include "components/viz/test/ordered_simple_task_runner.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/common/page/launching_process_state.h"
@@ -99,7 +99,7 @@
 void RepostingUpdateClockIdleTestTask(
     SingleThreadIdleTaskRunner* idle_task_runner,
     int* run_count,
-    base::SimpleTestTickClock* clock,
+    scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner,
     base::TimeDelta advance_time,
     std::vector<base::TimeTicks>* deadlines,
     base::TimeTicks deadline) {
@@ -107,16 +107,16 @@
     idle_task_runner->PostIdleTask(
         FROM_HERE, base::BindOnce(&RepostingUpdateClockIdleTestTask,
                                   base::Unretained(idle_task_runner), run_count,
-                                  clock, advance_time, deadlines));
+                                  test_task_runner, advance_time, deadlines));
   }
   deadlines->push_back(deadline);
   (*run_count)++;
-  clock->Advance(advance_time);
+  test_task_runner->AdvanceMockTickClock(advance_time);
 }
 
 void WillBeginFrameIdleTask(WebThreadScheduler* scheduler,
                             uint64_t sequence_number,
-                            base::SimpleTestTickClock* clock,
+                            const base::TickClock* clock,
                             base::TimeTicks deadline) {
   scheduler->WillBeginFrame(viz::BeginFrameArgs::Create(
       BEGINFRAME_FROM_HERE, 0, sequence_number, clock->NowTicks(),
@@ -124,10 +124,12 @@
       viz::BeginFrameArgs::NORMAL));
 }
 
-void UpdateClockToDeadlineIdleTestTask(base::SimpleTestTickClock* clock,
-                                       int* run_count,
-                                       base::TimeTicks deadline) {
-  clock->Advance(deadline - clock->NowTicks());
+void UpdateClockToDeadlineIdleTestTask(
+    scoped_refptr<base::TestMockTimeTaskRunner> task_runner,
+    int* run_count,
+    base::TimeTicks deadline) {
+  task_runner->AdvanceMockTickClock(
+      deadline - task_runner->GetMockTickClock()->NowTicks());
   (*run_count)++;
 }
 
@@ -190,26 +192,6 @@
   *is_anticipated_after = scheduler->IsHighPriorityWorkAnticipated();
 }
 
-// RAII helper class to enable auto advancing of time inside mock task runner.
-// Automatically disables auto-advancement when destroyed.
-class ScopedAutoAdvanceNowEnabler {
- public:
-  ScopedAutoAdvanceNowEnabler(
-      scoped_refptr<cc::OrderedSimpleTaskRunner> task_runner)
-      : task_runner_(task_runner) {
-    task_runner_->SetAutoAdvanceNowToPendingTasks(true);
-  }
-
-  ~ScopedAutoAdvanceNowEnabler() {
-    task_runner_->SetAutoAdvanceNowToPendingTasks(false);
-  }
-
- private:
-  scoped_refptr<cc::OrderedSimpleTaskRunner> task_runner_;
-
-  DISALLOW_COPY_AND_ASSIGN(ScopedAutoAdvanceNowEnabler);
-};
-
 class MainThreadSchedulerImplForTest : public MainThreadSchedulerImpl {
  public:
   using MainThreadSchedulerImpl::CompositorTaskQueue;
@@ -281,31 +263,26 @@
       : fake_task_(TaskQueue::PostedTask(base::BindOnce([] {}), FROM_HERE),
                    base::TimeTicks()) {
     feature_list_.InitAndEnableFeature(kHighPriorityInput);
-    clock_.Advance(base::TimeDelta::FromMicroseconds(5000));
-  }
-
-  MainThreadSchedulerImplTest(base::MessageLoop* message_loop)
-      : fake_task_(TaskQueue::PostedTask(base::BindOnce([] {}), FROM_HERE),
-                   base::TimeTicks()),
-        message_loop_(message_loop) {
-    clock_.Advance(base::TimeDelta::FromMicroseconds(5000));
   }
 
   ~MainThreadSchedulerImplTest() override = default;
 
   void SetUp() override {
-    if (!message_loop_) {
-      mock_task_runner_ =
-          base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(&clock_, false);
-    }
+    CreateTestTaskRunner();
     Initialize(std::make_unique<MainThreadSchedulerImplForTest>(
         base::sequence_manager::TaskQueueManagerForTest::Create(
-            message_loop_.get(),
-            message_loop_ ? message_loop_->task_runner() : mock_task_runner_,
-            &clock_),
+            nullptr, test_task_runner_, test_task_runner_->GetMockTickClock()),
         base::nullopt));
   }
 
+  void CreateTestTaskRunner() {
+    test_task_runner_ = base::WrapRefCounted(new base::TestMockTimeTaskRunner(
+        base::TestMockTimeTaskRunner::Type::kBoundToThread));
+    // A null clock triggers some assertions.
+    test_task_runner_->AdvanceMockTickClock(
+        base::TimeDelta::FromMilliseconds(5));
+  }
+
   void Initialize(std::unique_ptr<MainThreadSchedulerImplForTest> scheduler) {
     scheduler_ = std::move(scheduler);
 
@@ -334,34 +311,27 @@
   }
 
   void TearDown() override {
-    DCHECK(!mock_task_runner_.get() || !message_loop_.get());
     main_frame_scheduler_.reset();
     page_scheduler_.reset();
     scheduler_->Shutdown();
-    if (mock_task_runner_.get()) {
-      // Check that all tests stop posting tasks.
-      mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
-      while (mock_task_runner_->RunUntilIdle()) {
-      }
-    } else {
-      base::RunLoop().RunUntilIdle();
-    }
+    base::RunLoop().RunUntilIdle();
     scheduler_.reset();
   }
 
-  void RunUntilIdle() {
-    // Only one of mock_task_runner_ or message_loop_ should be set.
-    DCHECK(!mock_task_runner_.get() || !message_loop_.get());
-    if (mock_task_runner_.get()) {
-      mock_task_runner_->RunUntilIdle();
-    } else {
-      base::RunLoop().RunUntilIdle();
-    }
+  virtual base::TimeTicks Now() {
+    CHECK(test_task_runner_);
+    return test_task_runner_->GetMockTickClock()->NowTicks();
+  }
+
+  void AdvanceMockTickClockTo(base::TimeTicks time) {
+    CHECK(test_task_runner_);
+    CHECK_LE(Now(), time);
+    test_task_runner_->AdvanceMockTickClock(time - Now());
   }
 
   void DoMainFrame() {
     viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
+        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
         base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
         viz::BeginFrameArgs::NORMAL);
     begin_frame_args.on_critical_path = false;
@@ -371,7 +341,7 @@
 
   void DoMainFrameOnCriticalPath() {
     viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
+        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
         base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
         viz::BeginFrameArgs::NORMAL);
     begin_frame_args.on_critical_path = true;
@@ -385,25 +355,22 @@
     scheduler_->DidHandleInputEventOnCompositorThread(
         FakeInputEvent(blink::WebInputEvent::kGestureScrollEnd),
         InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
-    clock_.Advance(priority_escalation_after_input_duration() * 2);
+    test_task_runner_->AdvanceMockTickClock(
+        priority_escalation_after_input_duration() * 2);
     scheduler_->ForceUpdatePolicy();
   }
 
   void SimulateExpensiveTasks(
       const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
-    // RunUntilIdle won't actually run all of the SimpleTestTickClock::Advance
-    // tasks unless we set AutoAdvanceNow to true :/
-    ScopedAutoAdvanceNowEnabler enable_auto_advance_now(mock_task_runner_);
-
-    // Simulate a bunch of expensive tasks
+    // Simulate a bunch of expensive tasks.
     for (int i = 0; i < 10; i++) {
       task_runner->PostTask(
-          FROM_HERE, base::BindOnce(&base::SimpleTestTickClock::Advance,
-                                    base::Unretained(&clock_),
-                                    base::TimeDelta::FromMilliseconds(500)));
+          FROM_HERE,
+          base::BindOnce(&base::TestMockTimeTaskRunner::AdvanceMockTickClock,
+                         test_task_runner_,
+                         base::TimeDelta::FromMilliseconds(500)));
     }
-
-    RunUntilIdle();
+    test_task_runner_->FastForwardUntilNoTasksRemain();
   }
 
   enum class TouchEventPolicy {
@@ -535,7 +502,7 @@
     scheduler_->DidHandleInputEventOnCompositorThread(
         FakeInputEvent(blink::WebInputEvent::kTouchMove),
         InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
-    clock_.Advance(begin_main_frame_duration);
+    test_task_runner_->AdvanceMockTickClock(begin_main_frame_duration);
     scheduler_->DidHandleInputEventOnMainThread(
         FakeInputEvent(blink::WebInputEvent::kTouchMove),
         WebInputEventResult::kHandledApplication);
@@ -544,17 +511,18 @@
 
   void SimulateMainThreadCompositorTask(
       base::TimeDelta begin_main_frame_duration) {
-    clock_.Advance(begin_main_frame_duration);
+    test_task_runner_->AdvanceMockTickClock(begin_main_frame_duration);
     scheduler_->DidCommitFrameToCompositor();
-    simulate_compositor_task_ran_ = true;
   }
 
-  bool SimulatedCompositorTaskPending() const {
-    return !simulate_compositor_task_ran_;
+  void SimulateMainThreadCompositorAndQuitRunLoopTask(
+      base::TimeDelta begin_main_frame_duration) {
+    SimulateMainThreadCompositorTask(begin_main_frame_duration);
+    base::RunLoop().Quit();
   }
 
   void SimulateTimerTask(base::TimeDelta duration) {
-    clock_.Advance(duration);
+    test_task_runner_->AdvanceMockTickClock(duration);
     simulate_timer_task_ran_ = true;
   }
 
@@ -602,10 +570,11 @@
         scheduler_->NewLoadingTaskQueue(
             MainThreadTaskQueue::QueueType::kFrameLoading, nullptr);
 
-    base::TimeTicks start = clock_.NowTicks();
+    base::TimeTicks start = Now();
     scheduler_->OnTaskStarted(fake_queue.get(), fake_task_, start);
-    clock_.Advance(base::TimeDelta::FromSecondsD(duration));
-    base::TimeTicks end = clock_.NowTicks();
+    test_task_runner_->AdvanceMockTickClock(
+        base::TimeDelta::FromSecondsD(duration));
+    base::TimeTicks end = Now();
     scheduler_->OnTaskCompleted(fake_queue.get(), fake_task_, start, end,
                                 base::nullopt);
   }
@@ -618,7 +587,7 @@
         base::BindOnce(
             &MainThreadSchedulerImplTest::SimulateMainThreadCompositorTask,
             base::Unretained(this), base::TimeDelta::FromMilliseconds(1000)));
-    RunUntilIdle();
+    base::RunLoop().RunUntilIdle();
   }
 
   // Helper for posting several tasks of specific types. |task_descriptor| is a
@@ -737,11 +706,9 @@
   }
 
   base::test::ScopedFeatureList feature_list_;
-  base::SimpleTestTickClock clock_;
   TaskQueue::Task fake_task_;
-  // Only one of mock_task_runner_ or message_loop_ will be set.
-  scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
-  std::unique_ptr<base::MessageLoop> message_loop_;
+
+  scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner_;
 
   std::unique_ptr<MainThreadSchedulerImplForTest> scheduler_;
   std::unique_ptr<PageSchedulerImpl> page_scheduler_;
@@ -756,7 +723,6 @@
   scoped_refptr<TaskQueue> timer_task_runner_;
   scoped_refptr<base::SingleThreadTaskRunner> v8_task_runner_;
   bool simulate_timer_task_ran_;
-  bool simulate_compositor_task_ran_;
   uint64_t next_begin_frame_number_ = viz::BeginFrameArgs::kStartingFrameNumber;
 
   DISALLOW_COPY_AND_ASSIGN(MainThreadSchedulerImplTest);
@@ -766,7 +732,7 @@
   std::vector<std::string> run_order;
   PostTestTasks(&run_order, "D1 D2 D3 D4");
 
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("D1"), std::string("D2"),
                                    std::string("D3"), std::string("D4")));
@@ -775,7 +741,7 @@
 TEST_F(MainThreadSchedulerImplTest, TestPostDefaultAndCompositor) {
   std::vector<std::string> run_order;
   PostTestTasks(&run_order, "D1 C1 P1");
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order, testing::Contains("D1"));
   EXPECT_THAT(run_order, testing::Contains("C1"));
   EXPECT_THAT(run_order, testing::Contains("P1"));
@@ -788,7 +754,7 @@
       FROM_HERE, base::BindOnce(AppendToVectorReentrantTask,
                                 base::RetainedRef(default_task_runner_),
                                 &run_order, &count, 5));
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   EXPECT_THAT(run_order, testing::ElementsAre(0, 1, 2, 3, 4));
 }
@@ -796,35 +762,38 @@
 TEST_F(MainThreadSchedulerImplTest, TestPostIdleTask) {
   int run_count = 0;
   base::TimeTicks expected_deadline =
-      clock_.NowTicks() + base::TimeDelta::FromMilliseconds(2300);
+      Now() + base::TimeDelta::FromMilliseconds(2300);
   base::TimeTicks deadline_in_task;
 
-  clock_.Advance(base::TimeDelta::FromMilliseconds(100));
+  test_task_runner_->AdvanceMockTickClock(
+      base::TimeDelta::FromMilliseconds(100));
   idle_task_runner_->PostIdleTask(
       FROM_HERE, base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task));
 
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_EQ(0, run_count);  // Shouldn't run yet as no WillBeginFrame.
 
   scheduler_->WillBeginFrame(viz::BeginFrameArgs::Create(
-      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
+      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
       base::TimeTicks(), base::TimeDelta::FromMilliseconds(1000),
       viz::BeginFrameArgs::NORMAL));
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_EQ(0, run_count);  // Shouldn't run as no DidCommitFrameToCompositor.
 
-  clock_.Advance(base::TimeDelta::FromMilliseconds(1200));
+  test_task_runner_->AdvanceMockTickClock(
+      base::TimeDelta::FromMilliseconds(1200));
   scheduler_->DidCommitFrameToCompositor();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_EQ(0, run_count);  // We missed the deadline.
 
   scheduler_->WillBeginFrame(viz::BeginFrameArgs::Create(
-      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
+      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
       base::TimeTicks(), base::TimeDelta::FromMilliseconds(1000),
       viz::BeginFrameArgs::NORMAL));
-  clock_.Advance(base::TimeDelta::FromMilliseconds(800));
+  test_task_runner_->AdvanceMockTickClock(
+      base::TimeDelta::FromMilliseconds(800));
   scheduler_->DidCommitFrameToCompositor();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1, run_count);
   EXPECT_EQ(expected_deadline, deadline_in_task);
 }
@@ -838,37 +807,36 @@
       base::BindOnce(&RepostingIdleTestTask,
                      base::RetainedRef(idle_task_runner_), &run_count));
   EnableIdleTasks();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1, run_count);
 
   // Reposted tasks shouldn't run until next idle period.
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1, run_count);
 
   EnableIdleTasks();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_EQ(2, run_count);
 }
 
 TEST_F(MainThreadSchedulerImplTest, TestIdleTaskExceedsDeadline) {
-  ScopedAutoAdvanceNowEnabler enable_auto_advance_now(mock_task_runner_);
   int run_count = 0;
 
   // Post two UpdateClockToDeadlineIdleTestTask tasks.
   idle_task_runner_->PostIdleTask(
-      FROM_HERE,
-      base::BindOnce(&UpdateClockToDeadlineIdleTestTask, &clock_, &run_count));
+      FROM_HERE, base::BindOnce(&UpdateClockToDeadlineIdleTestTask,
+                                test_task_runner_, &run_count));
   idle_task_runner_->PostIdleTask(
-      FROM_HERE,
-      base::BindOnce(&UpdateClockToDeadlineIdleTestTask, &clock_, &run_count));
+      FROM_HERE, base::BindOnce(&UpdateClockToDeadlineIdleTestTask,
+                                test_task_runner_, &run_count));
 
   EnableIdleTasks();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // Only the first idle task should execute since it's used up the deadline.
   EXPECT_EQ(1, run_count);
 
   EnableIdleTasks();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // Second task should be run on the next idle period.
   EXPECT_EQ(2, run_count);
 }
@@ -882,33 +850,33 @@
 
   // Trigger the beginning of an idle period for 1000ms.
   scheduler_->WillBeginFrame(viz::BeginFrameArgs::Create(
-      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
+      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
       base::TimeTicks(), base::TimeDelta::FromMilliseconds(1000),
       viz::BeginFrameArgs::NORMAL));
   DoMainFrame();
 
   // End the idle period early (after 500ms), and send a WillBeginFrame which
   // specifies that the next idle period should end 1000ms from now.
-  clock_.Advance(base::TimeDelta::FromMilliseconds(500));
+  test_task_runner_->AdvanceMockTickClock(
+      base::TimeDelta::FromMilliseconds(500));
   scheduler_->WillBeginFrame(viz::BeginFrameArgs::Create(
-      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
+      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
       base::TimeTicks(), base::TimeDelta::FromMilliseconds(1000),
       viz::BeginFrameArgs::NORMAL));
 
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_EQ(0, run_count);  // Not currently in an idle period.
 
   // Trigger the start of the idle period before the task to end the previous
   // idle period has been triggered.
-  clock_.Advance(base::TimeDelta::FromMilliseconds(400));
+  test_task_runner_->AdvanceMockTickClock(
+      base::TimeDelta::FromMilliseconds(400));
   scheduler_->DidCommitFrameToCompositor();
 
   // Post a task which simulates running until after the previous end idle
   // period delayed task was scheduled for
   scheduler_->DefaultTaskQueue()->PostTask(FROM_HERE, base::BindOnce(NullTask));
-  clock_.Advance(base::TimeDelta::FromMilliseconds(300));
-
-  RunUntilIdle();
+  test_task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(300));
   EXPECT_EQ(1, run_count);  // We should still be in the new idle period.
 }
 
@@ -917,7 +885,7 @@
   PostTestTasks(&run_order, "L1 I1 D1 P1 C1 D2 P2 C2");
 
   EnableIdleTasks();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // High-priority input is enabled and input tasks are processed first.
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("P1"), std::string("P2"),
@@ -934,7 +902,7 @@
   PostTestTasks(&run_order, "L1 I1 D1 C1 P1 D2 C2");
 
   EnableIdleTasks();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // Even with slow compositor input tasks are handled first.
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("P1"), std::string("L1"),
@@ -952,7 +920,7 @@
   scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
   EnableIdleTasks();
   SimulateCompositorGestureStart(TouchEventPolicy::kSendTouchStart);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("L1"), std::string("D1"),
                                    std::string("D2"), std::string("C1"),
@@ -968,7 +936,7 @@
   scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
   EnableIdleTasks();
   SimulateMainThreadGestureWithoutScrollUpdates();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("C1"), std::string("C2"),
                                    std::string("L1"), std::string("D1"),
@@ -984,7 +952,7 @@
   scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
   EnableIdleTasks();
   SimulateMainThreadGestureWithoutPreventDefault();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("L1"), std::string("D1"),
                                    std::string("D2"), std::string("C1"),
@@ -999,25 +967,26 @@
   SimulateCompositorGestureStart(TouchEventPolicy::kSendTouchStart);
 
   base::TimeTicks loop_end_time =
-      clock_.NowTicks() + base::TimeDelta::FromMilliseconds(
-                              UserModel::kMedianGestureDurationMillis * 2);
+      Now() + base::TimeDelta::FromMilliseconds(
+                  UserModel::kMedianGestureDurationMillis * 2);
 
   // The UseCase::kCompositorGesture usecase initially deprioritizes
   // compositor tasks (see
   // TestCompositorPolicy_CompositorHandlesInput_WithTouchHandler) but if the
   // gesture is long enough, compositor tasks get prioritized again.
-  while (clock_.NowTicks() < loop_end_time) {
+  while (Now() < loop_end_time) {
     scheduler_->DidHandleInputEventOnCompositorThread(
         FakeInputEvent(blink::WebInputEvent::kTouchMove),
         InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
-    clock_.Advance(base::TimeDelta::FromMilliseconds(16));
-    RunUntilIdle();
+    test_task_runner_->AdvanceMockTickClock(
+        base::TimeDelta::FromMilliseconds(16));
+    base::RunLoop().RunUntilIdle();
   }
 
   std::vector<std::string> run_order;
   PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2");
 
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("C1"), std::string("C2"),
                                    std::string("L1"), std::string("D1"),
@@ -1032,7 +1001,7 @@
 
   EnableIdleTasks();
   SimulateCompositorGestureStart(TouchEventPolicy::kDontSendTouchStart);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("L1"), std::string("D1"),
                                    std::string("D2"), std::string("C1"),
@@ -1049,7 +1018,7 @@
   EnableIdleTasks();
   SimulateMainThreadGestureStart(TouchEventPolicy::kSendTouchStart,
                                  blink::WebInputEvent::kGestureScrollBegin);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("C1"), std::string("C2"),
                                    std::string("L1"), std::string("D1"),
@@ -1068,7 +1037,7 @@
   EnableIdleTasks();
   SimulateMainThreadGestureStart(TouchEventPolicy::kDontSendTouchStart,
                                  blink::WebInputEvent::kGestureScrollBegin);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("C1"), std::string("C2"),
                                    std::string("L1"), std::string("D1"),
@@ -1092,7 +1061,7 @@
   scheduler_->DidHandleInputEventOnMainThread(
       FakeInputEvent(blink::WebInputEvent::kTouchStart),
       WebInputEventResult::kHandledApplication);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // Because the main thread is performing custom input handling, we let all
   // tasks run. However compositing tasks are still given priority.
   EXPECT_THAT(run_order,
@@ -1116,7 +1085,7 @@
   scheduler_->DidHandleInputEventOnMainThread(
       FakeInputEvent(blink::WebInputEvent::kTouchStart),
       WebInputEventResult::kHandledSystem);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // Because we are still waiting for the touchstart to be processed,
   // non-essential tasks like loading tasks are blocked.
   EXPECT_THAT(run_order,
@@ -1137,7 +1106,7 @@
   EXPECT_EQ(UseCase::kCompositorGesture,
             ForceUpdatePolicyAndGetCurrentUseCase());
   EnableIdleTasks();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("D1"), std::string("D2"),
                                    std::string("C1"), std::string("C2"),
@@ -1159,7 +1128,7 @@
 
   PostTestTasks(&run_order, "C1 T1");
 
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("C1"), std::string("T1")));
@@ -1177,7 +1146,7 @@
 
   PostTestTasks(&run_order, "C1 T1");
 
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_FALSE(TouchStartExpectedSoon());
   EXPECT_EQ(UseCase::kMainThreadGesture, CurrentUseCase());
 
@@ -1196,7 +1165,7 @@
 
   PostTestTasks(&run_order, "C1 T1");
 
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_FALSE(TouchStartExpectedSoon());
   EXPECT_EQ(UseCase::kMainThreadCustomInputHandling, CurrentUseCase());
 
@@ -1216,7 +1185,7 @@
 
   PostTestTasks(&run_order, "C1 T1");
 
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_FALSE(TouchStartExpectedSoon());
   EXPECT_EQ(UseCase::kMainThreadCustomInputHandling, CurrentUseCase());
 
@@ -1234,7 +1203,7 @@
       FakeInputEvent(blink::WebInputEvent::kTouchStart),
       InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
   EnableIdleTasks();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("C1"), std::string("C2"),
                                    std::string("D1"), std::string("D2")));
@@ -1249,7 +1218,7 @@
   scheduler_->DidHandleInputEventOnCompositorThread(
       FakeInputEvent(blink::WebInputEvent::kGestureTapDown),
       InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order, testing::ElementsAre());
 
   // Action events like ScrollBegin will kick us back into compositor priority,
@@ -1258,7 +1227,7 @@
   scheduler_->DidHandleInputEventOnCompositorThread(
       FakeInputEvent(blink::WebInputEvent::kGestureScrollBegin),
       InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("L1"), std::string("T1"),
@@ -1278,7 +1247,7 @@
       FakeInputEvent(blink::WebInputEvent::kTouchStart),
       WebInputEventResult::kHandledSystem);
   EnableIdleTasks();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("C1"), std::string("C2"),
                                    std::string("D1"), std::string("D2")));
@@ -1297,7 +1266,7 @@
   scheduler_->DidHandleInputEventOnMainThread(
       FakeInputEvent(blink::WebInputEvent::kGestureTapDown),
       WebInputEventResult::kHandledSystem);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order, testing::ElementsAre());
 
   // Action events like ScrollBegin will kick us back into compositor priority,
@@ -1309,7 +1278,7 @@
   scheduler_->DidHandleInputEventOnMainThread(
       FakeInputEvent(blink::WebInputEvent::kGestureScrollBegin),
       WebInputEventResult::kHandledSystem);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("L1"), std::string("T1"),
@@ -1324,7 +1293,7 @@
 
   scheduler_->DidStartProvisionalLoad(true);
   EnableIdleTasks();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   // In loading policy, loading tasks are prioritized other others.
   std::string loading_policy_expected[] = {
@@ -1337,11 +1306,12 @@
   // Advance 15s and try again, the loading policy should have ended and the
   // task order should return to the NONE use case where loading tasks are no
   // longer prioritized.
-  clock_.Advance(base::TimeDelta::FromMilliseconds(150000));
+  test_task_runner_->AdvanceMockTickClock(
+      base::TimeDelta::FromMilliseconds(150000));
   run_order.clear();
   PostTestTasks(&run_order, "I1 D1 C1 T1 L1 D2 C2 T2 L2");
   EnableIdleTasks();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   std::string default_order_expected[] = {
       std::string("D1"), std::string("C1"), std::string("T1"),
@@ -1362,7 +1332,7 @@
   scheduler_->DidHandleInputEventOnCompositorThread(
       FakeInputEvent(blink::WebInputEvent::kMouseMove),
       InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // Note compositor tasks are not prioritized.
   EXPECT_EQ(UseCase::kNone, CurrentUseCase());
   EXPECT_THAT(run_order,
@@ -1382,7 +1352,7 @@
   scheduler_->DidHandleInputEventOnCompositorThread(
       FakeInputEvent(blink::WebInputEvent::kMouseMove),
       InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // Note compositor tasks are not prioritized.
   EXPECT_EQ(UseCase::kNone, CurrentUseCase());
   EXPECT_THAT(run_order,
@@ -1403,7 +1373,7 @@
       FakeInputEvent(blink::WebInputEvent::kMouseMove,
                      blink::WebInputEvent::kLeftButtonDown),
       InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // Note compositor tasks deprioritized.
   EXPECT_EQ(UseCase::kCompositorGesture, CurrentUseCase());
   EXPECT_THAT(run_order,
@@ -1422,7 +1392,7 @@
       FakeInputEvent(blink::WebInputEvent::kMouseMove,
                      blink::WebInputEvent::kLeftButtonDown),
       InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // Note compositor tasks are prioritized.
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("C1"), std::string("C2"),
@@ -1439,7 +1409,7 @@
   // Simulate a main thread driven mouse wheel scroll gesture.
   SimulateMainThreadGestureStart(TouchEventPolicy::kSendTouchStart,
                                  blink::WebInputEvent::kGestureScrollUpdate);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_FALSE(TouchStartExpectedSoon());
   EXPECT_EQ(UseCase::kMainThreadGesture, CurrentUseCase());
 
@@ -1457,7 +1427,7 @@
       FakeInputEvent(blink::WebInputEvent::kMouseMove,
                      blink::WebInputEvent::kLeftButtonDown),
       InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(UseCase::kMainThreadCustomInputHandling, CurrentUseCase());
 
@@ -1484,7 +1454,7 @@
       FakeInputEvent(blink::WebInputEvent::kMouseUp,
                      blink::WebInputEvent::kLeftButtonDown),
       InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(UseCase::kMainThreadCustomInputHandling, CurrentUseCase());
 
@@ -1504,7 +1474,7 @@
   scheduler_->DidHandleInputEventOnCompositorThread(
       FakeInputEvent(blink::WebInputEvent::kMouseWheel),
       InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // Note compositor tasks are not prioritized.
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("D1"), std::string("D2"),
@@ -1522,7 +1492,7 @@
   scheduler_->DidHandleInputEventOnCompositorThread(
       FakeInputEvent(blink::WebInputEvent::kMouseWheel),
       InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // Note compositor tasks are prioritized (since they are fast).
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("C1"), std::string("C2"),
@@ -1549,7 +1519,7 @@
   scheduler_->DidHandleInputEventOnCompositorThread(
       FakeInputEvent(blink::WebInputEvent::kGestureScrollUpdate),
       InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // Note compositor tasks are prioritized.
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("C1"), std::string("C2"),
@@ -1577,7 +1547,7 @@
   scheduler_->DidHandleInputEventOnCompositorThread(
       FakeInputEvent(blink::WebInputEvent::kGestureScrollUpdate),
       InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // Note compositor tasks are not prioritized.
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("D1"), std::string("D2"),
@@ -1597,7 +1567,7 @@
   scheduler_->DidHandleInputEventOnCompositorThread(
       FakeInputEvent(blink::WebInputEvent::kKeyDown),
       InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // Note compositor tasks are not prioritized.
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("D1"), std::string("C1"),
@@ -1617,7 +1587,7 @@
   scheduler_->DidHandleInputEventOnCompositorThread(
       FakeInputEvent(blink::WebInputEvent::kKeyDown),
       InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // Note compositor tasks are not prioritized.
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("D1"), std::string("C1"),
@@ -1647,7 +1617,7 @@
   scheduler_->DidHandleInputEventOnCompositorThread(
       FakeInputEvent(blink::WebInputEvent::kGestureFlingStart),
       InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // Ensure that the default D1 task gets to run at some point before the final
   // C2 compositor task.
   EXPECT_THAT(run_order,
@@ -1661,7 +1631,7 @@
   EXPECT_EQ(UseCase::kCompositorGesture,
             ForceUpdatePolicyAndGetCurrentUseCase());
 
-  clock_.Advance(base::TimeDelta::FromMilliseconds(1000));
+  test_task_runner_->AdvanceMockTickClock(base::TimeDelta::FromSeconds(1));
   EXPECT_EQ(UseCase::kNone, ForceUpdatePolicyAndGetCurrentUseCase());
 }
 
@@ -1672,7 +1642,7 @@
   EXPECT_EQ(UseCase::kMainThreadCustomInputHandling,
             ForceUpdatePolicyAndGetCurrentUseCase());
 
-  clock_.Advance(base::TimeDelta::FromMilliseconds(1000));
+  test_task_runner_->AdvanceMockTickClock(base::TimeDelta::FromSeconds(1));
   EXPECT_EQ(UseCase::kNone, ForceUpdatePolicyAndGetCurrentUseCase());
 }
 
@@ -1683,20 +1653,20 @@
   scheduler_->DidHandleInputEventOnCompositorThread(
       FakeInputEvent(blink::WebInputEvent::kTouchStart),
       InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("C1"), std::string("C2"),
                                    std::string("D1"), std::string("D2")));
 
   run_order.clear();
-  clock_.Advance(base::TimeDelta::FromMilliseconds(1000));
+  test_task_runner_->AdvanceMockTickClock(base::TimeDelta::FromSeconds(1));
 
   // Don't post any compositor tasks to simulate a very long running event
   // handler.
   PostTestTasks(&run_order, "D1 D2");
 
   // Touchstart policy mode should have ended now that the clock has advanced.
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("L1"), std::string("D1"),
                                    std::string("D2")));
@@ -1711,7 +1681,7 @@
   scheduler_->DidHandleInputEventOnCompositorThread(
       FakeInputEvent(blink::WebInputEvent::kTouchStart),
       InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("C1"), std::string("C2"),
                                    std::string("D1"), std::string("D2")));
@@ -1721,7 +1691,7 @@
   scheduler_->DidHandleInputEventOnCompositorThread(
       FakeInputEvent(blink::WebInputEvent::kTouchMove),
       InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order, testing::ElementsAre());
 
   // Receiving the second touchmove will kick us back into compositor priority.
@@ -1729,7 +1699,7 @@
   scheduler_->DidHandleInputEventOnCompositorThread(
       FakeInputEvent(blink::WebInputEvent::kTouchMove),
       InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order, testing::ElementsAre(std::string("L1")));
 }
 
@@ -1742,7 +1712,7 @@
       FROM_HERE, base::BindOnce(&AnticipationTestTask, scheduler_.get(),
                                 SimulateInputType::kNone,
                                 &is_anticipated_before, &is_anticipated_after));
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // In its default state, without input receipt, the scheduler should indicate
   // that no high-priority is anticipated.
   EXPECT_FALSE(is_anticipated_before);
@@ -1765,18 +1735,19 @@
       base::BindOnce(&AnticipationTestTask, scheduler_.get(),
                      SimulateInputType::kGestureScrollEnd, &dummy, &dummy));
 
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // When input is received, the scheduler should indicate that high-priority
   // work is anticipated.
   EXPECT_FALSE(is_anticipated_before);
   EXPECT_TRUE(is_anticipated_after);
 
-  clock_.Advance(priority_escalation_after_input_duration() * 2);
+  test_task_runner_->AdvanceMockTickClock(
+      priority_escalation_after_input_duration() * 2);
   default_task_runner_->PostTask(
       FROM_HERE, base::BindOnce(&AnticipationTestTask, scheduler_.get(),
                                 SimulateInputType::kNone,
                                 &is_anticipated_before, &is_anticipated_after));
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // Without additional input, the scheduler should go into NONE
   // use case but with scrolling expected where high-priority work is still
   // anticipated.
@@ -1785,12 +1756,13 @@
   EXPECT_TRUE(is_anticipated_before);
   EXPECT_TRUE(is_anticipated_after);
 
-  clock_.Advance(subsequent_input_expected_after_input_duration() * 2);
+  test_task_runner_->AdvanceMockTickClock(
+      subsequent_input_expected_after_input_duration() * 2);
   default_task_runner_->PostTask(
       FROM_HERE, base::BindOnce(&AnticipationTestTask, scheduler_.get(),
                                 SimulateInputType::kNone,
                                 &is_anticipated_before, &is_anticipated_after));
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // Eventually the scheduler should go into the default use case where
   // high-priority work is no longer anticipated.
   EXPECT_EQ(UseCase::kNone, CurrentUseCase());
@@ -1807,7 +1779,7 @@
       FROM_HERE, base::BindOnce(&PostingYieldingTestTask, scheduler_.get(),
                                 base::RetainedRef(default_task_runner_), false,
                                 &should_yield_before, &should_yield_after));
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // Posting to default runner shouldn't cause yielding.
   EXPECT_FALSE(should_yield_before);
   EXPECT_FALSE(should_yield_after);
@@ -1817,7 +1789,7 @@
       base::BindOnce(&PostingYieldingTestTask, scheduler_.get(),
                      base::RetainedRef(compositor_task_runner_), false,
                      &should_yield_before, &should_yield_after));
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // Posting while not mainthread scrolling shouldn't cause yielding.
   EXPECT_FALSE(should_yield_before);
   EXPECT_FALSE(should_yield_after);
@@ -1827,7 +1799,7 @@
       base::BindOnce(&PostingYieldingTestTask, scheduler_.get(),
                      base::RetainedRef(compositor_task_runner_), true,
                      &should_yield_before, &should_yield_after));
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // We should be able to switch to compositor priority mid-task.
   EXPECT_FALSE(should_yield_before);
   EXPECT_TRUE(should_yield_after);
@@ -1841,7 +1813,7 @@
       FakeInputEvent(blink::WebInputEvent::kTouchStart),
       InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
   EXPECT_TRUE(scheduler_->ShouldYieldForHighPriorityWork());
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 }
 
 TEST_F(MainThreadSchedulerImplTest, SlowMainThreadInputEvent) {
@@ -1851,217 +1823,176 @@
   scheduler_->DidHandleInputEventOnCompositorThread(
       FakeInputEvent(blink::WebInputEvent::kGestureFlingStart),
       InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_EQ(UseCase::kMainThreadCustomInputHandling, CurrentUseCase());
 
   // Simulate the input event being queued for a very long time. The compositor
   // task we post here represents the enqueued input task.
-  clock_.Advance(priority_escalation_after_input_duration() * 2);
+  test_task_runner_->AdvanceMockTickClock(
+      priority_escalation_after_input_duration() * 2);
   scheduler_->DidHandleInputEventOnMainThread(
       FakeInputEvent(blink::WebInputEvent::kGestureFlingStart),
       WebInputEventResult::kHandledSystem);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   // Even though we exceeded the input priority escalation period, we should
   // still be in main thread gesture since the input remains queued.
   EXPECT_EQ(UseCase::kMainThreadCustomInputHandling, CurrentUseCase());
 
   // After the escalation period ends we should go back into normal mode.
-  clock_.Advance(priority_escalation_after_input_duration() * 2);
-  RunUntilIdle();
+  test_task_runner_->FastForwardBy(priority_escalation_after_input_duration() *
+                                   2);
   EXPECT_EQ(UseCase::kNone, CurrentUseCase());
 }
 
-class MainThreadSchedulerImplWithMockSchedulerTest
-    : public MainThreadSchedulerImplTest {
- public:
-  void SetUp() override {
-    mock_task_runner_ =
-        base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(&clock_, false);
-    mock_scheduler_ = new MainThreadSchedulerImplForTest(
-        base::sequence_manager::TaskQueueManagerForTest::Create(
-            nullptr, mock_task_runner_, &clock_),
-        base::nullopt);
-    Initialize(base::WrapUnique(mock_scheduler_));
+TEST_F(MainThreadSchedulerImplTest, OnlyOnePendingUrgentPolicyUpdate) {
+  for (int i = 0; i < 4; i++) {
+    scheduler_->EnsureUrgentPolicyUpdatePostedOnMainThread();
   }
-
- protected:
-  MainThreadSchedulerImplForTest* mock_scheduler_;
-};
-
-TEST_F(MainThreadSchedulerImplWithMockSchedulerTest,
-       OnlyOnePendingUrgentPolicyUpdatey) {
-  mock_scheduler_->EnsureUrgentPolicyUpdatePostedOnMainThread();
-  mock_scheduler_->EnsureUrgentPolicyUpdatePostedOnMainThread();
-  mock_scheduler_->EnsureUrgentPolicyUpdatePostedOnMainThread();
-  mock_scheduler_->EnsureUrgentPolicyUpdatePostedOnMainThread();
-
-  RunUntilIdle();
-
-  EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(1, scheduler_->update_policy_count_);
 }
 
-TEST_F(MainThreadSchedulerImplWithMockSchedulerTest,
-       OnePendingDelayedAndOneUrgentUpdatePolicy) {
-  ScopedAutoAdvanceNowEnabler enable_auto_advance_now(mock_task_runner_);
+TEST_F(MainThreadSchedulerImplTest, OnePendingDelayedAndOneUrgentUpdatePolicy) {
+  scheduler_->ScheduleDelayedPolicyUpdate(Now(),
+                                          base::TimeDelta::FromMilliseconds(1));
+  scheduler_->EnsureUrgentPolicyUpdatePostedOnMainThread();
 
-  mock_scheduler_->ScheduleDelayedPolicyUpdate(
-      clock_.NowTicks(), base::TimeDelta::FromMilliseconds(1));
-  mock_scheduler_->EnsureUrgentPolicyUpdatePostedOnMainThread();
-
-  RunUntilIdle();
-
+  test_task_runner_->FastForwardUntilNoTasksRemain();
   // We expect both the urgent and the delayed updates to run.
-  EXPECT_EQ(2, mock_scheduler_->update_policy_count_);
+  EXPECT_EQ(2, scheduler_->update_policy_count_);
 }
 
-TEST_F(MainThreadSchedulerImplWithMockSchedulerTest,
-       OneUrgentAndOnePendingDelayedUpdatePolicy) {
-  ScopedAutoAdvanceNowEnabler enable_auto_advance_now(mock_task_runner_);
+TEST_F(MainThreadSchedulerImplTest, OneUrgentAndOnePendingDelayedUpdatePolicy) {
+  scheduler_->EnsureUrgentPolicyUpdatePostedOnMainThread();
+  scheduler_->ScheduleDelayedPolicyUpdate(Now(),
+                                          base::TimeDelta::FromMilliseconds(1));
 
-  mock_scheduler_->EnsureUrgentPolicyUpdatePostedOnMainThread();
-  mock_scheduler_->ScheduleDelayedPolicyUpdate(
-      clock_.NowTicks(), base::TimeDelta::FromMilliseconds(1));
-
-  RunUntilIdle();
-
+  test_task_runner_->FastForwardUntilNoTasksRemain();
   // We expect both the urgent and the delayed updates to run.
-  EXPECT_EQ(2, mock_scheduler_->update_policy_count_);
+  EXPECT_EQ(2, scheduler_->update_policy_count_);
 }
 
-TEST_F(MainThreadSchedulerImplWithMockSchedulerTest,
-       UpdatePolicyCountTriggeredByOneInputEvent) {
+TEST_F(MainThreadSchedulerImplTest, UpdatePolicyCountTriggeredByOneInputEvent) {
   // We expect DidHandleInputEventOnCompositorThread to post an urgent policy
   // update.
   scheduler_->DidHandleInputEventOnCompositorThread(
       FakeInputEvent(blink::WebInputEvent::kTouchStart),
       InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
-  EXPECT_EQ(0, mock_scheduler_->update_policy_count_);
-  mock_task_runner_->RunPendingTasks();
-  EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
+  EXPECT_EQ(0, scheduler_->update_policy_count_);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(1, scheduler_->update_policy_count_);
 
   scheduler_->DidHandleInputEventOnMainThread(
       FakeInputEvent(blink::WebInputEvent::kTouchStart),
       WebInputEventResult::kHandledSystem);
-  EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
+  EXPECT_EQ(1, scheduler_->update_policy_count_);
 
-  clock_.Advance(base::TimeDelta::FromMilliseconds(1000));
-  RunUntilIdle();
-
+  test_task_runner_->AdvanceMockTickClock(base::TimeDelta::FromSeconds(1));
+  base::RunLoop().RunUntilIdle();
   // We finally expect a delayed policy update 100ms later.
-  EXPECT_EQ(2, mock_scheduler_->update_policy_count_);
+  EXPECT_EQ(2, scheduler_->update_policy_count_);
 }
 
-TEST_F(MainThreadSchedulerImplWithMockSchedulerTest,
+TEST_F(MainThreadSchedulerImplTest,
        UpdatePolicyCountTriggeredByThreeInputEvents) {
-  // We expect DidHandleInputEventOnCompositorThread to post an urgent policy
-  // update.
+  // We expect DidHandleInputEventOnCompositorThread to post
+  // an urgent policy update.
   scheduler_->DidHandleInputEventOnCompositorThread(
       FakeInputEvent(blink::WebInputEvent::kTouchStart),
       InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
-  EXPECT_EQ(0, mock_scheduler_->update_policy_count_);
-  mock_task_runner_->RunPendingTasks();
-  EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
+  EXPECT_EQ(0, scheduler_->update_policy_count_);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(1, scheduler_->update_policy_count_);
 
   scheduler_->DidHandleInputEventOnMainThread(
       FakeInputEvent(blink::WebInputEvent::kTouchStart),
       WebInputEventResult::kHandledSystem);
-  EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
+  EXPECT_EQ(1, scheduler_->update_policy_count_);
 
-  // The second call to DidHandleInputEventOnCompositorThread should not post a
-  // policy update because we are already in compositor priority.
+  // The second call to DidHandleInputEventOnCompositorThread should not post
+  // a policy update because we are already in compositor priority.
   scheduler_->DidHandleInputEventOnCompositorThread(
       FakeInputEvent(blink::WebInputEvent::kTouchMove),
       InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
-  mock_task_runner_->RunPendingTasks();
-  EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(1, scheduler_->update_policy_count_);
 
   // We expect DidHandleInputEvent to trigger a policy update.
   scheduler_->DidHandleInputEventOnMainThread(
       FakeInputEvent(blink::WebInputEvent::kTouchMove),
       WebInputEventResult::kHandledSystem);
-  EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
+  EXPECT_EQ(1, scheduler_->update_policy_count_);
 
   // The third call to DidHandleInputEventOnCompositorThread should post a
   // policy update because the awaiting_touch_start_response_ flag changed.
   scheduler_->DidHandleInputEventOnCompositorThread(
       FakeInputEvent(blink::WebInputEvent::kTouchMove),
       InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
-  EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
-  mock_task_runner_->RunPendingTasks();
-  EXPECT_EQ(2, mock_scheduler_->update_policy_count_);
+  EXPECT_EQ(1, scheduler_->update_policy_count_);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(2, scheduler_->update_policy_count_);
 
   // We expect DidHandleInputEvent to trigger a policy update.
   scheduler_->DidHandleInputEventOnMainThread(
       FakeInputEvent(blink::WebInputEvent::kTouchMove),
       WebInputEventResult::kHandledSystem);
-  EXPECT_EQ(2, mock_scheduler_->update_policy_count_);
-
-  clock_.Advance(base::TimeDelta::FromMilliseconds(1000));
-  RunUntilIdle();
-
+  EXPECT_EQ(2, scheduler_->update_policy_count_);
+  test_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1));
   // We finally expect a delayed policy update.
-  EXPECT_EQ(3, mock_scheduler_->update_policy_count_);
+  EXPECT_EQ(3, scheduler_->update_policy_count_);
 }
 
-TEST_F(MainThreadSchedulerImplWithMockSchedulerTest,
+TEST_F(MainThreadSchedulerImplTest,
        UpdatePolicyCountTriggeredByTwoInputEventsWithALongSeparatingDelay) {
   // We expect DidHandleInputEventOnCompositorThread to post an urgent policy
   // update.
   scheduler_->DidHandleInputEventOnCompositorThread(
       FakeInputEvent(blink::WebInputEvent::kTouchStart),
       InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
-  EXPECT_EQ(0, mock_scheduler_->update_policy_count_);
-  mock_task_runner_->RunPendingTasks();
-  EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
+  EXPECT_EQ(0, scheduler_->update_policy_count_);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(1, scheduler_->update_policy_count_);
 
   scheduler_->DidHandleInputEventOnMainThread(
       FakeInputEvent(blink::WebInputEvent::kTouchStart),
       WebInputEventResult::kHandledSystem);
-  EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
-
-  clock_.Advance(base::TimeDelta::FromMilliseconds(1000));
-  RunUntilIdle();
+  EXPECT_EQ(1, scheduler_->update_policy_count_);
+  test_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1));
   // We expect a delayed policy update.
-  EXPECT_EQ(2, mock_scheduler_->update_policy_count_);
+  EXPECT_EQ(2, scheduler_->update_policy_count_);
 
   // We expect the second call to DidHandleInputEventOnCompositorThread to post
   // an urgent policy update because we are no longer in compositor priority.
   scheduler_->DidHandleInputEventOnCompositorThread(
       FakeInputEvent(blink::WebInputEvent::kTouchMove),
       InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
-  EXPECT_EQ(2, mock_scheduler_->update_policy_count_);
-  mock_task_runner_->RunPendingTasks();
-  EXPECT_EQ(3, mock_scheduler_->update_policy_count_);
+  EXPECT_EQ(2, scheduler_->update_policy_count_);
+  base::RunLoop().RunUntilIdle();
+  EXPECT_EQ(3, scheduler_->update_policy_count_);
 
   scheduler_->DidHandleInputEventOnMainThread(
       FakeInputEvent(blink::WebInputEvent::kTouchMove),
       WebInputEventResult::kHandledSystem);
-  EXPECT_EQ(3, mock_scheduler_->update_policy_count_);
-
-  clock_.Advance(base::TimeDelta::FromMilliseconds(1000));
-  RunUntilIdle();
-
+  EXPECT_EQ(3, scheduler_->update_policy_count_);
+  test_task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1));
   // We finally expect a delayed policy update.
-  EXPECT_EQ(4, mock_scheduler_->update_policy_count_);
+  EXPECT_EQ(4, scheduler_->update_policy_count_);
 }
 
-TEST_F(MainThreadSchedulerImplWithMockSchedulerTest,
-       EnsureUpdatePolicyNotTriggeredTooOften) {
-  ScopedAutoAdvanceNowEnabler enable_auto_advance_now(mock_task_runner_);
-
-  EXPECT_EQ(0, mock_scheduler_->update_policy_count_);
+TEST_F(MainThreadSchedulerImplTest, EnsureUpdatePolicyNotTriggeredTooOften) {
+  EXPECT_EQ(0, scheduler_->update_policy_count_);
   scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
-  EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
+  EXPECT_EQ(1, scheduler_->update_policy_count_);
 
   SimulateCompositorGestureStart(TouchEventPolicy::kSendTouchStart);
 
   // We expect the first call to IsHighPriorityWorkAnticipated to be called
   // after receiving an input event (but before the UpdateTask was processed) to
   // call UpdatePolicy.
-  EXPECT_EQ(1, mock_scheduler_->update_policy_count_);
+  EXPECT_EQ(1, scheduler_->update_policy_count_);
   scheduler_->IsHighPriorityWorkAnticipated();
-  EXPECT_EQ(2, mock_scheduler_->update_policy_count_);
+  EXPECT_EQ(2, scheduler_->update_policy_count_);
   // Subsequent calls should not call UpdatePolicy.
   scheduler_->IsHighPriorityWorkAnticipated();
   scheduler_->IsHighPriorityWorkAnticipated();
@@ -2091,14 +2022,14 @@
       FakeInputEvent(blink::WebInputEvent::kTouchEnd),
       WebInputEventResult::kHandledSystem);
 
-  EXPECT_EQ(2, mock_scheduler_->update_policy_count_);
+  EXPECT_EQ(2, scheduler_->update_policy_count_);
 
   // We expect both the urgent and the delayed updates to run in addition to the
   // earlier updated cause by IsHighPriorityWorkAnticipated, a final update
   // transitions from 'not_scrolling touchstart expected' to 'not_scrolling'.
-  RunUntilIdle();
+  test_task_runner_->FastForwardUntilNoTasksRemain();
   EXPECT_THAT(
-      mock_scheduler_->use_cases_,
+      scheduler_->use_cases_,
       testing::ElementsAre(
           std::string("none"), std::string("compositor_gesture"),
           std::string("compositor_gesture touchstart expected"),
@@ -2109,9 +2040,20 @@
     : public MainThreadSchedulerImplTest {
  public:
   MainThreadSchedulerImplWithMessageLoopTest()
-      : MainThreadSchedulerImplTest(new base::MessageLoop()) {}
+      : message_loop_(new base::MessageLoop()) {}
   ~MainThreadSchedulerImplWithMessageLoopTest() override = default;
 
+  void SetUp() override {
+    clock_.Advance(base::TimeDelta::FromMilliseconds(5));
+    Initialize(std::make_unique<MainThreadSchedulerImplForTest>(
+        base::sequence_manager::TaskQueueManagerForTest::Create(
+            message_loop_.get(), message_loop_->task_runner(), &clock_),
+        base::nullopt));
+  }
+
+  // Needed for EnableIdleTasks().
+  base::TimeTicks Now() override { return clock_.NowTicks(); }
+
   void PostFromNestedRunloop(
       std::vector<std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>>*
           tasks) {
@@ -2128,6 +2070,9 @@
   }
 
  private:
+  std::unique_ptr<base::MessageLoop> message_loop_;
+  base::SimpleTestTickClock clock_;
+
   DISALLOW_COPY_AND_ASSIGN(MainThreadSchedulerImplWithMessageLoopTest);
 };
 
@@ -2161,7 +2106,7 @@
           base::Unretained(&tasks_to_post_from_nested_loop)));
 
   EnableIdleTasks();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   // Note we expect task 3 to run last because it's non-nestable.
   EXPECT_THAT(order, testing::ElementsAre(std::string("1"), std::string("2"),
                                           std::string("4"), std::string("5"),
@@ -2170,47 +2115,46 @@
 
 TEST_F(MainThreadSchedulerImplTest, TestBeginMainFrameNotExpectedUntil) {
   base::TimeDelta ten_millis(base::TimeDelta::FromMilliseconds(10));
-  base::TimeTicks expected_deadline = clock_.NowTicks() + ten_millis;
+  base::TimeTicks expected_deadline = Now() + ten_millis;
   base::TimeTicks deadline_in_task;
   int run_count = 0;
 
   idle_task_runner_->PostIdleTask(
       FROM_HERE, base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task));
 
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_EQ(0, run_count);  // Shouldn't run yet as no idle period.
 
-  base::TimeTicks now = clock_.NowTicks();
+  base::TimeTicks now = Now();
   base::TimeTicks frame_time = now + ten_millis;
   // No main frame is expected until frame_time, so short idle work can be
   // scheduled in the mean time.
   scheduler_->BeginMainFrameNotExpectedUntil(frame_time);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1, run_count);  // Should have run in a long idle time.
   EXPECT_EQ(expected_deadline, deadline_in_task);
 }
 
 TEST_F(MainThreadSchedulerImplTest, TestLongIdlePeriod) {
-  base::TimeTicks expected_deadline =
-      clock_.NowTicks() + maximum_idle_period_duration();
+  base::TimeTicks expected_deadline = Now() + maximum_idle_period_duration();
   base::TimeTicks deadline_in_task;
   int run_count = 0;
 
   idle_task_runner_->PostIdleTask(
       FROM_HERE, base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task));
 
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_EQ(0, run_count);  // Shouldn't run yet as no idle period.
 
   scheduler_->BeginFrameNotExpectedSoon();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1, run_count);  // Should have run in a long idle time.
   EXPECT_EQ(expected_deadline, deadline_in_task);
 }
 
 TEST_F(MainThreadSchedulerImplTest, TestLongIdlePeriodWithPendingDelayedTask) {
   base::TimeDelta pending_task_delay = base::TimeDelta::FromMilliseconds(30);
-  base::TimeTicks expected_deadline = clock_.NowTicks() + pending_task_delay;
+  base::TimeTicks expected_deadline = Now() + pending_task_delay;
   base::TimeTicks deadline_in_task;
   int run_count = 0;
 
@@ -2220,7 +2164,7 @@
                                         pending_task_delay);
 
   scheduler_->BeginFrameNotExpectedSoon();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1, run_count);  // Should have run in a long idle time.
   EXPECT_EQ(expected_deadline, deadline_in_task);
 }
@@ -2235,7 +2179,8 @@
                                         pending_task_delay);
 
   // Advance clock until after delayed task was meant to be run.
-  clock_.Advance(base::TimeDelta::FromMilliseconds(20));
+  test_task_runner_->AdvanceMockTickClock(
+      base::TimeDelta::FromMilliseconds(20));
 
   // Post an idle task and BeginFrameNotExpectedSoon to initiate a long idle
   // period. Since there is a late pending delayed task this shouldn't actually
@@ -2243,30 +2188,28 @@
   idle_task_runner_->PostIdleTask(
       FROM_HERE, base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task));
   scheduler_->BeginFrameNotExpectedSoon();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_EQ(0, run_count);
 
   // After the delayed task has been run we should trigger an idle period.
-  clock_.Advance(maximum_idle_period_duration());
-  RunUntilIdle();
+  test_task_runner_->FastForwardBy(maximum_idle_period_duration());
   EXPECT_EQ(1, run_count);
 }
 
 TEST_F(MainThreadSchedulerImplTest, TestLongIdlePeriodRepeating) {
-  ScopedAutoAdvanceNowEnabler enable_auto_advance_now(mock_task_runner_);
   std::vector<base::TimeTicks> actual_deadlines;
   int run_count = 0;
 
   g_max_idle_task_reposts = 3;
-  base::TimeTicks clock_before(clock_.NowTicks());
+  base::TimeTicks clock_before = Now();
   base::TimeDelta idle_task_runtime(base::TimeDelta::FromMilliseconds(10));
   idle_task_runner_->PostIdleTask(
       FROM_HERE,
       base::BindOnce(&RepostingUpdateClockIdleTestTask,
-                     base::RetainedRef(idle_task_runner_), &run_count, &clock_,
-                     idle_task_runtime, &actual_deadlines));
+                     base::RetainedRef(idle_task_runner_), &run_count,
+                     test_task_runner_, idle_task_runtime, &actual_deadlines));
   scheduler_->BeginFrameNotExpectedSoon();
-  RunUntilIdle();
+  test_task_runner_->FastForwardUntilNoTasksRemain();
   EXPECT_EQ(3, run_count);
   EXPECT_THAT(
       actual_deadlines,
@@ -2280,13 +2223,15 @@
   idle_task_runner_->PostIdleTask(
       FROM_HERE,
       base::BindOnce(&RepostingUpdateClockIdleTestTask,
-                     base::RetainedRef(idle_task_runner_), &run_count, &clock_,
-                     idle_task_runtime, &actual_deadlines));
+                     base::RetainedRef(idle_task_runner_), &run_count,
+                     test_task_runner_, idle_task_runtime, &actual_deadlines));
   idle_task_runner_->PostIdleTask(
-      FROM_HERE, base::BindOnce(&WillBeginFrameIdleTask,
-                                base::Unretained(scheduler_.get()),
-                                next_begin_frame_number_++, &clock_));
-  RunUntilIdle();
+      FROM_HERE,
+      base::BindOnce(&WillBeginFrameIdleTask,
+                     base::Unretained(scheduler_.get()),
+                     next_begin_frame_number_++,
+                     base::Unretained(test_task_runner_->GetMockTickClock())));
+  test_task_runner_->FastForwardUntilNoTasksRemain();
   EXPECT_EQ(4, run_count);
 }
 
@@ -2302,12 +2247,11 @@
       FakeInputEvent(blink::WebInputEvent::kTouchStart),
       InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
   scheduler_->BeginFrameNotExpectedSoon();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_EQ(0, run_count);
 
   // The long idle period should start after the touchstart policy has finished.
-  clock_.Advance(priority_escalation_after_input_duration());
-  RunUntilIdle();
+  test_task_runner_->FastForwardBy(priority_escalation_after_input_duration());
   EXPECT_EQ(1, run_count);
 }
 
@@ -2332,7 +2276,7 @@
       base::BindOnce(&TestCanExceedIdleDeadlineIfRequiredTask, scheduler_.get(),
                      &can_exceed_idle_deadline, &run_count));
   EnableIdleTasks();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_EQ(1, run_count);
   EXPECT_FALSE(can_exceed_idle_deadline);
 
@@ -2345,33 +2289,31 @@
       base::BindOnce(&TestCanExceedIdleDeadlineIfRequiredTask, scheduler_.get(),
                      &can_exceed_idle_deadline, &run_count));
   scheduler_->BeginFrameNotExpectedSoon();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_EQ(2, run_count);
   EXPECT_FALSE(can_exceed_idle_deadline);
 
   // Next long idle period will be for the maximum time, so
   // CanExceedIdleDeadlineIfRequired should return true.
-  clock_.Advance(maximum_idle_period_duration());
+  test_task_runner_->AdvanceMockTickClock(maximum_idle_period_duration());
   idle_task_runner_->PostIdleTask(
       FROM_HERE,
       base::BindOnce(&TestCanExceedIdleDeadlineIfRequiredTask, scheduler_.get(),
                      &can_exceed_idle_deadline, &run_count));
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_EQ(3, run_count);
   EXPECT_TRUE(can_exceed_idle_deadline);
 
   // Next long idle period will be for the maximum time, so
   // CanExceedIdleDeadlineIfRequired should return true.
   scheduler_->WillBeginFrame(viz::BeginFrameArgs::Create(
-      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
+      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
       base::TimeTicks(), base::TimeDelta::FromMilliseconds(1000),
       viz::BeginFrameArgs::NORMAL));
   EXPECT_FALSE(scheduler_->CanExceedIdleDeadlineIfRequired());
 }
 
 TEST_F(MainThreadSchedulerImplTest, TestRendererHiddenIdlePeriod) {
-  ScopedAutoAdvanceNowEnabler enable_auto_advance_now(mock_task_runner_);
-
   int run_count = 0;
 
   g_max_idle_task_reposts = 2;
@@ -2381,14 +2323,14 @@
                      base::RetainedRef(idle_task_runner_), &run_count));
 
   // Renderer should start in visible state.
-  RunUntilIdle();
+  test_task_runner_->FastForwardUntilNoTasksRemain();
   EXPECT_EQ(0, run_count);
 
   // When we hide the renderer it should start a max deadline idle period, which
   // will run an idle task and then immediately start a new idle period, which
   // runs the second idle task.
   scheduler_->SetAllRenderWidgetsHidden(true);
-  RunUntilIdle();
+  test_task_runner_->FastForwardUntilNoTasksRemain();
   EXPECT_EQ(2, run_count);
 
   // Advance time by amount of time by the maximum amount of time we execute
@@ -2398,16 +2340,15 @@
       FROM_HERE,
       base::BindOnce(&RepostingIdleTestTask,
                      base::RetainedRef(idle_task_runner_), &run_count));
-  clock_.Advance(end_idle_when_hidden_delay() +
-                 base::TimeDelta::FromMilliseconds(10));
-  RunUntilIdle();
+  test_task_runner_->FastForwardBy(end_idle_when_hidden_delay() +
+                                   base::TimeDelta::FromMilliseconds(10));
   EXPECT_EQ(2, run_count);
 }
 
 TEST_F(MainThreadSchedulerImplTest, TimerQueueEnabledByDefault) {
   std::vector<std::string> run_order;
   PostTestTasks(&run_order, "T1 T2");
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("T1"), std::string("T2")));
 }
@@ -2417,11 +2358,11 @@
   PostTestTasks(&run_order, "T1 T2");
 
   auto pause_handle = scheduler_->PauseRenderer();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order, testing::ElementsAre());
 
   pause_handle.reset();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("T1"), std::string("T2")));
 }
@@ -2431,10 +2372,10 @@
   PostTestTasks(&run_order, "T1 T2");
 
   auto pause_handle = scheduler_->PauseRenderer();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   scheduler_->task_queue_throttler()->IncreaseThrottleRefCount(
       static_cast<TaskQueue*>(timer_task_runner_.get()));
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order, testing::ElementsAre());
 }
 
@@ -2444,9 +2385,9 @@
 
   scheduler_->task_queue_throttler()->IncreaseThrottleRefCount(
       static_cast<TaskQueue*>(timer_task_runner_.get()));
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   auto pause_handle = scheduler_->PauseRenderer();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order, testing::ElementsAre());
 }
 
@@ -2457,19 +2398,19 @@
   auto pause_handle1 = scheduler_->PauseRenderer();
   auto pause_handle2 = scheduler_->PauseRenderer();
   auto pause_handle3 = scheduler_->PauseRenderer();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order, testing::ElementsAre());
 
   pause_handle1.reset();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order, testing::ElementsAre());
 
   pause_handle2.reset();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order, testing::ElementsAre());
 
   pause_handle3.reset();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("T1"), std::string("T2")));
 }
@@ -2480,7 +2421,7 @@
   PostTestTasks(&run_order, "D1 C1 L1 I1 T1");
   auto pause_handle = scheduler_->PauseRenderer();
   EnableIdleTasks();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("D1"), std::string("C1"),
                                    std::string("I1")));
@@ -2488,7 +2429,7 @@
   // Tasks are executed when renderer is resumed.
   run_order.clear();
   pause_handle.reset();
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("L1"), std::string("T1")));
 }
@@ -2511,7 +2452,7 @@
   ASSERT_FALSE(scheduler_->BeginMainFrameOnCriticalPath());
 
   viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
+      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
       base::TimeTicks(), base::TimeDelta::FromMilliseconds(1000),
       viz::BeginFrameArgs::NORMAL);
   scheduler_->WillBeginFrame(begin_frame_args);
@@ -2528,7 +2469,7 @@
   scheduler_->Shutdown();
   std::vector<std::string> run_order;
   PostTestTasks(&run_order, "D1 C1");
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order, testing::ElementsAre());
 }
 
@@ -2555,8 +2496,8 @@
   // The background signal will not immediately suspend the timer queue.
   scheduler_->SetRendererBackgrounded(true);
   now += base::TimeDelta::FromMilliseconds(1100);
-  clock_.SetNowTicks(now);
-  RunUntilIdle();
+  AdvanceMockTickClockTo(now);
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("T1"), std::string("T2")));
 
@@ -2564,35 +2505,35 @@
   PostTestTasks(&run_order, "T3");
 
   now += base::TimeDelta::FromSeconds(1);
-  clock_.SetNowTicks(now);
-  RunUntilIdle();
+  AdvanceMockTickClockTo(now);
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order, testing::ElementsAre(std::string("T3")));
 
   // Advance the time until after the scheduled timer queue suspension.
   now = base::TimeTicks() + delay_for_background_tab_freezing() +
         base::TimeDelta::FromMilliseconds(10);
   run_order.clear();
-  clock_.SetNowTicks(now);
-  RunUntilIdle();
+  AdvanceMockTickClockTo(now);
+  base::RunLoop().RunUntilIdle();
   ASSERT_TRUE(run_order.empty());
 
   // Timer tasks should be paused until the foregrounded signal.
   PostTestTasks(&run_order, "T4 T5 V1");
   now += base::TimeDelta::FromSeconds(10);
-  clock_.SetNowTicks(now);
-  RunUntilIdle();
+  AdvanceMockTickClockTo(now);
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order, testing::ElementsAre(std::string("V1")));
 
   run_order.clear();
   scheduler_->SetRendererBackgrounded(false);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("T4"), std::string("T5")));
 
   // Subsequent timer tasks should fire as usual.
   run_order.clear();
   PostTestTasks(&run_order, "T6");
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order, testing::ElementsAre(std::string("T6")));
 }
 
@@ -2604,7 +2545,7 @@
   SimulateExpensiveTasks(loading_task_runner_);
   ForceTouchStartToBeExpectedSoon();
   PostTestTasks(&run_order, "L1 D1");
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(UseCase::kNone, ForceUpdatePolicyAndGetCurrentUseCase());
   EXPECT_FALSE(HaveSeenABeginMainframe());
@@ -2619,7 +2560,7 @@
   run_order.clear();
 
   PostTestTasks(&run_order, "L1 D1");
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(UseCase::kNone, CurrentUseCase());
   EXPECT_TRUE(HaveSeenABeginMainframe());
@@ -2639,7 +2580,7 @@
   SimulateExpensiveTasks(loading_task_runner_);
   ForceTouchStartToBeExpectedSoon();
   PostTestTasks(&run_order, "L1 D1");
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(UseCase::kNone, ForceUpdatePolicyAndGetCurrentUseCase());
   EXPECT_TRUE(HaveSeenABeginMainframe());
@@ -2661,7 +2602,7 @@
   ForceTouchStartToBeExpectedSoon();
 
   PostTestTasks(&run_order, "T1 D1");
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(UseCase::kNone, ForceUpdatePolicyAndGetCurrentUseCase());
   EXPECT_TRUE(HaveSeenABeginMainframe());
@@ -2692,11 +2633,12 @@
       FakeInputEvent(blink::WebInputEvent::kTouchEnd),
       WebInputEventResult::kHandledSystem);
 
-  clock_.Advance(priority_escalation_after_input_duration() * 2);
+  test_task_runner_->AdvanceMockTickClock(
+      priority_escalation_after_input_duration() * 2);
   EXPECT_EQ(UseCase::kNone, ForceUpdatePolicyAndGetCurrentUseCase());
 
   PostTestTasks(&run_order, "T1 D1");
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(UseCase::kNone, ForceUpdatePolicyAndGetCurrentUseCase());
   EXPECT_TRUE(HaveSeenABeginMainframe());
@@ -2719,7 +2661,7 @@
   scheduler_->DidAnimateForInputOnCompositorThread();
 
   PostTestTasks(&run_order, "T1 D1");
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(UseCase::kCompositorGesture,
             ForceUpdatePolicyAndGetCurrentUseCase());
@@ -2742,7 +2684,7 @@
   scheduler_->BeginFrameNotExpectedSoon();
 
   PostTestTasks(&run_order, "T1 D1");
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(UseCase::kNone, ForceUpdatePolicyAndGetCurrentUseCase());
   EXPECT_TRUE(HaveSeenABeginMainframe());
@@ -2763,7 +2705,7 @@
   ForceTouchStartToBeExpectedSoon();
 
   PostTestTasks(&run_order, "L1 D1");
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   // The expensive loading task gets blocked.
   EXPECT_THAT(run_order, testing::ElementsAre(std::string("D1")));
@@ -2782,7 +2724,7 @@
   // Trigger main_thread_gesture UseCase
   SimulateMainThreadGestureStart(TouchEventPolicy::kSendTouchStart,
                                  blink::WebInputEvent::kGestureScrollBegin);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_EQ(UseCase::kMainThreadCustomInputHandling, CurrentUseCase());
 
   EXPECT_TRUE(LoadingTasksSeemExpensive());
@@ -2796,12 +2738,12 @@
   scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
   SimulateMainThreadGestureStart(TouchEventPolicy::kSendTouchStart,
                                  blink::WebInputEvent::kTouchMove);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   for (int i = 0; i < 20; i++) {
     simulate_timer_task_ran_ = false;
 
     viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
+        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
         base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
         viz::BeginFrameArgs::NORMAL);
     begin_frame_args.on_critical_path = false;
@@ -2819,29 +2761,28 @@
                        base::Unretained(this),
                        base::TimeDelta::FromMilliseconds(4)));
 
-    RunUntilIdle();
+    base::RunLoop().RunUntilIdle();
     EXPECT_TRUE(simulate_timer_task_ran_) << " i = " << i;
     EXPECT_EQ(UseCase::kMainThreadCustomInputHandling, CurrentUseCase())
         << " i = " << i;
     EXPECT_FALSE(LoadingTasksSeemExpensive()) << " i = " << i;
     EXPECT_FALSE(TimerTasksSeemExpensive()) << " i = " << i;
 
-    base::TimeDelta time_till_next_frame =
-        EstimatedNextFrameBegin() - clock_.NowTicks();
+    base::TimeDelta time_till_next_frame = EstimatedNextFrameBegin() - Now();
     if (time_till_next_frame > base::TimeDelta())
-      clock_.Advance(time_till_next_frame);
+      test_task_runner_->AdvanceMockTickClock(time_till_next_frame);
   }
 }
 
 TEST_F(MainThreadSchedulerImplTest,
        FourtyMsTimer_NotBlocked_CompositorScrolling) {
   scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   for (int i = 0; i < 20; i++) {
     simulate_timer_task_ran_ = false;
 
     viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
+        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
         base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
         viz::BeginFrameArgs::NORMAL);
     begin_frame_args.on_critical_path = false;
@@ -2859,16 +2800,15 @@
                        base::Unretained(this),
                        base::TimeDelta::FromMilliseconds(40)));
 
-    RunUntilIdle();
+    base::RunLoop().RunUntilIdle();
     EXPECT_TRUE(simulate_timer_task_ran_) << " i = " << i;
     EXPECT_EQ(UseCase::kCompositorGesture, CurrentUseCase()) << " i = " << i;
     EXPECT_FALSE(LoadingTasksSeemExpensive()) << " i = " << i;
     EXPECT_FALSE(TimerTasksSeemExpensive()) << " i = " << i;
 
-    base::TimeDelta time_till_next_frame =
-        EstimatedNextFrameBegin() - clock_.NowTicks();
+    base::TimeDelta time_till_next_frame = EstimatedNextFrameBegin() - Now();
     if (time_till_next_frame > base::TimeDelta())
-      clock_.Advance(time_till_next_frame);
+      test_task_runner_->AdvanceMockTickClock(time_till_next_frame);
   }
 }
 
@@ -2877,12 +2817,12 @@
   scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true);
   SimulateMainThreadGestureStart(TouchEventPolicy::kSendTouchStart,
                                  blink::WebInputEvent::kTouchMove);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   for (int i = 0; i < 20; i++) {
     simulate_timer_task_ran_ = false;
 
     viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
+        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
         base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
         viz::BeginFrameArgs::NORMAL);
     begin_frame_args.on_critical_path = false;
@@ -2900,7 +2840,7 @@
                        base::Unretained(this),
                        base::TimeDelta::FromMilliseconds(10)));
 
-    RunUntilIdle();
+    base::RunLoop().RunUntilIdle();
     EXPECT_EQ(UseCase::kMainThreadCustomInputHandling, CurrentUseCase())
         << " i = " << i;
     EXPECT_FALSE(LoadingTasksSeemExpensive()) << " i = " << i;
@@ -2911,10 +2851,9 @@
     }
     EXPECT_TRUE(simulate_timer_task_ran_) << " i = " << i;
 
-    base::TimeDelta time_till_next_frame =
-        EstimatedNextFrameBegin() - clock_.NowTicks();
+    base::TimeDelta time_till_next_frame = EstimatedNextFrameBegin() - Now();
     if (time_till_next_frame > base::TimeDelta())
-      clock_.Advance(time_till_next_frame);
+      test_task_runner_->AdvanceMockTickClock(time_till_next_frame);
   }
 }
 
@@ -2949,7 +2888,7 @@
   SimulateMainThreadGestureStart(TouchEventPolicy::kSendTouchStart,
                                  blink::WebInputEvent::kGestureScrollUpdate);
   viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
+      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
       base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
       viz::BeginFrameArgs::NORMAL);
   begin_frame_args.on_critical_path = false;
@@ -2962,7 +2901,7 @@
                      base::Unretained(this),
                      base::TimeDelta::FromMilliseconds(5)));
 
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_EQ(UseCase::kMainThreadGesture, CurrentUseCase());
 
   // 16ms frame - 5ms compositor work = 11ms for other stuff.
@@ -2974,7 +2913,7 @@
     MainThreadSchedulerImplTest,
     EstimateLongestJankFreeTaskDuration_UseCase_MAIN_THREAD_CUSTOM_INPUT_HANDLING) {
   viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
+      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
       base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
       viz::BeginFrameArgs::NORMAL);
   begin_frame_args.on_critical_path = false;
@@ -2987,7 +2926,7 @@
                      base::Unretained(this),
                      base::TimeDelta::FromMilliseconds(5)));
 
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_EQ(UseCase::kMainThreadCustomInputHandling, CurrentUseCase());
 
   // 16ms frame - 5ms compositor work = 11ms for other stuff.
@@ -3000,7 +2939,7 @@
   SimulateCompositorGestureStart(TouchEventPolicy::kDontSendTouchStart);
 
   viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
+      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
       base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
       viz::BeginFrameArgs::NORMAL);
   begin_frame_args.on_critical_path = true;
@@ -3012,7 +2951,7 @@
           &MainThreadSchedulerImplTest::SimulateMainThreadCompositorTask,
           base::Unretained(this), base::TimeDelta::FromMilliseconds(5)));
 
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_EQ(UseCase::kSynchronizedGesture, CurrentUseCase());
 
   // 16ms frame - 5ms compositor work = 11ms for other stuff.
@@ -3044,14 +2983,15 @@
 
 namespace {
 void SlowCountingTask(size_t* count,
-                      base::SimpleTestTickClock* clock,
+                      scoped_refptr<base::TestMockTimeTaskRunner> task_runner,
                       int task_duration,
                       scoped_refptr<base::SingleThreadTaskRunner> timer_queue) {
-  clock->Advance(base::TimeDelta::FromMilliseconds(task_duration));
+  task_runner->AdvanceMockTickClock(
+      base::TimeDelta::FromMilliseconds(task_duration));
   if (++(*count) < 500) {
-    timer_queue->PostTask(
-        FROM_HERE, base::BindOnce(SlowCountingTask, count, clock, task_duration,
-                                  timer_queue));
+    timer_queue->PostTask(FROM_HERE,
+                          base::BindOnce(SlowCountingTask, count, task_runner,
+                                         task_duration, timer_queue));
   }
 }
 }  // namespace
@@ -3061,18 +3001,18 @@
   SimulateCompositorGestureStart(TouchEventPolicy::kSendTouchStart);
 
   base::TimeTicks first_throttled_run_time =
-      TaskQueueThrottler::AlignedThrottledRunTime(clock_.NowTicks());
+      TaskQueueThrottler::AlignedThrottledRunTime(Now());
 
   size_t count = 0;
   // With the compositor task taking 10ms, there is not enough time to run this
   // 7ms timer task in the 16ms frame.
   timer_task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(SlowCountingTask, &count, &clock_, 7, timer_task_runner_));
+      FROM_HERE, base::BindOnce(SlowCountingTask, &count, test_task_runner_, 7,
+                                timer_task_runner_));
 
   for (int i = 0; i < 1000; i++) {
     viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
+        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
         base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
         viz::BeginFrameArgs::NORMAL);
     begin_frame_args.on_critical_path = true;
@@ -3081,16 +3021,14 @@
         FakeInputEvent(blink::WebInputEvent::kGestureScrollUpdate),
         InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
 
-    simulate_compositor_task_ran_ = false;
     compositor_task_runner_->PostTask(
         FROM_HERE,
-        base::BindOnce(
-            &MainThreadSchedulerImplTest::SimulateMainThreadCompositorTask,
-            base::Unretained(this), base::TimeDelta::FromMilliseconds(10)));
+        base::BindOnce(&MainThreadSchedulerImplTest::
+                           SimulateMainThreadCompositorAndQuitRunLoopTask,
+                       base::Unretained(this),
+                       base::TimeDelta::FromMilliseconds(10)));
 
-    mock_task_runner_->RunTasksWhile(base::BindRepeating(
-        &MainThreadSchedulerImplTest::SimulatedCompositorTaskPending,
-        base::Unretained(this)));
+    base::RunLoop().RunUntilIdle();
     EXPECT_EQ(UseCase::kSynchronizedGesture, CurrentUseCase()) << "i = " << i;
 
     // We expect the queue to get throttled on the second iteration which is
@@ -3110,7 +3048,7 @@
     // The task runs twice before the system realizes it's too expensive.
     bool throttled_task_has_run = count > 2;
     bool throttled_task_expected_to_have_run =
-        (clock_.NowTicks() > first_throttled_run_time);
+        (Now() > first_throttled_run_time);
     EXPECT_EQ(throttled_task_expected_to_have_run, throttled_task_has_run)
         << "i = " << i << " count = " << count;
   }
@@ -3124,19 +3062,19 @@
   SimulateCompositorGestureStart(TouchEventPolicy::kSendTouchStart);
 
   base::TimeTicks first_throttled_run_time =
-      TaskQueueThrottler::AlignedThrottledRunTime(clock_.NowTicks());
+      TaskQueueThrottler::AlignedThrottledRunTime(Now());
 
   size_t count = 0;
   // With the compositor task taking 10ms, there is not enough time to run this
   // 7ms timer task in the 16ms frame.
   timer_task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(SlowCountingTask, &count, &clock_, 7, timer_task_runner_));
+      FROM_HERE, base::BindOnce(SlowCountingTask, &count, test_task_runner_, 7,
+                                timer_task_runner_));
 
   std::unique_ptr<WebThreadScheduler::RendererPauseHandle> paused;
   for (int i = 0; i < 1000; i++) {
     viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
+        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
         base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
         viz::BeginFrameArgs::NORMAL);
     begin_frame_args.on_critical_path = true;
@@ -3145,22 +3083,19 @@
         FakeInputEvent(blink::WebInputEvent::kGestureScrollUpdate),
         InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
 
-    simulate_compositor_task_ran_ = false;
     compositor_task_runner_->PostTask(
         FROM_HERE,
-        base::BindOnce(
-            &MainThreadSchedulerImplTest::SimulateMainThreadCompositorTask,
-            base::Unretained(this), base::TimeDelta::FromMilliseconds(10)));
+        base::BindOnce(&MainThreadSchedulerImplTest::
+                           SimulateMainThreadCompositorAndQuitRunLoopTask,
+                       base::Unretained(this),
+                       base::TimeDelta::FromMilliseconds(10)));
 
-    mock_task_runner_->RunTasksWhile(base::BindRepeating(
-        &MainThreadSchedulerImplTest::SimulatedCompositorTaskPending,
-        base::Unretained(this)));
+    base::RunLoop().RunUntilIdle();
     EXPECT_EQ(UseCase::kSynchronizedGesture, CurrentUseCase()) << "i = " << i;
 
     // Before the policy is updated the queue will be enabled. Subsequently it
     // will be disabled until the throttled queue is pumped.
-    bool expect_queue_enabled =
-        (i == 0) || (clock_.NowTicks() > first_throttled_run_time);
+    bool expect_queue_enabled = (i == 0) || (Now() > first_throttled_run_time);
     if (paused)
       expect_queue_enabled = false;
     EXPECT_EQ(expect_queue_enabled, timer_task_runner_->IsQueueEnabled())
@@ -3187,12 +3122,12 @@
   // With the compositor task taking 10ms, there is enough time to run this 6ms
   // timer task in the 16ms frame.
   timer_task_runner_->PostTask(
-      FROM_HERE,
-      base::BindOnce(SlowCountingTask, &count, &clock_, 6, timer_task_runner_));
+      FROM_HERE, base::BindOnce(SlowCountingTask, &count, test_task_runner_, 6,
+                                timer_task_runner_));
 
   for (int i = 0; i < 1000; i++) {
     viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
+        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
         base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
         viz::BeginFrameArgs::NORMAL);
     begin_frame_args.on_critical_path = true;
@@ -3201,16 +3136,14 @@
         FakeInputEvent(blink::WebInputEvent::kGestureScrollUpdate),
         InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
 
-    simulate_compositor_task_ran_ = false;
     compositor_task_runner_->PostTask(
         FROM_HERE,
-        base::BindOnce(
-            &MainThreadSchedulerImplTest::SimulateMainThreadCompositorTask,
-            base::Unretained(this), base::TimeDelta::FromMilliseconds(10)));
+        base::BindOnce(&MainThreadSchedulerImplTest::
+                           SimulateMainThreadCompositorAndQuitRunLoopTask,
+                       base::Unretained(this),
+                       base::TimeDelta::FromMilliseconds(10)));
 
-    mock_task_runner_->RunTasksWhile(base::BindRepeating(
-        &MainThreadSchedulerImplTest::SimulatedCompositorTaskPending,
-        base::Unretained(this)));
+    base::RunLoop().RunUntilIdle();
     EXPECT_EQ(UseCase::kSynchronizedGesture, CurrentUseCase()) << "i = " << i;
     EXPECT_TRUE(timer_task_runner_->IsQueueEnabled()) << "i = " << i;
   }
@@ -3232,7 +3165,7 @@
       InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
 
   viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
+      BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
       base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
       viz::BeginFrameArgs::NORMAL);
   begin_frame_args.on_critical_path = true;
@@ -3294,7 +3227,7 @@
 
   for (int i = 0; i < 100; i++) {
     viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
+        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
         base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
         viz::BeginFrameArgs::NORMAL);
     begin_frame_args.on_critical_path = true;
@@ -3303,16 +3236,14 @@
         FakeInputEvent(blink::WebInputEvent::kGestureScrollUpdate),
         InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
 
-    simulate_compositor_task_ran_ = false;
     compositor_task_runner_->PostTask(
         FROM_HERE,
-        base::BindOnce(
-            &MainThreadSchedulerImplTest::SimulateMainThreadCompositorTask,
-            base::Unretained(this), base::TimeDelta::FromMilliseconds(20)));
+        base::BindOnce(&MainThreadSchedulerImplTest::
+                           SimulateMainThreadCompositorAndQuitRunLoopTask,
+                       base::Unretained(this),
+                       base::TimeDelta::FromMilliseconds(20)));
 
-    mock_task_runner_->RunTasksWhile(base::BindRepeating(
-        &MainThreadSchedulerImplTest::SimulatedCompositorTaskPending,
-        base::Unretained(this)));
+    base::RunLoop().RunUntilIdle();
     EXPECT_EQ(UseCase::kSynchronizedGesture, CurrentUseCase()) << "i = " << i;
   }
 
@@ -3336,7 +3267,7 @@
 
   for (int i = 0; i < 100; i++) {
     viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
+        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
         base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
         viz::BeginFrameArgs::NORMAL);
     begin_frame_args.on_critical_path = true;
@@ -3345,16 +3276,14 @@
         FakeInputEvent(blink::WebInputEvent::kTouchMove),
         InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
 
-    simulate_compositor_task_ran_ = false;
     compositor_task_runner_->PostTask(
         FROM_HERE,
-        base::BindOnce(
-            &MainThreadSchedulerImplTest::SimulateMainThreadCompositorTask,
-            base::Unretained(this), base::TimeDelta::FromMilliseconds(20)));
+        base::BindOnce(&MainThreadSchedulerImplTest::
+                           SimulateMainThreadCompositorAndQuitRunLoopTask,
+                       base::Unretained(this),
+                       base::TimeDelta::FromMilliseconds(20)));
 
-    mock_task_runner_->RunTasksWhile(base::BindRepeating(
-        &MainThreadSchedulerImplTest::SimulatedCompositorTaskPending,
-        base::Unretained(this)));
+    base::RunLoop().RunUntilIdle();
     EXPECT_EQ(UseCase::kMainThreadCustomInputHandling, CurrentUseCase())
         << "i = " << i;
   }
@@ -3380,7 +3309,7 @@
 
   for (int i = 0; i < 100; i++) {
     viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
+        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
         base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
         viz::BeginFrameArgs::NORMAL);
     begin_frame_args.on_critical_path = true;
@@ -3389,16 +3318,14 @@
         FakeInputEvent(blink::WebInputEvent::kGestureScrollUpdate),
         InputEventState::EVENT_FORWARDED_TO_MAIN_THREAD);
 
-    simulate_compositor_task_ran_ = false;
     compositor_task_runner_->PostTask(
         FROM_HERE,
-        base::BindOnce(
-            &MainThreadSchedulerImplTest::SimulateMainThreadCompositorTask,
-            base::Unretained(this), base::TimeDelta::FromMilliseconds(20)));
+        base::BindOnce(&MainThreadSchedulerImplTest::
+                           SimulateMainThreadCompositorAndQuitRunLoopTask,
+                       base::Unretained(this),
+                       base::TimeDelta::FromMilliseconds(20)));
 
-    mock_task_runner_->RunTasksWhile(base::BindRepeating(
-        &MainThreadSchedulerImplTest::SimulatedCompositorTaskPending,
-        base::Unretained(this)));
+    base::RunLoop().RunUntilIdle();
     EXPECT_EQ(UseCase::kMainThreadGesture, CurrentUseCase()) << "i = " << i;
   }
 
@@ -3497,16 +3424,16 @@
   size_t timer_count = 0;
   size_t unthrottled_count = 0;
   timer_task_runner_->PostTask(
-      FROM_HERE, base::BindOnce(SlowCountingTask, &timer_count, &clock_, 7,
-                                timer_task_runner_));
+      FROM_HERE, base::BindOnce(SlowCountingTask, &timer_count,
+                                test_task_runner_, 7, timer_task_runner_));
   unthrottled_task_runner->PostTask(
-      FROM_HERE, base::BindOnce(SlowCountingTask, &unthrottled_count, &clock_,
-                                7, unthrottled_task_runner));
+      FROM_HERE, base::BindOnce(SlowCountingTask, &unthrottled_count,
+                                test_task_runner_, 7, unthrottled_task_runner));
   auto handle = scheduler_->PauseRenderer();
 
   for (int i = 0; i < 1000; i++) {
     viz::BeginFrameArgs begin_frame_args = viz::BeginFrameArgs::Create(
-        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, clock_.NowTicks(),
+        BEGINFRAME_FROM_HERE, 0, next_begin_frame_number_++, Now(),
         base::TimeTicks(), base::TimeDelta::FromMilliseconds(16),
         viz::BeginFrameArgs::NORMAL);
     begin_frame_args.on_critical_path = true;
@@ -3515,16 +3442,14 @@
         FakeInputEvent(blink::WebInputEvent::kGestureScrollUpdate),
         InputEventState::EVENT_CONSUMED_BY_COMPOSITOR);
 
-    simulate_compositor_task_ran_ = false;
     compositor_task_runner_->PostTask(
         FROM_HERE,
-        base::BindOnce(
-            &MainThreadSchedulerImplTest::SimulateMainThreadCompositorTask,
-            base::Unretained(this), base::TimeDelta::FromMilliseconds(10)));
+        base::BindOnce(&MainThreadSchedulerImplTest::
+                           SimulateMainThreadCompositorAndQuitRunLoopTask,
+                       base::Unretained(this),
+                       base::TimeDelta::FromMilliseconds(10)));
 
-    mock_task_runner_->RunTasksWhile(base::BindRepeating(
-        &MainThreadSchedulerImplTest::SimulatedCompositorTaskPending,
-        base::Unretained(this)));
+    base::RunLoop().RunUntilIdle();
     EXPECT_EQ(UseCase::kSynchronizedGesture, CurrentUseCase()) << "i = " << i;
   }
 
@@ -3721,43 +3646,39 @@
   EXPECT_TRUE(value);
 }
 
-void RecordingTimeTestTask(std::vector<base::TimeTicks>* run_times,
-                           base::SimpleTestTickClock* clock) {
-  run_times->push_back(clock->NowTicks());
+void RecordingTimeTestTask(
+    std::vector<base::TimeTicks>* run_times,
+    scoped_refptr<base::TestMockTimeTaskRunner> task_runner) {
+  run_times->push_back(task_runner->GetMockTickClock()->NowTicks());
 }
 
-// TODO(altimin@): Re-enable after splitting the timer policy into separate
-// policies.
 TEST_F(MainThreadSchedulerImplTest,
-       DISABLED_DefaultTimerTasksAreThrottledWhenBackgrounded) {
-  ScopedAutoAdvanceNowEnabler enable_auto_advance_now(mock_task_runner_);
-
-  scheduler_->SetRendererBackgrounded(true);
-
+       DefaultTimerTasksAreThrottledWhenBackgrounded) {
   std::vector<base::TimeTicks> run_times;
 
+  scheduler_->SetRendererBackgrounded(true);
   timer_task_runner_->PostTask(
-      FROM_HERE, base::BindOnce(&RecordingTimeTestTask, &run_times, &clock_));
+      FROM_HERE,
+      base::BindOnce(&RecordingTimeTestTask, &run_times, test_task_runner_));
 
-  mock_task_runner_->RunUntilTime(base::TimeTicks() +
-                                  base::TimeDelta::FromMilliseconds(1100));
-
+  test_task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(1100));
+  // It's expected to run every "absolute" second.
   EXPECT_THAT(run_times, testing::ElementsAre(base::TimeTicks() +
                                               base::TimeDelta::FromSeconds(1)));
   run_times.clear();
 
+  base::TimeTicks posting_time = Now();
   timer_task_runner_->PostDelayedTask(
-      FROM_HERE, base::BindOnce(&RecordingTimeTestTask, &run_times, &clock_),
+      FROM_HERE,
+      base::BindOnce(&RecordingTimeTestTask, &run_times, test_task_runner_),
       base::TimeDelta::FromMilliseconds(200));
 
   scheduler_->SetRendererBackgrounded(false);
 
-  mock_task_runner_->RunUntilTime(base::TimeTicks() +
-                                  base::TimeDelta::FromMilliseconds(1500));
-
+  test_task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(400));
   EXPECT_THAT(run_times,
-              testing::ElementsAre(base::TimeTicks() +
-                                   base::TimeDelta::FromMilliseconds(1300)));
+              testing::ElementsAre(posting_time +
+                                   base::TimeDelta::FromMilliseconds(200)));
 }
 
 //                  Nav Start     Nav Start            assert
@@ -3865,7 +3786,7 @@
   // tasks (L).
   std::vector<std::string> run_order;
   PostTestTasks(&run_order, "L1 L2 M1 L3 L4 M2 L5 L6");
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("M1"), std::string("M2"),
                                    std::string("L1"), std::string("L2"),
@@ -3880,14 +3801,14 @@
 
   scheduler_->OnPendingTasksChanged(true);
   EXPECT_CALL(*page_scheduler, RequestBeginMainFrameNotExpected(true)).Times(1);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   Mock::VerifyAndClearExpectations(page_scheduler.get());
 
   scheduler_->OnPendingTasksChanged(false);
   EXPECT_CALL(*page_scheduler, RequestBeginMainFrameNotExpected(false))
       .Times(1);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   Mock::VerifyAndClearExpectations(page_scheduler.get());
 }
@@ -3902,27 +3823,26 @@
   scheduler_->OnPendingTasksChanged(true);
   // Multiple calls should result in only one call.
   EXPECT_CALL(*page_scheduler, RequestBeginMainFrameNotExpected(true)).Times(1);
-  RunUntilIdle();
+  base::RunLoop().RunUntilIdle();
 
   Mock::VerifyAndClearExpectations(page_scheduler.get());
 }
 
 #if defined(OS_ANDROID)
 TEST_F(MainThreadSchedulerImplTest, PauseTimersForAndroidWebView) {
-  ScopedAutoAdvanceNowEnabler enable_auto_advance_now(mock_task_runner_);
   // Tasks in some queues don't fire when the timers are paused.
   std::vector<std::string> run_order;
   PostTestTasks(&run_order, "D1 C1 L1 I1 T1");
   scheduler_->PauseTimersForAndroidWebView();
   EnableIdleTasks();
-  RunUntilIdle();
+  test_task_runner_->FastForwardUntilNoTasksRemain();
   EXPECT_THAT(run_order,
               testing::ElementsAre(std::string("D1"), std::string("C1"),
                                    std::string("L1"), std::string("I1")));
   // The rest queued tasks fire when the timers are resumed.
   run_order.clear();
   scheduler_->ResumeTimersForAndroidWebView();
-  RunUntilIdle();
+  test_task_runner_->FastForwardUntilNoTasksRemain();
   EXPECT_THAT(run_order, testing::ElementsAre(std::string("T1")));
 }
 #endif  // defined(OS_ANDROID)
@@ -3931,15 +3851,10 @@
     : public MainThreadSchedulerImplTest {
  public:
   void SetUp() override {
-    if (!message_loop_) {
-      mock_task_runner_ =
-          base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(&clock_, false);
-    }
+    CreateTestTaskRunner();
     Initialize(std::make_unique<MainThreadSchedulerImplForTest>(
         base::sequence_manager::TaskQueueManagerForTest::Create(
-            message_loop_.get(),
-            message_loop_ ? message_loop_->task_runner() : mock_task_runner_,
-            &clock_),
+            nullptr, test_task_runner_, test_task_runner_->GetMockTickClock()),
         base::Time::FromJsTime(1000000.0)));
   }
 };
diff --git a/third_party/blink/renderer/platform/weborigin/security_origin.h b/third_party/blink/renderer/platform/weborigin/security_origin.h
index 7dc3420d..4101ef4 100644
--- a/third_party/blink/renderer/platform/weborigin/security_origin.h
+++ b/third_party/blink/renderer/platform/weborigin/security_origin.h
@@ -59,10 +59,6 @@
   // Creates a new opaque SecurityOrigin that is guaranteed to be cross-origin
   // to all currently existing SecurityOrigins.
   static scoped_refptr<SecurityOrigin> CreateUniqueOpaque();
-  // Deprecated alias for CreateOpaque().
-  static scoped_refptr<SecurityOrigin> CreateUnique() {
-    return CreateUniqueOpaque();
-  }
 
   static scoped_refptr<SecurityOrigin> CreateFromString(const String&);
   static scoped_refptr<SecurityOrigin> Create(const String& protocol,
diff --git a/third_party/blink/renderer/platform/wtf/math_extras.h b/third_party/blink/renderer/platform/wtf/math_extras.h
index d4667619..ac4a6f32 100644
--- a/third_party/blink/renderer/platform/wtf/math_extras.h
+++ b/third_party/blink/renderer/platform/wtf/math_extras.h
@@ -48,24 +48,23 @@
 #include <sys/types.h>
 #endif
 
-const double piDouble = M_PI;
-const float piFloat = static_cast<float>(M_PI);
+const double kPiDouble = M_PI;
+const float kPiFloat = static_cast<float>(M_PI);
 
-const double piOverTwoDouble = M_PI_2;
-const float piOverTwoFloat = static_cast<float>(M_PI_2);
+const double kPiOverTwoDouble = M_PI_2;
+const float kPiOverTwoFloat = static_cast<float>(M_PI_2);
 
-const double piOverFourDouble = M_PI_4;
-const float piOverFourFloat = static_cast<float>(M_PI_4);
+const double kPiOverFourDouble = M_PI_4;
+const float kPiOverFourFloat = static_cast<float>(M_PI_4);
 
-const double twoPiDouble = piDouble * 2.0;
-const float twoPiFloat = piFloat * 2.0f;
-
+const double kTwoPiDouble = kPiDouble * 2.0;
+const float kTwoPiFloat = kPiFloat * 2.0f;
 
 inline double deg2rad(double d) {
-  return d * piDouble / 180.0;
+  return d * kPiDouble / 180.0;
 }
 inline double rad2deg(double r) {
-  return r * 180.0 / piDouble;
+  return r * 180.0 / kPiDouble;
 }
 inline double deg2grad(double d) {
   return d * 400.0 / 360.0;
@@ -80,10 +79,10 @@
   return d / 360.0;
 }
 inline double rad2grad(double r) {
-  return r * 200.0 / piDouble;
+  return r * 200.0 / kPiDouble;
 }
 inline double grad2rad(double g) {
-  return g * piDouble / 200.0;
+  return g * kPiDouble / 200.0;
 }
 inline double turn2grad(double t) {
   return t * 400;
@@ -92,17 +91,17 @@
   return g / 400;
 }
 inline double rad2turn(double r) {
-  return r / twoPiDouble;
+  return r / kTwoPiDouble;
 }
 inline double turn2rad(double t) {
-  return t * twoPiDouble;
+  return t * kTwoPiDouble;
 }
 
 inline float deg2rad(float d) {
-  return d * piFloat / 180.0f;
+  return d * kPiFloat / 180.0f;
 }
 inline float rad2deg(float r) {
-  return r * 180.0f / piFloat;
+  return r * 180.0f / kPiFloat;
 }
 inline float deg2grad(float d) {
   return d * 400.0f / 360.0f;
@@ -117,10 +116,10 @@
   return d / 360.0f;
 }
 inline float rad2grad(float r) {
-  return r * 200.0f / piFloat;
+  return r * 200.0f / kPiFloat;
 }
 inline float grad2rad(float g) {
-  return g * piFloat / 200.0f;
+  return g * kPiFloat / 200.0f;
 }
 inline float turn2grad(float t) {
   return t * 400;
@@ -338,14 +337,6 @@
   return a && b ? a / greatestCommonDivisor(a, b) * b : 0;
 }
 
-#ifndef UINT64_C
-#if defined(COMPILER_MSVC)
-#define UINT64_C(c) c##ui64
-#else
-#define UINT64_C(c) c##ull
-#endif
-#endif
-
 // Calculate d % 2^{64}.
 inline void doubleToInteger(double d, unsigned long long& value) {
   if (std::isnan(d) || std::isinf(d)) {
diff --git a/third_party/blink/renderer/platform/wtf/text/wtf_string_test.cc b/third_party/blink/renderer/platform/wtf/text/wtf_string_test.cc
index 9a54ed0..b2a3af61 100644
--- a/third_party/blink/renderer/platform/wtf/text/wtf_string_test.cc
+++ b/third_party/blink/renderer/platform/wtf/text/wtf_string_test.cc
@@ -87,12 +87,12 @@
 
 TEST(StringTest, NumberToStringECMAScriptRegularNumbers) {
   // Pi.
-  TestNumberToStringECMAScript(piDouble, "3.141592653589793");
-  TestNumberToStringECMAScript(piFloat, "3.1415927410125732");
-  TestNumberToStringECMAScript(piOverTwoDouble, "1.5707963267948966");
-  TestNumberToStringECMAScript(piOverTwoFloat, "1.5707963705062866");
-  TestNumberToStringECMAScript(piOverFourDouble, "0.7853981633974483");
-  TestNumberToStringECMAScript(piOverFourFloat, "0.7853981852531433");
+  TestNumberToStringECMAScript(kPiDouble, "3.141592653589793");
+  TestNumberToStringECMAScript(kPiFloat, "3.1415927410125732");
+  TestNumberToStringECMAScript(kPiOverTwoDouble, "1.5707963267948966");
+  TestNumberToStringECMAScript(kPiOverTwoFloat, "1.5707963705062866");
+  TestNumberToStringECMAScript(kPiOverFourDouble, "0.7853981633974483");
+  TestNumberToStringECMAScript(kPiOverFourFloat, "0.7853981852531433");
 
   // e.
   const double kE = 2.71828182845904523536028747135266249775724709369995;
diff --git a/third_party/breakpad/BUILD.gn b/third_party/breakpad/BUILD.gn
index 902736d..58b96b5 100644
--- a/third_party/breakpad/BUILD.gn
+++ b/third_party/breakpad/BUILD.gn
@@ -59,6 +59,22 @@
   ldflags = [ "-Wl,--build-id=0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" ]
 }
 
+config("default_logging_severity_config") {
+  defines = [ "BPLOG_MINIMUM_SEVERITY=SEVERITY_ERROR" ]
+}
+
+config("fuzzing_logging_severity_config") {
+  defines = [ "BPLOG_MINIMUM_SEVERITY=SEVERITY_CRITICAL" ]
+}
+
+default_breakpad_configs = [ ":tools_config" ]
+
+if (use_fuzzing_engine) {
+  default_breakpad_configs += [ ":fuzzing_logging_severity_config" ]
+} else {
+  default_breakpad_configs += [ ":default_logging_severity_config" ]
+}
+
 # {micro,mini}dump_stackwalk and minidump_dump are tool-type executables
 # that do not build on Windows.
 if (!is_win) {
@@ -142,11 +158,9 @@
         "breakpad/src/third_party/libdisasm/x86_operand_list.h",
       ]
 
-      defines = [ "BPLOG_MINIMUM_SEVERITY=SEVERITY_ERROR" ]
-
       configs -= [ "//build/config/compiler:chromium_code" ]
       configs += [ "//build/config/compiler:no_chromium_code" ]
-      configs += [ ":tools_config" ]
+      configs += default_breakpad_configs
     }
 
     fuzzer_test("minidump_fuzzer") {
@@ -162,7 +176,7 @@
         "//base",
       ]
 
-      defines = [ "BPLOG_MINIMUM_SEVERITY=SEVERITY_CRITICAL" ]
+      additional_configs = [ ":fuzzing_logging_severity_config" ]
       include_dirs = [ "breakpad/src" ]
 
       libfuzzer_options = [
@@ -193,11 +207,9 @@
         ":stackwalk_common",
       ]
 
-      defines = [ "BPLOG_MINIMUM_SEVERITY=SEVERITY_ERROR" ]
-
       configs -= [ "//build/config/compiler:chromium_code" ]
       configs += [ "//build/config/compiler:no_chromium_code" ]
-      configs += [ ":tools_config" ]
+      configs += default_breakpad_configs
     }
 
     executable("minidump_stackwalk") {
@@ -212,11 +224,9 @@
         ":stackwalk_common",
       ]
 
-      defines = [ "BPLOG_MINIMUM_SEVERITY=SEVERITY_ERROR" ]
-
       configs -= [ "//build/config/compiler:chromium_code" ]
       configs += [ "//build/config/compiler:no_chromium_code" ]
-      configs += [ ":tools_config" ]
+      configs += default_breakpad_configs
 
       # Always want these files included regardless of platform.
       set_sources_assignment_filter([])
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 9f073b5..dd06ae1 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -1035,7 +1035,7 @@
     ],
 
     'asan_lsan_release_trybot': [
-      'asan', 'libfuzzer', 'lsan', 'release_trybot',
+      'asan', 'lsan', 'release_trybot',
     ],
 
     # Cast Linux takes very long in linking, possibly due to being on GCE
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 2cbc4e4..aff0127 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -893,6 +893,26 @@
   </summary>
 </histogram>
 
+<histogram name="Android.DeviceSize.LargestDisplaySize" units="dp">
+  <owner>twellington@chromium.org</owner>
+  <owner>tedchoc@chromium.org</owner>
+  <summary>
+    Records the largest display dimension in dp during deferred startup. The
+    display size is not affected by Android N multi-window mode. Clamped at
+    200dp to 1200dp.
+  </summary>
+</histogram>
+
+<histogram name="Android.DeviceSize.SmallestDisplaySize" units="dp">
+  <owner>twellington@chromium.org</owner>
+  <owner>tedchoc@chromium.org</owner>
+  <summary>
+    Records the smallest display dimension in dp during deferred startup. The
+    display size is not affected by Android N multi-window mode. Clamped at 0 to
+    1000dp.
+  </summary>
+</histogram>
+
 <histogram name="Android.Download.InfoBar.CloseButtonClicked"
     enum="DownloadInfoBarState">
   <owner>shaktisahu@chromium.org</owner>
@@ -1367,6 +1387,7 @@
 <histogram name="Android.MultiInstanceMigration.FailedToRenameMetadataFile"
     enum="Boolean">
   <owner>twellington@chromium.org</owner>
+  <owner>tedchoc@chromium.org</owner>
   <summary>
     Renaming the old tab metadata file failed during multi-instance migration.
     Only true is recorded.
@@ -1376,6 +1397,7 @@
 <histogram name="Android.MultiInstanceMigration.NewMetadataFileExists"
     enum="Boolean">
   <owner>twellington@chromium.org</owner>
+  <owner>tedchoc@chromium.org</owner>
   <summary>
     The new tab metadata file already existed when multi-instance migration was
     attempted. Only true is recorded.
@@ -1384,6 +1406,7 @@
 
 <histogram name="Android.MultiWindowMode.Active" enum="BooleanEnabled">
   <owner>twellington@chromium.org</owner>
+  <owner>tedchoc@chromium.org</owner>
   <summary>
     Records on every metrics upload whether the activity is running in Android N
     multi-window mode or not.
@@ -1393,6 +1416,7 @@
 <histogram name="Android.MultiWindowMode.IsTabletScreenWidthBelow600"
     enum="Boolean">
   <owner>twellington@chromium.org</owner>
+  <owner>tedchoc@chromium.org</owner>
   <summary>
     Records whether the screen width is below 600dp when the activity is in
     Android N multi-window mode. True if the screen width is less than 600dp and
@@ -1400,8 +1424,27 @@
   </summary>
 </histogram>
 
+<histogram name="Android.MultiWindowMode.ScreenHeight" units="dp">
+  <owner>twellington@chromium.org</owner>
+  <owner>tedchoc@chromium.org</owner>
+  <summary>
+    Records the screen height in dp when the activity is in Android N
+    multi-window mode. Clamped at 200dp to 1200dp.
+  </summary>
+</histogram>
+
+<histogram name="Android.MultiWindowMode.ScreenWidth" units="dp">
+  <owner>twellington@chromium.org</owner>
+  <owner>tedchoc@chromium.org</owner>
+  <summary>
+    Records the screen width in dp when the activity is in Android N
+    multi-window mode. Clamped at 200dp to 1200dp.
+  </summary>
+</histogram>
+
 <histogram name="Android.MultiWindowMode.TabletScreenWidth" units="dp">
   <owner>twellington@chromium.org</owner>
+  <owner>tedchoc@chromium.org</owner>
   <summary>
     Records the screen width in dp when the activity is in Android N
     multi-window mode and the width is below 600dp.
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py
index fb3616c..108c9989 100755
--- a/tools/perf/core/perf_data_generator.py
+++ b/tools/perf/core/perf_data_generator.py
@@ -372,58 +372,6 @@
       }
     ])
 
-  waterfall = add_tester(
-    waterfall, 'Mac 10.12 Perf', 'chromium-rel-mac12',
-    'mac',
-    swarming=[
-      {
-       'os': 'Mac-10.12',
-       'gpu': '8086:0a2e',
-       'pool': 'Chrome-perf',
-       'device_ids': [
-           'build158-m1', 'build159-m1', 'build160-m1',
-           'build161-m1', 'build162-m1'],
-       'perf_tests': [
-         ('net_perftests', 'build159-m1'),
-         ('views_perftests', 'build160-m1'),
-       ]
-      }
-    ])
-  waterfall = add_tester(
-    waterfall, 'Mac Pro 10.11 Perf',
-    'chromium-rel-mac11-pro', 'mac',
-    swarming=[
-      {
-       'gpu': '1002:6821',
-       'os': 'Mac-10.11',
-       'pool': 'chrome.tests.perf',
-       'device_ids': [
-           'build205-b7', 'build206-b7',
-           'build207-b7', 'build208-b7', 'build209-b7'
-          ],
-       'perf_tests': [
-         ('performance_browser_tests', 'build209-b7')
-       ]
-      }
-    ])
-  waterfall = add_tester(
-    waterfall, 'Mac Air 10.11 Perf',
-    'chromium-rel-mac11-air', 'mac',
-    swarming=[
-      {
-       'gpu': '8086:1626',
-       'os': 'Mac-10.11',
-       'pool': 'Chrome-perf',
-       'device_ids': [
-           'build123-b1', 'build124-b1',
-           'build125-b1', 'build126-b1', 'build127-b1'
-          ],
-       'perf_tests': [
-         ('performance_browser_tests', 'build126-b1')
-       ]
-      }
-    ])
-
   return waterfall
 
 
@@ -849,10 +797,28 @@
         emails, decorators.GetComponent(benchmark), False)
   return metadata
 
+# With migration to new recipe tests are now listed in the shard maps
+# that live in tools/perf/core.  We need to verify off of that list.
+def get_tests_in_performance_test_suite():
+  tests = sets.Set()
+  add_benchmarks_from_sharding_map(tests, "benchmark_desktop_bot_map.json")
+  add_benchmarks_from_sharding_map(tests, "benchmark_android_bot_map.json")
+  return tests
+
+
+def add_benchmarks_from_sharding_map(tests, shard_map_name):
+  path = os.path.join(os.path.dirname(__file__), shard_map_name)
+  if os.path.exists(path):
+    with open(path) as f:
+      sharding_map = json.load(f)
+    for _, benchmarks in sharding_map.iteritems():
+      for benchmark, _ in benchmarks['benchmarks'].iteritems():
+        tests.add(benchmark)
+
 
 def verify_all_tests_in_benchmark_csv(tests, benchmark_metadata):
   benchmark_names = sets.Set(benchmark_metadata)
-  test_names = sets.Set()
+  test_names = get_tests_in_performance_test_suite()
   for t in tests:
     scripts = []
     if 'isolated_scripts' in tests[t]:
@@ -970,36 +936,6 @@
 #     assumed to be true.
 NEW_PERF_RECIPE_FYI_TESTERS = {
   'testers' : {
-    'Mac 10.13 Laptop High End': {
-      'tests': [
-        {
-          'isolate': 'performance_test_suite',
-          'extra_args': [
-            '--run-ref-build',
-            '--test-shard-map-filename=benchmark_desktop_bot_map.json',
-          ],
-          'num_shards': 26
-        },
-        {
-          'isolate': 'net_perftests',
-          'num_shards': 1,
-          'telemetry': False,
-        },
-        {
-          'isolate': 'views_perftests',
-          'num_shards': 1,
-          'telemetry': False,
-        }
-      ],
-      'platform': 'mac',
-      'dimension': {
-        'pool': 'chrome.tests.perf-fyi',
-        'os': 'Mac-10.13',
-        'gpu': '1002:6821'
-      },
-      'device_ids': [
-      ],
-    },
     'One Buildbot Step Test Builder': {
       'tests': [
         {
@@ -1113,6 +1049,11 @@
           'isolate': 'load_library_perf_tests',
           'num_shards': 1,
           'telemetry': False,
+        },
+        {
+          'isolate': 'performance_browser_tests',
+          'num_shards': 1,
+          'telemetry': False,
         }
       ],
       'platform': 'mac',
@@ -1162,7 +1103,42 @@
         'pool': 'chrome.tests.perf',
       },
       'device_ids': [],
-    }
+    },
+    'mac-10_13_laptop_high_end-perf': {
+      'tests': [
+        {
+          'isolate': 'performance_test_suite',
+          'extra_args': [
+            '--run-ref-build',
+            '--test-shard-map-filename=benchmark_desktop_bot_map.json',
+          ],
+          'num_shards': 26
+        },
+        {
+          'isolate': 'net_perftests',
+          'num_shards': 1,
+          'telemetry': False,
+        },
+        {
+          'isolate': 'views_perftests',
+          'num_shards': 1,
+          'telemetry': False,
+        },
+        {
+          'isolate': 'media_perftests',
+          'num_shards': 1,
+          'telemetry': False,
+        }
+      ],
+      'platform': 'mac',
+      'dimension': {
+        'pool': 'chrome.tests.perf',
+        'os': 'Mac-10.13',
+        'gpu': '1002:6821'
+      },
+      'device_ids': [
+      ],
+    },
   }
 }
 def add_common_test_properties(test_entry, tester_config, test_spec):
diff --git a/tools/perf/core/perf_data_generator_unittest.py b/tools/perf/core/perf_data_generator_unittest.py
index 6cecc5e..41d92e5e 100644
--- a/tools/perf/core/perf_data_generator_unittest.py
+++ b/tools/perf/core/perf_data_generator_unittest.py
@@ -9,6 +9,7 @@
 from telemetry import benchmark
 
 import mock
+import json
 
 
 class PerfDataGeneratorTest(unittest.TestCase):
@@ -39,9 +40,16 @@
         'benchmark_name_3': BenchmarkMetadata('neo@matrix.org', None, False)
     }
 
-    # Mock out content of unowned_benchmarks.txt
+    # Mock out content of unowned_benchmarks.txt and sharding map
+    data = {
+      "0": {
+        "benchmarks": {
+            "benchmark_name_2": {}
+        }
+      }
+    }
     with mock.patch('__builtin__.open',
-                    mock.mock_open(read_data="benchmark_name_2")):
+                    mock.mock_open(read_data=json.dumps(data))):
       perf_data_generator.verify_all_tests_in_benchmark_csv(tests, benchmarks)
 
 
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config
index b306e44..6054bc6 100644
--- a/tools/perf/expectations.config
+++ b/tools/perf/expectations.config
@@ -122,6 +122,9 @@
 crbug.com/841931 [ Win ] rendering.desktop/gmail [ Skip ]
 crbug.com/750131 [ Win ] rendering.desktop/gmail_move [ Skip ]
 crbug.com/770904 [ Mac ] rendering.desktop/gmail_move [ Skip ]
+crbug.com/350692 [ All ] rendering.desktop/microsoft_performance [ Skip ]
+crbug.com/755556 [ Mac ] rendering.desktop/mix_blend_mode_animation_difference [ Skip ]
+crbug.com/755556 [ Mac ] rendering.desktop/mix_blend_mode_animation_hue [ Skip ]
 
 # Benchmark: rendering.mobile
 crbug.com/667432 [ All ] rendering.mobile/amazon [ Skip ]
@@ -146,6 +149,11 @@
 crbug.com/785286 [ Android_Webview ] rendering.mobile/effect_games [ Skip ]
 crbug.com/364248 [ Nexus_5 ] rendering.mobile/geo_apis [ Skip ]
 crbug.com/825234 [ Android_Webview ] rendering.mobile/bouncing_balls_shadow [ Skip ]
+crbug.com/350692 [ All ] rendering.mobile/microsoft_performance [ Skip ]
+crbug.com/755556 [ Android ] rendering.mobile/balls_css_key_frame_animations_composited_transform [ Skip ]
+crbug.com/829499 [ Android_One ] rendering.mobile/css_animations_many_keyframes [ Skip ]
+crbug.com/829499 [ Android_One ] rendering.mobile/web_animations_many_keyframes [ Skip ]
+crbug.com/840964 [ Nexus_5X ] rendering.mobile/web_animations_many_keyframes [ Skip ]
 
 # Benchmark: smoothness.gpu_rasterization.polymer
 [ All ] smoothness.gpu_rasterization.polymer/* [ Skip ] # Test needs to be modernized.
@@ -192,7 +200,7 @@
 crbug.com/822925 [ Android_Webview ] smoothness.pathological_mobile_sites/http://sports.yahoo.com/ [ Skip ]
 
 # Benchmark: smoothness.simple_mobile_sites
-crbug.com/750833 [ Android_Webview ] smoothness.simple_mobile_sites/https://www.flickr.com/ [ Skip ]
+crbug.com/750833 [ Android_Webview ] smoothness.simple_mobile_sites/flickr_scroll [ Skip ]
 
 # Benchmark: smoothness.sync_scroll.key_mobile_sites_smooth
 crbug.com/756119 [ All ] smoothness.sync_scroll.key_mobile_sites_smooth/digg [ Skip ]
diff --git a/tools/perf/page_sets/data/rendering_desktop.json b/tools/perf/page_sets/data/rendering_desktop.json
index 1d58ccd..17bfca4 100644
--- a/tools/perf/page_sets/data/rendering_desktop.json
+++ b/tools/perf/page_sets/data/rendering_desktop.json
@@ -170,6 +170,9 @@
         },
         "smash_cat": {
             "DEFAULT": "tough_canvas_cases_001.wprgo"
+	},
+	"microsoft_performance": {
+            "DEFAULT": "tough_animation_cases_000.wprgo"
         }
     },
     "description": "Describes the Web Page Replay archives for a story set. Don't edit by hand! Use record_wpr for updating.",
diff --git a/tools/perf/page_sets/data/rendering_mobile.json b/tools/perf/page_sets/data/rendering_mobile.json
index 7534fc1..65484d5 100644
--- a/tools/perf/page_sets/data/rendering_mobile.json
+++ b/tools/perf/page_sets/data/rendering_mobile.json
@@ -518,6 +518,9 @@
         },
         "smash_cat": {
             "DEFAULT": "tough_canvas_cases_001.wprgo"
+	},
+	"microsoft_performance": {
+            "DEFAULT": "tough_animation_cases_000.wprgo"
         }
     },
     "description": "Describes the Web Page Replay archives for a story set. Don't edit by hand! Use record_wpr for updating.",
diff --git a/tools/perf/page_sets/data/simple_mobile_sites.json b/tools/perf/page_sets/data/simple_mobile_sites.json
index bc34d83..187d7d3d 100644
--- a/tools/perf/page_sets/data/simple_mobile_sites.json
+++ b/tools/perf/page_sets/data/simple_mobile_sites.json
@@ -1,27 +1,18 @@
 {
     "archives": {
-        "http://m.nytimes.com/": {
+        "nytimes_scroll": {
             "DEFAULT": "simple_mobile_sites_002.wprgo"
         },
-        "http://m.us.wsj.com/": {
+        "ebay_scroll": {
             "DEFAULT": "simple_mobile_sites_002.wprgo"
         },
-        "http://www.apple.com/mac/": {
+        "nyc_gov_scroll": {
             "DEFAULT": "simple_mobile_sites_002.wprgo"
         },
-        "http://www.ebay.co.uk/": {
-            "DEFAULT": "simple_mobile_sites_002.wprgo"
-        },
-        "http://www.nyc.gov": {
-            "DEFAULT": "simple_mobile_sites_002.wprgo"
-        },
-        "https://www.flickr.com/": {
-            "DEFAULT": "simple_mobile_sites_002.wprgo"
-        },
-        "https://www.yahoo.com/": {
+        "flickr_scroll": {
             "DEFAULT": "simple_mobile_sites_002.wprgo"
         }
     },
     "description": "Describes the Web Page Replay archives for a story set. Don't edit by hand! Use record_wpr for updating.",
     "platform_specific": true
-}
\ No newline at end of file
+}
diff --git a/tools/perf/page_sets/rendering/tough_animation_cases.py b/tools/perf/page_sets/rendering/tough_animation_cases.py
new file mode 100644
index 0000000..88ecd43
--- /dev/null
+++ b/tools/perf/page_sets/rendering/tough_animation_cases.py
@@ -0,0 +1,663 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+from telemetry.page import shared_page_state
+from telemetry import story
+
+from page_sets.rendering import rendering_story
+
+
+class ToughAnimationPage(rendering_story.RenderingStory):
+  ABSTRACT_STORY = True
+  NEED_MEASUREMENT_READY = True
+
+  def __init__(self,
+               page_set,
+               shared_page_state_class,
+               name_suffix='',
+               extra_browser_args=None):
+    super(ToughAnimationPage, self).__init__(
+        page_set=page_set,
+        shared_page_state_class=shared_page_state_class,
+        name_suffix=name_suffix,
+        extra_browser_args=extra_browser_args)
+
+  def RunNavigateSteps(self, action_runner):
+    super(ToughAnimationPage, self).RunNavigateSteps(action_runner)
+    if self.NEED_MEASUREMENT_READY:
+      action_runner.WaitForJavaScriptCondition('window.measurementReady')
+
+  def RunPageInteractions(self, action_runner):
+    with action_runner.CreateInteraction('ToughAnimation'):
+      action_runner.Wait(10)
+
+
+class BallsSVGAnimationsPage(ToughAnimationPage):
+  """Why: Tests the balls animation implemented with SVG animations."""
+  BASE_NAME = 'balls_svg_animations'
+  URL = 'file://../tough_animation_cases/balls_svg_animations.html'
+
+
+class BallsJavascriptCanvasPage(ToughAnimationPage):
+  """Why: Tests the balls animation implemented with Javascript and canvas."""
+  BASE_NAME = 'balls_javascript_canvas'
+  URL = 'file://../tough_animation_cases/balls_javascript_canvas.html'
+
+
+class BallsJavascriptCssPage(ToughAnimationPage):
+  """Why: Tests the balls animation implemented with Javascript and CSS."""
+  BASE_NAME = 'balls_javascript_css'
+  URL = 'file://../tough_animation_cases/balls_javascript_css.html'
+
+
+class BallsCssKeyFrameAnimationsPage(ToughAnimationPage):
+  """Why: Tests the balls animation implemented with CSS keyframe animations."""
+  BASE_NAME = 'balls_css_key_frame_animations'
+  URL = 'file://../tough_animation_cases/balls_css_keyframe_animations.html'
+
+
+class BallsCssKeyFrameAnimationsCompositedPage(ToughAnimationPage):
+  """Why: Tests the balls animation implemented with transforms and CSS
+  keyframe animations to be run on the compositor thread.
+  """
+  BASE_NAME = 'balls_css_key_frame_animations_composited_transform'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/balls_css_keyframe_animations_composited_transform.html'
+
+
+class BallsCssTransition2PropertiesPage(ToughAnimationPage):
+  """Why: Tests the balls animation implemented with CSS transitions on 2
+  properties.
+  """
+  BASE_NAME = 'balls_css_transition_2_properties'
+  URL = 'file://../tough_animation_cases/balls_css_transition_2_properties.html'
+
+
+class BallsCssTransition40PropertiesPage(ToughAnimationPage):
+  """Why: Tests the balls animation implemented with CSS transitions on 40
+  properties.
+  """
+  BASE_NAME = 'balls_css_transition_40_properties'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/balls_css_transition_40_properties.html'
+
+
+class BallsCssTransitionAllPropertiesPage(ToughAnimationPage):
+  """Why: Tests the balls animation implemented with CSS transitions on all
+  animatable properties.
+  """
+  BASE_NAME = 'balls_css_transition_all_properties'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/balls_css_transition_all_properties.html'
+
+
+class OverlayBackgroundColorCssTransitionsPage(ToughAnimationPage):
+  BASE_NAME = 'overlay_background_color_css_transitions_page'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/overlay_background_color_css_transitions.html'
+
+
+class CssTransitionsNewElementPage(ToughAnimationPage):
+  """Why: Tests many CSS Transitions all starting at the same time triggered
+  by inserting new elements.
+  """
+  BASE_NAME = 'css_transitions_new_element'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_transitions_simultaneous_by_inserting_new_element.html?N=0316'
+
+
+class CssTransitionsStyleElementPage(ToughAnimationPage):
+  """Why: Tests many CSS Transitions all starting at the same time triggered
+  by inserting style sheets.
+  """
+  BASE_NAME = 'css_transitions_style_element'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_transitions_simultaneous_by_inserting_style_element.html?N=0316'
+
+
+class CssTransitionsUpdatingClassPage(ToughAnimationPage):
+  """Why: Tests many CSS Transitions all starting at the same time triggered
+  by updating class.
+  """
+  BASE_NAME = 'css_transitions_updating_class'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_transitions_simultaneous_by_updating_class.html?N=0316'
+
+
+class CssTransitionsInlineStylePage(ToughAnimationPage):
+  """Why: Tests many CSS Transitions all starting at the same time triggered
+  by updating inline style.
+  """
+  BASE_NAME = 'css_transitions_inline_style'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_transitions_simultaneous_by_updating_inline_style.html?N=0316'
+
+
+class CssTransitionsStaggeredNewElementPage(ToughAnimationPage):
+  """Why: Tests many CSS Transitions chained together using events at
+  different times triggered by inserting new elements.
+  """
+  BASE_NAME = 'css_transitions_staggered_new_element'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_transitions_staggered_chaining_by_inserting_new_element.html?N=0316'
+
+
+class CssTransitionsStaggeredStyleElementPage(ToughAnimationPage):
+  """Why: Tests many CSS Transitions chained together using events at
+  different times triggered by inserting style sheets.
+  """
+  BASE_NAME = 'css_transitions_staggered_style_element'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_transitions_staggered_chaining_by_inserting_style_element.html?N=0316'
+
+
+class CssTransitionsStaggeredUpdatingClassPage(ToughAnimationPage):
+  """Why: Tests many CSS Transitions chained together using events at
+  different times triggered by updating class.
+  """
+  BASE_NAME = 'css_transitions_staggered_updating_class'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_transitions_staggered_chaining_by_updating_class.html?N=0316'
+
+
+class CssTransitionsStaggeredInlineStylePage(ToughAnimationPage):
+  """Why: Tests many CSS Transitions chained together using events at
+  different times triggered by updating inline style.
+  """
+  BASE_NAME = 'css_transitions_staggered_inline_style'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_transitions_staggered_chaining_by_updating_inline_style.html?N=0316'
+
+
+class CssTransitionsTriggeredNewElementPage(ToughAnimationPage):
+  """Why: Tests many CSS Transitions starting at different times triggered by
+  inserting new elements.
+  """
+  BASE_NAME = 'css_transitions_triggered_new_element'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_transitions_staggered_triggering_by_inserting_new_element.html?N=0316'
+
+
+class CssTransitionsTriggeredStyleElementPage(ToughAnimationPage):
+  """Why: Tests many CSS Transitions starting at different times triggered by
+  inserting style sheets.
+  """
+  BASE_NAME = 'css_transitions_triggered_style_element'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_transitions_staggered_triggering_by_inserting_style_element.html?N=0316'
+
+
+class CssTransitionsTriggeredUpdatingClassPage(ToughAnimationPage):
+  """Why: Tests many CSS Transitions starting at different times triggered by
+  updating class.
+  """
+  BASE_NAME = 'css_transitions_triggered_updating_class'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_transitions_staggered_triggering_by_updating_class.html?N=0316'
+
+
+class CssTransitionsTriggeredInlineStylePage(ToughAnimationPage):
+  """Why: Tests many CSS Transitions starting at different times triggered by
+  updating inline style.
+  """
+  BASE_NAME = 'css_transitions_triggered_inline_style'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_transitions_staggered_triggering_by_updating_inline_style.html?N=0316'
+
+
+class CssAnimationsManyKeyframesPage(ToughAnimationPage):
+  """Why: Tests many CSS Animations all starting at the same time with 500
+  keyframes each.
+  """
+  BASE_NAME = 'css_animations_many_keyframes'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_animations_many_keyframes.html?N=0316'
+
+
+class CssAnimationsSimultaneousNewElementPage(ToughAnimationPage):
+  """Why: Tests many CSS Animations all starting at the same time triggered
+  by inserting new elements.
+  """
+  BASE_NAME = 'css_animations_simultaneous_new_element'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_animations_simultaneous_by_inserting_new_element.html?N=0316'
+
+
+class CssAnimationsSimultaneousStyleElementPage(ToughAnimationPage):
+  """Why: Tests many CSS Animations all starting at the same time triggered
+  by inserting style sheets.
+  """
+  BASE_NAME = 'css_animations_simultaneous_style_element'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_animations_simultaneous_by_inserting_style_element.html?N=0316'
+
+
+class CssAnimationsSimultaneousUpdatingClassPage(ToughAnimationPage):
+  """Why: Tests many CSS Animations all starting at the same time triggered
+  by updating class.
+  """
+  BASE_NAME = 'css_animations_simultaneous_updating_class'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_animations_simultaneous_by_updating_class.html?N=0316'
+
+
+class CssAnimationsSimultaneousInlineStylePage(ToughAnimationPage):
+  """Why: Tests many CSS Animations all starting at the same time triggered
+  by updating inline style.
+  """
+  BASE_NAME = 'css_animations_simultaneous_inline_style'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_animations_simultaneous_by_updating_inline_style.html?N=0316'
+
+
+class CssAnimationsStaggeredNewElementPage(ToughAnimationPage):
+  """Why: Tests many CSS Animations chained together using events at
+  different times triggered by inserting new elements.
+  """
+  BASE_NAME = 'css_animations_staggered_new_element'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_animations_staggered_chaining_by_inserting_new_element.html?N=0316'
+
+
+class CssAnimationsStaggeredStyleElementPage(ToughAnimationPage):
+  """Why: Tests many CSS Animations chained together using events at
+  different times triggered by inserting style sheets.
+  """
+  BASE_NAME = 'css_animations_staggered_style_element'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_animations_staggered_chaining_by_inserting_style_element.html?N=0316'
+
+
+class CssAnimationsStaggeredUpdatingClassPage(ToughAnimationPage):
+  """Why: Tests many CSS Animations chained together using events at
+  different times triggered by updating class.
+  """
+  BASE_NAME = 'css_animations_staggered_updating_class'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_animations_staggered_chaining_by_updating_class.html?N=0316'
+
+
+class CssAnimationsStaggeredInlineStylePage(ToughAnimationPage):
+  """Why: Tests many CSS Animations chained together using events at
+  different times triggered by updating inline style.
+  """
+  BASE_NAME = 'css_animations_staggered_inline_style'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_animations_staggered_chaining_by_updating_inline_style.html?N=0316'
+
+
+class CssAnimationsTriggeredNewElementPage(ToughAnimationPage):
+  """Why: Tests many CSS Animations starting at different times triggered by
+  inserting new elements.
+  """
+  BASE_NAME = 'css_animations_triggered_new_element'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_animations_staggered_triggering_by_inserting_new_element.html?N=0316'
+
+
+class CssAnimationsStaggeredInfinitePage(ToughAnimationPage):
+  """Why: Tests many CSS Animations all starting at the same time with
+  staggered animation offsets.
+  """
+  BASE_NAME = 'css_animations_staggered_infinite_iterations'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_animations_staggered_infinite_iterations.html?N=0316'
+
+
+class CssAnimationsTriggeredStyleElementPage(ToughAnimationPage):
+  """Why: Tests many CSS Animations starting at different times triggered by
+  inserting style sheets.
+  """
+  BASE_NAME = 'css_animations_triggered_style_element'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_animations_staggered_triggering_by_inserting_style_element.html?N=0316'
+
+
+class CssAnimationsTriggeredUpdatingClassPage(ToughAnimationPage):
+  """Why: Tests many CSS Animations starting at different times triggered by
+  updating class.
+  """
+  BASE_NAME = 'css_animations_triggered_updating_class'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_animations_staggered_triggering_by_updating_class.html?N=0316'
+
+
+class CssAnimationsTriggeredInlineStylePage(ToughAnimationPage):
+  """Why: Tests many CSS Animations starting at different times triggered by
+  updating inline style.
+  """
+  BASE_NAME = 'css_animations_triggered_inline_style'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_animations_staggered_triggering_by_updating_inline_style.html?N=0316'
+
+
+class WebAnimationsManyKeyframesPage(ToughAnimationPage):
+  """Why: Tests many Web Animations all starting at the same time with 500
+  keyframes each.
+  """
+  BASE_NAME = 'web_animations_many_keyframes'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/web_animations_many_keyframes.html?N=0316'
+
+
+class WebAnimationsSetCurrentTimePage(ToughAnimationPage):
+  """Why: Tests many paused Web Animations having their currentTimes updated
+  in every requestAnimationFrame.
+  """
+  BASE_NAME = 'web_animations_set_current_time'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/web_animations_set_current_time_in_raf.html?N=0316'
+
+
+class WebAnimationsSimultaneousPage(ToughAnimationPage):
+  """Why: Tests many Web Animations all starting at the same time."""
+  BASE_NAME = 'web_animations_simultaneous'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/web_animations_simultaneous.html?N=0316'
+
+
+class WebAnimationsStaggeredChainingPage(ToughAnimationPage):
+  """Why: Tests many Web Animations all starting at different times then
+  chained together using events.
+  """
+  BASE_NAME = 'web_animations_staggered_chaining'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/web_animations_staggered_chaining.html?N=0316'
+
+
+class WebAnimationStaggeredInfinitePage(ToughAnimationPage):
+  """Why: Tests many Web Animations all starting at different times with
+  infinite iterations.
+  """
+  BASE_NAME = 'web_animations_staggered_infinite_iterations'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/web_animations_staggered_infinite_iterations.html?N=0316'
+
+
+class WebAnimationsStaggeredTriggeringPage(ToughAnimationPage):
+  """Why: Tests many Web Animations all starting at different times."""
+  BASE_NAME = 'web_animations_staggered_triggering_page'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/web_animations_staggered_triggering.html?N=0316'
+
+
+class CssValueTypeColorPage(ToughAnimationPage):
+  """Why: Tests color animations using CSS Animations."""
+  BASE_NAME = 'css_value_type_color'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_value_type_color.html?api=css_animations&N=0316'
+
+
+class CssValueTypeFilterPage(ToughAnimationPage):
+  """Why: Tests filter animations using CSS Animations."""
+  BASE_NAME = 'css_value_type_filter'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_value_type_filter.html?api=css_animations&N=0316'
+
+
+class CssValueTypeLengthPage(ToughAnimationPage):
+  """Why: Tests length 3D animations using CSS Animations."""
+  BASE_NAME = 'css_value_type_length'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_value_type_length_3d.html?api=css_animations&N=0316'
+
+
+class CssValueTypeLengthComplexPage(ToughAnimationPage):
+  """Why: Tests complex length animations using CSS Animations."""
+  BASE_NAME = 'css_value_type_length_complex'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_value_type_length_complex.html?api=css_animations&N=0316'
+
+
+class CssValueTypeLengthSimplePage(ToughAnimationPage):
+  """Why: Tests simple length animations using CSS Animations."""
+  BASE_NAME = 'css_value_type_length_simple'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_value_type_length_simple.html?api=css_animations&N=0316'
+
+
+class CssValueTypePathPage(ToughAnimationPage):
+  """Why: Tests path animations using CSS Animations."""
+  BASE_NAME = 'css_value_type_path'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_value_type_path.html?api=css_animations&N=0316'
+
+
+class CssValueTypeShadowPage(ToughAnimationPage):
+  """Why: Tests shadow animations using CSS Animations."""
+  BASE_NAME = 'css_value_type_shadow'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_value_type_shadow.html?api=css_animations&N=0316'
+
+
+class CssValueTypeTransformComplexPage(ToughAnimationPage):
+  """Why: Tests complex transform animations using CSS Animations."""
+  BASE_NAME = 'css_value_type_transform_complex'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_value_type_transform_complex.html?api=css_animations&N=0316'
+
+
+class CssValueTypeTransformSimplePage(ToughAnimationPage):
+  """Why: Tests simple transform animations using CSS Animations."""
+  BASE_NAME = 'css_value_type_transform_simple'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_value_type_transform_simple.html?api=css_animations&N=0316'
+
+
+class WebAnimationValueTypeColorPage(ToughAnimationPage):
+  """Why: Tests color animations using Web Animations."""
+  BASE_NAME = 'web_animation_value_type_color'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_value_type_color.html?api=web_animations&N=0316'
+
+
+class WebAnimationValueTypeLength3dPage(ToughAnimationPage):
+  """Why: Tests length 3D animations using Web Animations."""
+  BASE_NAME = 'web_animation_value_type_length_3d'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_value_type_length_3d.html?api=web_animations&N=0316'
+
+
+class WebAnimationValueTypeLengthComplexPage(ToughAnimationPage):
+  """Why: Tests complex length animations using Web Animations."""
+  BASE_NAME = 'web_animation_value_type_length_complex'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_value_type_length_complex.html?api=web_animations&N=0316'
+
+
+class WebAnimationValueTypeLengthSimplePage(ToughAnimationPage):
+  """Why: Tests simple length animations using Web Animations."""
+  BASE_NAME = 'web_animation_value_type_length_simple'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_value_type_length_simple.html?api=web_animations&N=0316'
+
+
+class WebAnimationValueTypePathPage(ToughAnimationPage):
+  """Why: Tests path animations using Web Animations."""
+  BASE_NAME = 'web_animation_value_type_path'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_value_type_path.html?api=web_animations&N=0316'
+
+
+class WebAnimationValueTypeShadowPage(ToughAnimationPage):
+  """Why: Tests shadow animations using Web Animations."""
+  BASE_NAME = 'web_animation_value_type_shadow'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_value_type_shadow.html?api=web_animations&N=0316'
+
+
+class WebAnimationValueTypeTransformComplexPage(ToughAnimationPage):
+  """Why: Tests complex transform animations using Web Animations."""
+  BASE_NAME = 'web_animation_value_type_transform_complex'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_value_type_transform_complex.html?api=web_animations&N=0316'
+
+
+class WebAnimationValueTypeTransformSimplePage(ToughAnimationPage):
+  """Why: Tests simple transform animations using Web Animations."""
+  BASE_NAME = 'web_animation_value_type_transform_simple'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/css_value_type_transform_simple.html?api=web_animations&N=0316'
+
+
+class CompositorHeavyAnimationPage(ToughAnimationPage):
+  """Why: Test to update and then draw many times a large set of textures
+  to compare one-copy and zero-copy.
+  """
+  BASE_NAME = 'compositor_heavy_animation'
+  URL = 'file://../tough_animation_cases/compositor_heavy_animation.html?N=0200'
+
+
+class KeyframedAnimationsPage(ToughAnimationPage):
+  """Why: Tests various keyframed animations."""
+  BASE_NAME = 'keyframed_animations'
+  URL = 'file://../tough_animation_cases/keyframed_animations.html'
+  NEED_MEASUREMENT_READY = False
+
+
+class TransformTransitionsPage(ToughAnimationPage):
+  """Why: Tests various transitions."""
+  BASE_NAME = 'transform_transitions'
+  URL = 'file://../tough_animation_cases/transform_transitions.html'
+  NEED_MEASUREMENT_READY = False
+
+
+class TransformTransitionsJSBlockPage(ToughAnimationPage):
+  """Why: JS execution blocks CSS transition unless initial transform is set."""
+  BASE_NAME = 'transform_transitions_js_block'
+  URL = 'file://../tough_animation_cases/transform_transition_js_block.html'
+  NEED_MEASUREMENT_READY = False
+
+
+class MixBlendModeAnimationDifferencePage(ToughAnimationPage):
+  """Why: Tests animating elements having mix-blend-mode: difference (a
+  separable popular blend mode).
+  """
+  BASE_NAME = 'mix_blend_mode_animation_difference'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/mix_blend_mode_animation_difference.html'
+  NEED_MEASUREMENT_READY = False
+
+
+class MixBlendModeAnimationHuePage(ToughAnimationPage):
+  """Why: Tests animating elements having mix-blend-mode: hue (a
+  non-separable blend mode).
+  """
+  BASE_NAME = 'mix_blend_mode_animation_hue'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/mix_blend_mode_animation_hue.html'
+  NEED_MEASUREMENT_READY = False
+
+
+class MixBlendModeAnimationScreenPage(ToughAnimationPage):
+  """Why: Tests animating elements having mix-blend-mode: screen."""
+  BASE_NAME = 'mix_blend_mode_animation_screen'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/mix_blend_mode_animation_screen.html'
+  NEED_MEASUREMENT_READY = False
+
+
+class MixAnimationPropagatingIsolationPage(ToughAnimationPage):
+  """Why: Tests software-animating a deep DOM subtree having one blending
+  leaf.
+  """
+  BASE_NAME = 'mix_blend_mode_animation_propagating_isolation'
+  # pylint: disable=line-too-long
+  URL = 'file://../tough_animation_cases/mix_blend_mode_propagating_isolation.html'
+  NEED_MEASUREMENT_READY = False
+
+
+class MicrosoftPerformancePage(ToughAnimationPage):
+  """Why: Login page is slow because of ineffecient transform operations."""
+  BASE_NAME = 'microsoft_performance'
+  URL = 'http://ie.microsoft.com/testdrive/performance/robohornetpro/'
+  NEED_MEASUREMENT_READY = False
+
+
+# TODO(crbug.com/760553):remove this class after
+# smoothness.tough_animation_cases benchmark is completely
+# replaced by rendering benchmarks
+class ToughAnimationCasesPageSet(story.StorySet):
+
+  """
+  Description: A collection of animation performance tests
+  """
+
+  def __init__(self):
+    super(ToughAnimationCasesPageSet, self).__init__(
+      archive_data_file='../data/tough_animation_cases.json',
+      cloud_storage_bucket=story.PARTNER_BUCKET)
+
+    page_classes = [
+      BallsSVGAnimationsPage,
+      BallsJavascriptCanvasPage,
+      BallsJavascriptCssPage,
+      BallsCssKeyFrameAnimationsPage,
+      BallsCssKeyFrameAnimationsCompositedPage,
+      BallsCssTransition2PropertiesPage,
+      BallsCssTransition40PropertiesPage,
+      BallsCssTransitionAllPropertiesPage,
+      OverlayBackgroundColorCssTransitionsPage,
+      CssTransitionsNewElementPage,
+      CssTransitionsStyleElementPage,
+      CssTransitionsUpdatingClassPage,
+      CssTransitionsInlineStylePage,
+      CssTransitionsStaggeredNewElementPage,
+      CssTransitionsStaggeredStyleElementPage,
+      CssTransitionsStaggeredUpdatingClassPage,
+      CssTransitionsStaggeredInlineStylePage,
+      CssTransitionsTriggeredNewElementPage,
+      CssTransitionsTriggeredStyleElementPage,
+      CssTransitionsTriggeredUpdatingClassPage,
+      CssTransitionsTriggeredInlineStylePage,
+      CssAnimationsManyKeyframesPage,
+      CssAnimationsSimultaneousNewElementPage,
+      CssAnimationsSimultaneousStyleElementPage,
+      CssAnimationsSimultaneousInlineStylePage,
+      CssAnimationsSimultaneousUpdatingClassPage,
+      CssAnimationsStaggeredNewElementPage,
+      CssAnimationsStaggeredStyleElementPage,
+      CssAnimationsStaggeredUpdatingClassPage,
+      CssAnimationsStaggeredInlineStylePage,
+      CssAnimationsTriggeredNewElementPage,
+      CssAnimationsStaggeredInfinitePage,
+      CssAnimationsTriggeredStyleElementPage,
+      CssAnimationsTriggeredUpdatingClassPage,
+      CssAnimationsTriggeredInlineStylePage,
+      WebAnimationsManyKeyframesPage,
+      WebAnimationsSetCurrentTimePage,
+      WebAnimationsSimultaneousPage,
+      WebAnimationsStaggeredChainingPage,
+      WebAnimationStaggeredInfinitePage,
+      WebAnimationsStaggeredTriggeringPage,
+      CssValueTypeColorPage,
+      CssValueTypeFilterPage,
+      CssValueTypeLengthPage,
+      CssValueTypeLengthComplexPage,
+      CssValueTypeLengthSimplePage,
+      CssValueTypePathPage,
+      CssValueTypeShadowPage,
+      CssValueTypeTransformComplexPage,
+      CssValueTypeTransformSimplePage,
+      WebAnimationValueTypeColorPage,
+      WebAnimationValueTypeLength3dPage,
+      WebAnimationValueTypeLengthComplexPage,
+      WebAnimationValueTypeLengthSimplePage,
+      WebAnimationValueTypePathPage,
+      WebAnimationValueTypeShadowPage,
+      WebAnimationValueTypeTransformComplexPage,
+      WebAnimationValueTypeTransformSimplePage,
+      KeyframedAnimationsPage,
+      TransformTransitionsPage,
+      TransformTransitionsJSBlockPage,
+      MixBlendModeAnimationDifferencePage,
+      MixBlendModeAnimationHuePage,
+      MixBlendModeAnimationScreenPage,
+      MixAnimationPropagatingIsolationPage,
+      MicrosoftPerformancePage
+    ]
+
+    for page_class in page_classes:
+      self.AddStory(page_class(
+          page_set=self,
+          shared_page_state_class=shared_page_state.SharedPageState))
diff --git a/tools/perf/page_sets/simple_mobile_sites.py b/tools/perf/page_sets/simple_mobile_sites.py
index 805541a4..2aee4bd 100644
--- a/tools/perf/page_sets/simple_mobile_sites.py
+++ b/tools/perf/page_sets/simple_mobile_sites.py
@@ -6,25 +6,20 @@
 from telemetry import story
 
 
-class SimplePage(page_module.Page):
+class SimpleScrollPage(page_module.Page):
 
-  def __init__(self, url, page_set):
-    super(SimplePage, self).__init__(
+  def __init__(self, name, url, page_set):
+    super(SimpleScrollPage, self).__init__(
+        name=name,
         url=url,
         page_set=page_set,
-        shared_page_state_class=shared_page_state.Shared10InchTabletPageState,
-        name=url)
+        shared_page_state_class=shared_page_state.Shared10InchTabletPageState)
 
   def RunNavigateSteps(self, action_runner):
-    super(SimplePage, self).RunNavigateSteps(action_runner)
+    super(SimpleScrollPage, self).RunNavigateSteps(action_runner)
     # TODO(epenner): Remove this wait (http://crbug.com/366933)
     action_runner.Wait(5)
 
-class SimpleScrollPage(SimplePage):
-
-  def __init__(self, url, page_set):
-    super(SimpleScrollPage, self).__init__(url=url, page_set=page_set)
-
   def RunPageInteractions(self, action_runner):
     # Make the scroll longer to reduce noise.
     with action_runner.CreateGestureInteraction('ScrollAction'):
@@ -41,11 +36,13 @@
 
     scroll_page_list = [
       # Why: Scrolls moderately complex pages (up to 60 layers)
-      'http://www.ebay.co.uk/',
-      'https://www.flickr.com/',
-      'http://www.nyc.gov',
-      'http://m.nytimes.com/'
+      ('ebay_scroll', 'http://www.ebay.co.uk/'),
+      ('flickr_scroll', 'https://www.flickr.com/'),
+      ('nyc_gov_scroll', 'http://www.nyc.gov'),
+      ('nytimes_scroll', 'http://m.nytimes.com/')
     ]
 
-    for url in scroll_page_list:
-      self.AddStory(SimpleScrollPage(url, self))
+    for name,url in scroll_page_list:
+      self.AddStory(SimpleScrollPage(name=name,
+                                     url=url,
+                                     page_set=self))
diff --git a/tools/perf/page_sets/tough_animation_cases.py b/tools/perf/page_sets/tough_animation_cases.py
deleted file mode 100644
index 0ea0852..0000000
--- a/tools/perf/page_sets/tough_animation_cases.py
+++ /dev/null
@@ -1,344 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-from telemetry.page import page as page_module
-from telemetry import story
-
-
-class ToughAnimationCasesPage(page_module.Page):
-
-  def __init__(self, name, url, page_set, need_measurement_ready):
-    super(ToughAnimationCasesPage, self).__init__(
-        url=url, page_set=page_set, name=name)
-    self._need_measurement_ready = need_measurement_ready
-
-  def RunNavigateSteps(self, action_runner):
-    super(ToughAnimationCasesPage, self).RunNavigateSteps(action_runner)
-    if self._need_measurement_ready:
-      action_runner.WaitForJavaScriptCondition('window.measurementReady')
-
-  def RunPageInteractions(self, action_runner):
-    with action_runner.CreateInteraction('ToughAnimation'):
-      action_runner.Wait(10)
-
-class ToughAnimationCasesPageSet(story.StorySet):
-
-  """
-  Description: A collection of animation performance tests
-  """
-
-  def __init__(self):
-    super(ToughAnimationCasesPageSet, self).__init__(
-      archive_data_file='data/tough_animation_cases.json',
-      cloud_storage_bucket=story.PARTNER_BUCKET)
-
-    urls_list_one = [
-      # Why: Tests the balls animation implemented with SVG animations.
-      ('balls_svg_animations',
-       'file://tough_animation_cases/balls_svg_animations.html'),
-      # Why: Tests the balls animation implemented with Javascript and canvas.
-      ('balls_javascript_canvas',
-       'file://tough_animation_cases/balls_javascript_canvas.html'),
-      # Why: Tests the balls animation implemented with Javascript and CSS.
-      ('balls_javascript_css',
-       'file://tough_animation_cases/balls_javascript_css.html'),
-      # Why: Tests the balls animation implemented with CSS keyframe animations.
-      ('balls_css_key_frame_animations',
-       'file://tough_animation_cases/balls_css_keyframe_animations.html'),
-      # Why: Tests the balls animation implemented with transforms and CSS
-      # keyframe animations to be run on the compositor thread.
-      ('balls_css_key_frame_animations_composited_transform',
-       # pylint: disable=line-too-long
-      'file://tough_animation_cases/balls_css_keyframe_animations_composited_transform.html'),
-      # Why: Tests the balls animation implemented with CSS transitions on 2
-      # properties.
-      ('balls_css_transition_2_properties',
-       'file://tough_animation_cases/balls_css_transition_2_properties.html'),
-      # Why: Tests the balls animation implemented with CSS transitions on 40
-      # properties.
-      ('balls_css_transition_40_properties',
-       'file://tough_animation_cases/balls_css_transition_40_properties.html'),
-      # Why: Tests the balls animation implemented with CSS transitions on all
-      # animatable properties.
-      ('balls_css_transition_all_properties',
-       'file://tough_animation_cases/balls_css_transition_all_properties.html'),
-      ('overlay_background_color_css_transitions_page',
-       # pylint: disable=line-too-long
-      'file://tough_animation_cases/overlay_background_color_css_transitions.html'),
-
-      # Why: Tests many CSS Transitions all starting at the same time triggered
-      # by inserting new elements.
-      ('css_transitions_new_element',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_transitions_simultaneous_by_inserting_new_element.html?N=0316'),
-      # Why: Tests many CSS Transitions all starting at the same time triggered
-      # by inserting style sheets.
-      ('css_transitions_style_element',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_transitions_simultaneous_by_inserting_style_element.html?N=0316'),
-      # Why: Tests many CSS Transitions all starting at the same time triggered
-      # by updating class.
-      ('css_transitions_updating_class',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_transitions_simultaneous_by_updating_class.html?N=0316'),
-      # Why: Tests many CSS Transitions all starting at the same time triggered
-      # by updating inline style.
-      ('css_transitions_inline_style',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_transitions_simultaneous_by_updating_inline_style.html?N=0316'),
-      # Why: Tests many CSS Transitions chained together using events at
-      # different times triggered by inserting new elements.
-      ('css_transitions_staggered_new_element',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_transitions_staggered_chaining_by_inserting_new_element.html?N=0316'),
-      # Why: Tests many CSS Transitions chained together using events at
-      # different times triggered by inserting style sheets.
-      ('css_transitions_staggered_style_element',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_transitions_staggered_chaining_by_inserting_style_element.html?N=0316'),
-      # Why: Tests many CSS Transitions chained together using events at
-      # different times triggered by updating class.
-      ('css_transitions_staggered_updating_class',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_transitions_staggered_chaining_by_updating_class.html?N=0316'),
-      # Why: Tests many CSS Transitions chained together using events at
-      # different times triggered by updating inline style.
-      ('css_transitions_staggered_inline_style',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_transitions_staggered_chaining_by_updating_inline_style.html?N=0316'),
-      # Why: Tests many CSS Transitions starting at different times triggered by
-      # inserting new elements.
-      ('css_transitions_triggered_new_element',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_transitions_staggered_triggering_by_inserting_new_element.html?N=0316'),
-      # Why: Tests many CSS Transitions starting at different times triggered by
-      # inserting style sheets.
-      ('css_transitions_triggered_style_element',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_transitions_staggered_triggering_by_inserting_style_element.html?N=0316'),
-      # Why: Tests many CSS Transitions starting at different times triggered by
-      # updating class.
-      ('css_transitions_triggered_updating_class',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_transitions_staggered_triggering_by_updating_class.html?N=0316'),
-      # Why: Tests many CSS Transitions starting at different times triggered by
-      # updating inline style.
-      ('css_transitions_triggered_inline_style',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_transitions_staggered_triggering_by_updating_inline_style.html?N=0316'),
-
-      # Why: Tests many CSS Animations all starting at the same time with 500
-      # keyframes each.
-      ('css_animations_many_keyframes',
-       'file://tough_animation_cases/css_animations_many_keyframes.html?N=0316'),
-      # Why: Tests many CSS Animations all starting at the same time triggered
-      # by inserting new elements.
-      ('css_animations_simultaneous_new_element',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_animations_simultaneous_by_inserting_new_element.html?N=0316'),
-      # Why: Tests many CSS Animations all starting at the same time triggered
-      # by inserting style sheets.
-      ('css_animations_simultaneous_style_element',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_animations_simultaneous_by_inserting_style_element.html?N=0316'),
-      # Why: Tests many CSS Animations all starting at the same time triggered
-      # by updating class.
-      ('css_animations_simultaneous_updating_class',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_animations_simultaneous_by_updating_class.html?N=0316'),
-      # Why: Tests many CSS Animations all starting at the same time triggered
-      # by updating inline style.
-      ('css_animations_simultaneous_inline_style',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_animations_simultaneous_by_updating_inline_style.html?N=0316'),
-      # Why: Tests many CSS Animations chained together using events at
-      # different times triggered by inserting new elements.
-      ('css_animations_staggered_new_element',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_animations_staggered_chaining_by_inserting_new_element.html?N=0316'),
-      # Why: Tests many CSS Animations chained together using events at
-      # different times triggered by inserting style sheets.
-      ('css_animations_staggered_style_element',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_animations_staggered_chaining_by_inserting_style_element.html?N=0316'),
-      # Why: Tests many CSS Animations chained together using events at
-      # different times triggered by updating class.
-      ('css_animations_staggered_updating_class',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_animations_staggered_chaining_by_updating_class.html?N=0316'),
-      # Why: Tests many CSS Animations chained together using events at
-      # different times triggered by updating inline style.
-      ('css_animations_staggered_inline_style',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_animations_staggered_chaining_by_updating_inline_style.html?N=0316'),
-      # Why: Tests many CSS Animations starting at different times triggered by
-      # inserting new elements.
-      ('css_animations_triggered_new_element',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_animations_staggered_triggering_by_inserting_new_element.html?N=0316'),
-      # Why: Tests many CSS Animations all starting at the same time with
-      # staggered animation offsets.
-      ('css_animations_staggered_infinite_iterations',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_animations_staggered_infinite_iterations.html?N=0316'),
-      # Why: Tests many CSS Animations starting at different times triggered by
-      # inserting style sheets.
-      ('css_animations_triggered_style_element',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_animations_staggered_triggering_by_inserting_style_element.html?N=0316'),
-      # Why: Tests many CSS Animations starting at different times triggered by
-      # updating class.
-      ('css_animations_triggered_updating_class',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_animations_staggered_triggering_by_updating_class.html?N=0316'),
-      # Why: Tests many CSS Animations starting at different times triggered by
-      # updating inline style.
-      ('css_animations_triggered_inline_style',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_animations_staggered_triggering_by_updating_inline_style.html?N=0316'),
-
-      # Why: Tests many Web Animations all starting at the same time with 500
-      # keyframes each.
-      ('web_animations_many_keyframes',
-       'file://tough_animation_cases/web_animations_many_keyframes.html?N=0316'),
-      # Why: Tests many paused Web Animations having their currentTimes updated
-      # in every requestAnimationFrame.
-      ('web_animations_set_current_time',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/web_animations_set_current_time_in_raf.html?N=0316'),
-      # Why: Tests many Web Animations all starting at the same time.
-      ('web_animations_simultaneous',
-       'file://tough_animation_cases/web_animations_simultaneous.html?N=0316'),
-      # Why: Tests many Web Animations all starting at different times then
-      # chained together using events.
-      ('web_animations_staggered_chaining',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/web_animations_staggered_chaining.html?N=0316'),
-      # Why: Tests many Web Animations all starting at different times with
-      # infinite iterations.
-      ('web_animations_staggered_infinite_iterations',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/web_animations_staggered_infinite_iterations.html?N=0316'),
-      # Why: Tests many Web Animations all starting at different times.
-      ('web_animations_staggered_triggering_page',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/web_animations_staggered_triggering.html?N=0316'),
-
-      # Why: Tests color animations using CSS Animations.
-      ('css_value_type_color',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_value_type_color.html?api=css_animations&N=0316'),
-      # Why: Tests filter animations using CSS Animations.
-      ('css_value_type_filter',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_value_type_filter.html?api=css_animations&N=0316'),
-      # Why: Tests length 3D animations using CSS Animations.
-      ('css_value_type_length',
-        # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_value_type_length_3d.html?api=css_animations&N=0316'),
-      # Why: Tests complex length animations using CSS Animations.
-      ('css_value_type_length_complex',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_value_type_length_complex.html?api=css_animations&N=0316'),
-      # Why: Tests simple length animations using CSS Animations.
-      ('css_value_type_length_simple',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_value_type_length_simple.html?api=css_animations&N=0316'),
-      # Why: Tests path animations using CSS Animations.
-      ('css_value_type_path',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_value_type_path.html?api=css_animations&N=0316'),
-      # Why: Tests shadow animations using CSS Animations.
-      ('css_value_type_shadow',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_value_type_shadow.html?api=css_animations&N=0316'),
-      # Why: Tests complex transform animations using CSS Animations.
-      ('css_value_type_transform_complex',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_value_type_transform_complex.html?api=css_animations&N=0316'),
-      # Why: Tests simple transform animations using CSS Animations.
-      ('css_value_type_transform_simple',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_value_type_transform_simple.html?api=css_animations&N=0316'),
-
-      # Why: Tests color animations using Web Animations.
-      ('web_animation_value_type_color',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_value_type_color.html?api=web_animations&N=0316'),
-      # Why: Tests length 3D animations using Web Animations.
-      ('web_animation_value_type_length_3d',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_value_type_length_3d.html?api=web_animations&N=0316'),
-      # Why: Tests complex length animations using Web Animations.
-      ('web_animation_value_type_length_complex',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_value_type_length_complex.html?api=web_animations&N=0316'),
-      # Why: Tests simple length animations using Web Animations.
-      ('web_animation_value_type_length_simple',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_value_type_length_simple.html?api=web_animations&N=0316'),
-      # Why: Tests path animations using Web Animations.
-      ('web_animation_value_type_path',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_value_type_path.html?api=web_animations&N=0316'),
-      # Why: Tests shadow animations using Web Animations.
-      ('web_animation_value_type_shadow',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_value_type_shadow.html?api=web_animations&N=0316'),
-      # Why: Tests complex transform animations using Web Animations.
-      ('web_animation_value_type_transform_complex',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_value_type_transform_complex.html?api=web_animations&N=0316'),
-      # Why: Tests simple transform animations using Web Animations.
-      ('web_animation_value_type_transform_simple',
-       # pylint: disable=line-too-long
-       'file://tough_animation_cases/css_value_type_transform_simple.html?api=web_animations&N=0316'),
-
-      # Why: Test to update and then draw many times a large set of textures
-      # to compare one-copy and zero-copy.
-      ('compositor_heavy_animation',
-       'file://tough_animation_cases/compositor_heavy_animation.html?N=0200'),
-    ]
-
-    for name,url in urls_list_one:
-      self.AddStory(ToughAnimationCasesPage(name=name,
-                                            url=url,
-                                            page_set=self,
-                                            need_measurement_ready=True))
-
-    urls_list_two = [
-      # Why: Tests various keyframed animations.
-      ('keyframed_animations',
-       'file://tough_animation_cases/keyframed_animations.html'),
-      # Why: Tests various transitions.
-      ('transform_transitions',
-       'file://tough_animation_cases/transform_transitions.html'),
-      # Why: JS execution blocks CSS transition unless initial transform is set.
-      ('transform_transitions_js_block',
-       'file://tough_animation_cases/transform_transition_js_block.html'),
-      # Why: Tests animating elements having mix-blend-mode: difference (a
-      # separable popular blend mode).
-      ('mix_blend_mode_animation_difference',
-       'file://tough_animation_cases/mix_blend_mode_animation_difference.html'),
-      # Why: Tests animating elements having mix-blend-mode: hue (a
-      # non-separable blend mode).
-      ('mix_blend_mode_animation_hue',
-       'file://tough_animation_cases/mix_blend_mode_animation_hue.html'),
-      # Why: Tests animating elements having mix-blend-mode: screen.
-      ('mix_blend_mode_animation_screen',
-       'file://tough_animation_cases/mix_blend_mode_animation_screen.html'),
-      # Why: Tests software-animating a deep DOM subtree having one blending
-      # leaf.
-      ('mix_blend_mode_animation_propagating_isolation',
-       'file://tough_animation_cases/mix_blend_mode_propagating_isolation.html'),
-
-      # Why: Login page is slow because of ineffecient transform operations.
-      ('microsoft_performance',
-       'http://ie.microsoft.com/testdrive/performance/robohornetpro/'),
-    ]
-
-    for name,url in urls_list_two:
-      self.AddStory(ToughAnimationCasesPage(name=name,
-                                            url=url,
-                                            page_set=self,
-                                            need_measurement_ready=False))
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml
index 423126e..8e0bec7 100644
--- a/tools/traffic_annotation/summary/annotations.xml
+++ b/tools/traffic_annotation/summary/annotations.xml
@@ -165,6 +165,7 @@
  <item id="p2p_invalidator" hash_code="84201371" type="0" content_hash_code="117416248" os_list="linux,windows" file_path="components/invalidation/impl/p2p_invalidator.cc"/>
  <item id="parallel_download_job" hash_code="135118587" type="0" content_hash_code="105330419" os_list="linux,windows" file_path="components/download/internal/common/parallel_download_job.cc"/>
  <item id="password_protection_request" hash_code="66322287" type="0" content_hash_code="25596947" os_list="linux,windows" file_path="components/safe_browsing/password_protection/password_protection_request.cc"/>
+ <item id="password_requirements_spec_fetch" hash_code="69585116" type="0" content_hash_code="5591260" os_list="linux,windows" file_path="components/autofill/core/browser/password_requirements_spec_fetcher.cc"/>
  <item id="payment_instrument_icon_fetcher" hash_code="73309970" type="0" deprecated="2017-09-16" content_hash_code="84709873" file_path=""/>
  <item id="payment_manifest_downloader" hash_code="84045030" type="0" content_hash_code="19293316" os_list="linux,windows" file_path="components/payments/core/payment_manifest_downloader.cc"/>
  <item id="payments_sync_cards" hash_code="95588446" type="0" content_hash_code="56526513" os_list="linux,windows" file_path="components/autofill/core/browser/payments/payments_client.cc"/>
diff --git a/ui/message_center/BUILD.gn b/ui/message_center/BUILD.gn
index e7b7e35..29764da5 100644
--- a/ui/message_center/BUILD.gn
+++ b/ui/message_center/BUILD.gn
@@ -18,6 +18,7 @@
     "notification_expand_more.icon",
     "notification_inline_reply.icon",
     "notification_settings_button.icon",
+    "notification_snooze_button.icon",
     "product.icon",
   ]
 }
diff --git a/ui/message_center/public/cpp/notification.h b/ui/message_center/public/cpp/notification.h
index bbe62a4..b0a6f95 100644
--- a/ui/message_center/public/cpp/notification.h
+++ b/ui/message_center/public/cpp/notification.h
@@ -178,6 +178,9 @@
   // crbug.com/780342
   SettingsButtonHandler settings_button_handler = SettingsButtonHandler::NONE;
 
+  // Controls whether a snooze button should appear on the notification.
+  bool should_show_snooze_button = false;
+
   FullscreenVisibility fullscreen_visibility = FullscreenVisibility::NONE;
 };
 
@@ -401,6 +404,10 @@
            SettingsButtonHandler::NONE;
   }
 
+  bool should_show_snooze_button() const {
+    return optional_fields_.should_show_snooze_button;
+  }
+
   FullscreenVisibility fullscreen_visibility() const {
     return optional_fields_.fullscreen_visibility;
   }
diff --git a/ui/message_center/vector_icons/notification_snooze_button.icon b/ui/message_center/vector_icons/notification_snooze_button.icon
new file mode 100644
index 0000000..a62c3b42
--- /dev/null
+++ b/ui/message_center/vector_icons/notification_snooze_button.icon
@@ -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.
+
+// Converted from the svg files attached in http://crbug.com/840497.
+
+CANVAS_DIMENSIONS, 24,
+MOVE_TO, 11.99f, 2,
+ARC_TO, 10, 10, 0, 1, 0, 12, 21.99f,
+ARC_TO, 10, 10, 0, 0, 0, 11.99f, 2,
+CLOSE,
+MOVE_TO, 12, 20,
+R_ARC_TO, 8, 8, 0, 1, 1, 0, -16,
+R_ARC_TO, 8, 8, 0, 0, 1, 0, 16,
+CLOSE,
+MOVE_TO, 12.5f, 7,
+H_LINE_TO, 11,
+R_V_LINE_TO, 6,
+R_LINE_TO, 5.25f, 3.15f,
+R_LINE_TO, 0.75f, -1.23f,
+R_LINE_TO, -4.5f, -2.67f,
+CLOSE
+
+CANVAS_DIMENSIONS, 12,
+MOVE_TO, 6, 1,
+R_ARC_TO, 5, 5, 0, 0, 0, -5, 5,
+R_ARC_TO, 5, 5, 0, 0, 0, 5, 5,
+R_ARC_TO, 5, 5, 0, 0, 0, 5, -5,
+R_ARC_TO, 5, 5, 0, 0, 0, -5, -5,
+CLOSE,
+R_MOVE_TO, 0, 9,
+R_ARC_TO, 4, 4, 0, 1, 1, 0, -8,
+R_ARC_TO, 4, 4, 0, 0, 1, 0, 8,
+CLOSE,
+MOVE_TO, 6.25f, 3.5f,
+H_LINE_TO, 5.5f,
+R_V_LINE_TO, 3,
+R_LINE_TO, 2.63f, 1.57f,
+R_LINE_TO, 0.37f, -0.61f,
+R_LINE_TO, -2.25f, -1.34f,
+CLOSE
+
diff --git a/ui/message_center/views/message_view.cc b/ui/message_center/views/message_view.cc
index 50065af..80201b6 100644
--- a/ui/message_center/views/message_view.cc
+++ b/ui/message_center/views/message_view.cc
@@ -128,7 +128,11 @@
 }
 
 void MessageView::SetIsNested() {
+  DCHECK(!is_nested_) << "MessageView::SetIsNested() is called twice wrongly.";
+
   is_nested_ = true;
+  // Update enability since it might be changed by "is_nested" flag.
+  slide_out_controller_.set_enabled(!GetPinned());
 
   if (ShouldRoundMessageViewCorners()) {
     SetBorder(views::CreateRoundedRectBorder(
@@ -353,6 +357,10 @@
   MessageCenter::Get()->ClickOnSettingsButton(notification_id_);
 }
 
+void MessageView::OnSnoozeButtonPressed(const ui::Event& event) {
+  // No default implementation for snooze.
+}
+
 void MessageView::SetDrawBackgroundAsActive(bool active) {
   background_view_->background()->
       SetNativeControlColor(active ? kHoveredButtonBackgroundColor :
diff --git a/ui/message_center/views/message_view.h b/ui/message_center/views/message_view.h
index 687fa64..9807673 100644
--- a/ui/message_center/views/message_view.h
+++ b/ui/message_center/views/message_view.h
@@ -77,6 +77,7 @@
 
   void OnCloseButtonPressed();
   virtual void OnSettingsButtonPressed(const ui::Event& event);
+  virtual void OnSnoozeButtonPressed(const ui::Event& event);
 
   // views::View
   void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
diff --git a/ui/message_center/views/notification_control_buttons_view.cc b/ui/message_center/views/notification_control_buttons_view.cc
index bf1dae5..7695460 100644
--- a/ui/message_center/views/notification_control_buttons_view.cc
+++ b/ui/message_center/views/notification_control_buttons_view.cc
@@ -70,8 +70,8 @@
         views::CreateSolidBackground(SK_ColorTRANSPARENT));
 
     // Add the button at the last.
-    DCHECK_LE(child_count(), 1);
     AddChildView(close_button_.get());
+    Layout();
   } else if (!show && close_button_) {
     DCHECK(Contains(close_button_.get()));
     close_button_.reset();
@@ -93,15 +93,40 @@
     settings_button_->SetBackground(
         views::CreateSolidBackground(SK_ColorTRANSPARENT));
 
-    // Add the button at the first.
-    DCHECK_LE(child_count(), 1);
-    AddChildViewAt(settings_button_.get(), 0);
+    // Add the button next right to the snooze button.
+    int position = snooze_button_ ? 1 : 0;
+    AddChildViewAt(settings_button_.get(), position);
+    Layout();
   } else if (!show && settings_button_) {
     DCHECK(Contains(settings_button_.get()));
     settings_button_.reset();
   }
 }
 
+void NotificationControlButtonsView::ShowSnoozeButton(bool show) {
+  if (show && !snooze_button_) {
+    snooze_button_ = std::make_unique<PaddedButton>(this);
+    snooze_button_->set_owned_by_client();
+    snooze_button_->SetImage(
+        views::Button::STATE_NORMAL,
+        gfx::CreateVectorIcon(kNotificationSnoozeButtonIcon,
+                              gfx::kChromeIconGrey));
+    snooze_button_->SetAccessibleName(l10n_util::GetStringUTF16(
+        IDS_MESSAGE_NOTIFICATION_SETTINGS_BUTTON_ACCESSIBLE_NAME));
+    snooze_button_->SetTooltipText(l10n_util::GetStringUTF16(
+        IDS_MESSAGE_NOTIFICATION_SETTINGS_BUTTON_ACCESSIBLE_NAME));
+    snooze_button_->SetBackground(
+        views::CreateSolidBackground(SK_ColorTRANSPARENT));
+
+    // Add the button at the first.
+    AddChildViewAt(snooze_button_.get(), 0);
+    Layout();
+  } else if (!show && snooze_button_) {
+    DCHECK(Contains(snooze_button_.get()));
+    snooze_button_.reset();
+  }
+}
+
 void NotificationControlButtonsView::SetBackgroundColor(
     const SkColor& target_bgcolor) {
   DCHECK(background());
@@ -146,6 +171,10 @@
   return settings_button_.get();
 }
 
+views::Button* NotificationControlButtonsView::snooze_button() const {
+  return snooze_button_.get();
+}
+
 const char* NotificationControlButtonsView::GetClassName() const {
   return kViewClassName;
 }
@@ -156,6 +185,8 @@
     message_view_->OnCloseButtonPressed();
   } else if (settings_button_ && sender == settings_button_.get()) {
     message_view_->OnSettingsButtonPressed(event);
+  } else if (snooze_button_ && sender == snooze_button_.get()) {
+    message_view_->OnSnoozeButtonPressed(event);
   }
 }
 
diff --git a/ui/message_center/views/notification_control_buttons_view.h b/ui/message_center/views/notification_control_buttons_view.h
index 176221e..1140eaca 100644
--- a/ui/message_center/views/notification_control_buttons_view.h
+++ b/ui/message_center/views/notification_control_buttons_view.h
@@ -44,6 +44,9 @@
   void ShowCloseButton(bool show);
   // Change the visibility of the settings button. True to show, false to hide.
   void ShowSettingsButton(bool show);
+  // Change the visibility of the settings button. True to show, false to hide.
+  // Default: hidden.
+  void ShowSnoozeButton(bool show);
 
   // Set the background color of the view.
   void SetBackgroundColor(const SkColor& target_bgcolor);
@@ -61,6 +64,7 @@
   // Methods for retrieving the control buttons directly.
   views::Button* close_button() const;
   views::Button* settings_button() const;
+  views::Button* snooze_button() const;
 
   // views::View
   const char* GetClassName() const override;
@@ -79,6 +83,7 @@
 
   std::unique_ptr<PaddedButton> close_button_;
   std::unique_ptr<PaddedButton> settings_button_;
+  std::unique_ptr<PaddedButton> snooze_button_;
 
   std::unique_ptr<gfx::LinearAnimation> bgcolor_animation_;
   SkColor bgcolor_origin_;
diff --git a/ui/message_center/views/notification_view_md.cc b/ui/message_center/views/notification_view_md.cc
index 32ef294..873e5177 100644
--- a/ui/message_center/views/notification_view_md.cc
+++ b/ui/message_center/views/notification_view_md.cc
@@ -757,6 +757,8 @@
     const Notification& notification) {
   control_buttons_view_->ShowSettingsButton(
       notification.should_show_settings_button());
+  control_buttons_view_->ShowSnoozeButton(
+      notification.should_show_snooze_button());
   control_buttons_view_->ShowCloseButton(!GetPinned());
   UpdateControlButtonsVisibility();
 }
diff --git a/ui/message_center/views/notification_view_md_unittest.cc b/ui/message_center/views/notification_view_md_unittest.cc
index 5226ba1..bff78cc 100644
--- a/ui/message_center/views/notification_view_md_unittest.cc
+++ b/ui/message_center/views/notification_view_md_unittest.cc
@@ -33,6 +33,8 @@
 // Used to fill bitmaps returned by CreateBitmap().
 static const SkColor kBitmapColor = SK_ColorGREEN;
 
+constexpr char kDefaultNotificationId[] = "notification id";
+
 class NotificationTestDelegate : public NotificationDelegate {
  public:
   NotificationTestDelegate() = default;
@@ -98,22 +100,22 @@
   NotificationViewMD* notification_view() const {
     return notification_view_.get();
   }
-  Notification* notification() const { return notification_.get(); }
   views::Widget* widget() const {
     DCHECK_EQ(widget_, notification_view()->GetWidget());
     return widget_;
   }
 
  protected:
-  const gfx::Image CreateTestImage(int width, int height);
-  const SkBitmap CreateBitmap(int width, int height);
+  const gfx::Image CreateTestImage(int width, int height) const;
+  const SkBitmap CreateBitmap(int width, int height) const;
   std::vector<ButtonInfo> CreateButtons(int number);
+  std::unique_ptr<Notification> CreateSimpleNotification() const;
 
   // Paints |view| and returns the size that the original image (which must have
   // been created by CreateBitmap()) was scaled to.
   gfx::Size GetImagePaintSize(ProportionalImageView* view);
 
-  void UpdateNotificationViews();
+  void UpdateNotificationViews(const Notification& notification);
   float GetNotificationSlideAmount() const;
   bool IsRemoved(const std::string& notification_id) const;
   void DispatchGesture(const ui::GestureEventDetails& details);
@@ -124,8 +126,6 @@
 
   std::set<std::string> removed_ids_;
   scoped_refptr<NotificationTestDelegate> delegate_;
-  std::unique_ptr<RichNotificationData> data_;
-  std::unique_ptr<Notification> notification_;
   std::unique_ptr<NotificationViewMD> notification_view_;
   views::Widget* widget_;
 
@@ -136,6 +136,22 @@
 NotificationViewMDTest::NotificationViewMDTest() = default;
 NotificationViewMDTest::~NotificationViewMDTest() = default;
 
+std::unique_ptr<Notification> NotificationViewMDTest::CreateSimpleNotification()
+    const {
+  RichNotificationData data;
+  data.settings_button_handler = SettingsButtonHandler::INLINE;
+
+  std::unique_ptr<Notification> notification = std::make_unique<Notification>(
+      NOTIFICATION_TYPE_BASE_FORMAT, std::string(kDefaultNotificationId),
+      base::UTF8ToUTF16("title"), base::UTF8ToUTF16("message"),
+      CreateTestImage(80, 80), base::UTF8ToUTF16("display source"), GURL(),
+      NotifierId(NotifierId::APPLICATION, "extension_id"), data, delegate_);
+  notification->set_small_image(CreateTestImage(16, 16));
+  notification->set_image(CreateTestImage(320, 240));
+
+  return notification;
+}
+
 void NotificationViewMDTest::SetUp() {
   views::ViewsTestBase::SetUp();
 
@@ -143,35 +159,9 @@
 
   // Create a dummy notification.
   delegate_ = new NotificationTestDelegate();
-  data_.reset(new RichNotificationData());
-  data_->settings_button_handler = SettingsButtonHandler::INLINE;
-  notification_.reset(new Notification(
-      NOTIFICATION_TYPE_BASE_FORMAT, std::string("notification id"),
-      base::UTF8ToUTF16("title"), base::UTF8ToUTF16("message"),
-      CreateTestImage(80, 80), base::UTF8ToUTF16("display source"), GURL(),
-      NotifierId(NotifierId::APPLICATION, "extension_id"), *data_, delegate_));
-  notification_->set_small_image(CreateTestImage(16, 16));
-  notification_->set_image(CreateTestImage(320, 240));
 
-  // Then create a new NotificationView with that single notification.
-  // In the actual code path, this is instantiated by
-  // MessageViewFactory::Create.
-  // TODO(tetsui): Confirm that NotificationViewMD options are same as one
-  // created by the method.
-  notification_view_.reset(new NotificationViewMD(*notification_));
-  notification_view_->AddObserver(this);
-  notification_view_->SetIsNested();
-  notification_view_->set_owned_by_client();
-
-  views::Widget::InitParams init_params(
-      CreateParams(views::Widget::InitParams::TYPE_POPUP));
-  widget_ = new views::Widget();
-  widget_->Init(init_params);
-  widget_->SetContentsView(notification_view_.get());
-  widget_->SetSize(notification_view_->GetPreferredSize());
-  widget_->Show();
-  widget_->widget_delegate()->set_can_activate(true);
-  widget_->Activate();
+  std::unique_ptr<Notification> notification = CreateSimpleNotification();
+  UpdateNotificationViews(*notification);
 }
 
 void NotificationViewMDTest::TearDown() {
@@ -190,11 +180,12 @@
 }
 
 const gfx::Image NotificationViewMDTest::CreateTestImage(int width,
-                                                         int height) {
+                                                         int height) const {
   return gfx::Image::CreateFrom1xBitmap(CreateBitmap(width, height));
 }
 
-const SkBitmap NotificationViewMDTest::CreateBitmap(int width, int height) {
+const SkBitmap NotificationViewMDTest::CreateBitmap(int width,
+                                                    int height) const {
   SkBitmap bitmap;
   bitmap.allocN32Pixels(width, height);
   bitmap.eraseColor(kBitmapColor);
@@ -243,10 +234,34 @@
   return rect.size();
 }
 
-void NotificationViewMDTest::UpdateNotificationViews() {
+void NotificationViewMDTest::UpdateNotificationViews(
+    const Notification& notification) {
   MessageCenter::Get()->AddNotification(
-      std::make_unique<Notification>(*notification()));
-  notification_view()->UpdateWithNotification(*notification());
+      std::make_unique<Notification>(notification));
+
+  if (!notification_view_) {
+    // Then create a new NotificationView with that single notification.
+    // In the actual code path, this is instantiated by
+    // MessageViewFactory::Create.
+    // TODO(tetsui): Confirm that NotificationViewMD options are same as one
+    // created by the method.
+    notification_view_ = std::make_unique<NotificationViewMD>(notification);
+    notification_view_->AddObserver(this);
+    notification_view_->SetIsNested();
+    notification_view_->set_owned_by_client();
+
+    views::Widget::InitParams init_params(
+        CreateParams(views::Widget::InitParams::TYPE_POPUP));
+    widget_ = new views::Widget();
+    widget_->Init(init_params);
+    widget_->SetContentsView(notification_view_.get());
+    widget_->SetSize(notification_view_->GetPreferredSize());
+    widget_->Show();
+    widget_->widget_delegate()->set_can_activate(true);
+    widget_->Activate();
+  } else {
+    notification_view_->UpdateWithNotification(notification);
+  }
 }
 
 float NotificationViewMDTest::GetNotificationSlideAmount() const {
@@ -301,12 +316,13 @@
   EXPECT_NE(nullptr, notification_view()->icon_view_);
   EXPECT_NE(nullptr, notification_view()->image_container_view_);
 
-  notification()->set_image(gfx::Image());
-  notification()->set_title(base::string16());
-  notification()->set_message(base::string16());
-  notification()->set_icon(gfx::Image());
+  std::unique_ptr<Notification> notification = CreateSimpleNotification();
+  notification->set_image(gfx::Image());
+  notification->set_title(base::string16());
+  notification->set_message(base::string16());
+  notification->set_icon(gfx::Image());
 
-  notification_view()->CreateOrUpdateViews(*notification());
+  notification_view()->CreateOrUpdateViews(*notification);
 
   EXPECT_EQ(nullptr, notification_view()->title_view_);
   EXPECT_EQ(nullptr, notification_view()->message_view_);
@@ -318,42 +334,44 @@
   // TODO(tetsui): Remove duplicated integer literal in CreateOrUpdateIconView.
   const int kNotificationIconSize = 36;
 
-  notification()->set_type(NOTIFICATION_TYPE_SIMPLE);
+  std::unique_ptr<Notification> notification = CreateSimpleNotification();
+  notification->set_type(NOTIFICATION_TYPE_SIMPLE);
   ProportionalImageView* view = notification_view()->icon_view_;
 
   // Icons smaller than the maximum size should remain unscaled.
-  notification()->set_icon(
+  notification->set_icon(
       CreateTestImage(kNotificationIconSize / 2, kNotificationIconSize / 4));
-  UpdateNotificationViews();
+  UpdateNotificationViews(*notification);
   EXPECT_EQ(gfx::Size(kNotificationIconSize / 2, kNotificationIconSize / 4)
                 .ToString(),
             GetImagePaintSize(view).ToString());
 
   // Icons of exactly the intended icon size should remain unscaled.
-  notification()->set_icon(
+  notification->set_icon(
       CreateTestImage(kNotificationIconSize, kNotificationIconSize));
-  UpdateNotificationViews();
+  UpdateNotificationViews(*notification);
   EXPECT_EQ(gfx::Size(kNotificationIconSize, kNotificationIconSize).ToString(),
             GetImagePaintSize(view).ToString());
 
   // Icons over the maximum size should be scaled down, maintaining proportions.
-  notification()->set_icon(
+  notification->set_icon(
       CreateTestImage(2 * kNotificationIconSize, 2 * kNotificationIconSize));
-  UpdateNotificationViews();
+  UpdateNotificationViews(*notification);
   EXPECT_EQ(gfx::Size(kNotificationIconSize, kNotificationIconSize).ToString(),
             GetImagePaintSize(view).ToString());
 
-  notification()->set_icon(
+  notification->set_icon(
       CreateTestImage(4 * kNotificationIconSize, 2 * kNotificationIconSize));
-  UpdateNotificationViews();
+  UpdateNotificationViews(*notification);
   EXPECT_EQ(
       gfx::Size(kNotificationIconSize, kNotificationIconSize / 2).ToString(),
       GetImagePaintSize(view).ToString());
 }
 
 TEST_F(NotificationViewMDTest, UpdateButtonsStateTest) {
-  notification()->set_buttons(CreateButtons(2));
-  notification_view()->CreateOrUpdateViews(*notification());
+  std::unique_ptr<Notification> notification = CreateSimpleNotification();
+  notification->set_buttons(CreateButtons(2));
+  notification_view()->CreateOrUpdateViews(*notification);
   widget()->Show();
 
   // Action buttons are hidden by collapsed state.
@@ -376,7 +394,7 @@
   EXPECT_EQ(views::Button::STATE_HOVERED,
             notification_view()->action_buttons_[0]->state());
 
-  notification_view()->CreateOrUpdateViews(*notification());
+  notification_view()->CreateOrUpdateViews(*notification);
 
   EXPECT_EQ(views::Button::STATE_HOVERED,
             notification_view()->action_buttons_[0]->state());
@@ -393,8 +411,9 @@
 }
 
 TEST_F(NotificationViewMDTest, UpdateButtonCountTest) {
-  notification()->set_buttons(CreateButtons(2));
-  UpdateNotificationViews();
+  std::unique_ptr<Notification> notification = CreateSimpleNotification();
+  notification->set_buttons(CreateButtons(2));
+  UpdateNotificationViews(*notification);
   widget()->Show();
 
   // Action buttons are hidden by collapsed state.
@@ -423,8 +442,8 @@
   EXPECT_EQ(views::Button::STATE_NORMAL,
             notification_view()->action_buttons_[1]->state());
 
-  notification()->set_buttons(CreateButtons(1));
-  UpdateNotificationViews();
+  notification->set_buttons(CreateButtons(1));
+  UpdateNotificationViews(*notification);
 
   EXPECT_EQ(views::Button::STATE_HOVERED,
             notification_view()->action_buttons_[0]->state());
@@ -442,10 +461,11 @@
 }
 
 TEST_F(NotificationViewMDTest, TestActionButtonClick) {
+  std::unique_ptr<Notification> notification = CreateSimpleNotification();
   delegate_->set_expecting_button_click(true);
 
-  notification()->set_buttons(CreateButtons(2));
-  UpdateNotificationViews();
+  notification->set_buttons(CreateButtons(2));
+  UpdateNotificationViews(*notification);
   widget()->Show();
 
   ui::test::EventGenerator generator(widget()->GetNativeWindow());
@@ -467,12 +487,13 @@
 }
 
 TEST_F(NotificationViewMDTest, TestInlineReply) {
+  std::unique_ptr<Notification> notification = CreateSimpleNotification();
   delegate_->set_expecting_reply_submission(true);
 
   std::vector<ButtonInfo> buttons = CreateButtons(2);
   buttons[1].placeholder = base::string16();
-  notification()->set_buttons(buttons);
-  UpdateNotificationViews();
+  notification->set_buttons(buttons);
+  UpdateNotificationViews(*notification);
   widget()->Show();
 
   ui::test::EventGenerator generator(widget()->GetNativeWindow());
@@ -557,47 +578,42 @@
   ui::ScopedAnimationDurationScaleMode zero_duration_scope(
       ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
 
-  UpdateNotificationViews();
-  std::string notification_id = notification()->id();
+  EXPECT_FALSE(IsRemoved(kDefaultNotificationId));
 
   BeginScroll();
   ScrollBy(-10);
-  EXPECT_FALSE(IsRemoved(notification_id));
+  EXPECT_FALSE(IsRemoved(kDefaultNotificationId));
   EXPECT_EQ(-10.f, GetNotificationSlideAmount());
   EndScroll();
-  EXPECT_FALSE(IsRemoved(notification_id));
+  EXPECT_FALSE(IsRemoved(kDefaultNotificationId));
   EXPECT_EQ(0.f, GetNotificationSlideAmount());
 
   BeginScroll();
   ScrollBy(-200);
-  EXPECT_FALSE(IsRemoved(notification_id));
+  EXPECT_FALSE(IsRemoved(kDefaultNotificationId));
   EXPECT_EQ(-200.f, GetNotificationSlideAmount());
   EndScroll();
-  EXPECT_TRUE(IsRemoved(notification_id));
+  EXPECT_TRUE(IsRemoved(kDefaultNotificationId));
 }
 
 TEST_F(NotificationViewMDTest, SlideOutNested) {
   ui::ScopedAnimationDurationScaleMode zero_duration_scope(
       ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
 
-  UpdateNotificationViews();
-  notification_view()->SetIsNested();
-  std::string notification_id = notification()->id();
-
   BeginScroll();
   ScrollBy(-10);
-  EXPECT_FALSE(IsRemoved(notification_id));
+  EXPECT_FALSE(IsRemoved(kDefaultNotificationId));
   EXPECT_EQ(-10.f, GetNotificationSlideAmount());
   EndScroll();
-  EXPECT_FALSE(IsRemoved(notification_id));
+  EXPECT_FALSE(IsRemoved(kDefaultNotificationId));
   EXPECT_EQ(0.f, GetNotificationSlideAmount());
 
   BeginScroll();
   ScrollBy(-200);
-  EXPECT_FALSE(IsRemoved(notification_id));
+  EXPECT_FALSE(IsRemoved(kDefaultNotificationId));
   EXPECT_EQ(-200.f, GetNotificationSlideAmount());
   EndScroll();
-  EXPECT_TRUE(IsRemoved(notification_id));
+  EXPECT_TRUE(IsRemoved(kDefaultNotificationId));
 }
 
 // Pinning notification is ChromeOS only feature.
@@ -607,55 +623,78 @@
   ui::ScopedAnimationDurationScaleMode zero_duration_scope(
       ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
 
-  notification()->set_pinned(true);
-  UpdateNotificationViews();
-  std::string notification_id = notification()->id();
+  std::unique_ptr<Notification> notification = CreateSimpleNotification();
+  notification->set_pinned(true);
+  UpdateNotificationViews(*notification);
 
   BeginScroll();
   ScrollBy(-200);
-  EXPECT_FALSE(IsRemoved(notification_id));
+  EXPECT_FALSE(IsRemoved(kDefaultNotificationId));
   EXPECT_LT(-200.f, GetNotificationSlideAmount());
   EndScroll();
-  EXPECT_FALSE(IsRemoved(notification_id));
+  EXPECT_FALSE(IsRemoved(kDefaultNotificationId));
 }
 
 TEST_F(NotificationViewMDTest, Pinned) {
+  std::unique_ptr<Notification> notification = CreateSimpleNotification();
+
   // Visible at the initial state.
   EXPECT_TRUE(GetCloseButton());
   EXPECT_TRUE(GetCloseButton()->visible());
 
   // Pin.
-  notification()->set_pinned(true);
-  UpdateNotificationViews();
+  notification->set_pinned(true);
+  UpdateNotificationViews(*notification);
   EXPECT_FALSE(GetCloseButton());
 
   // Unpin.
-  notification()->set_pinned(false);
-  UpdateNotificationViews();
+  notification->set_pinned(false);
+  UpdateNotificationViews(*notification);
   EXPECT_TRUE(GetCloseButton());
   EXPECT_TRUE(GetCloseButton()->visible());
 
   // Pin again.
-  notification()->set_pinned(true);
-  UpdateNotificationViews();
+  notification->set_pinned(true);
+  UpdateNotificationViews(*notification);
   EXPECT_FALSE(GetCloseButton());
 }
 
+TEST_F(NotificationViewMDTest, SnoozeButton) {
+  // Create notification to replace the current one with itself.
+  message_center::RichNotificationData rich_data;
+  rich_data.settings_button_handler = SettingsButtonHandler::INLINE;
+  rich_data.pinned = true;
+  rich_data.should_show_snooze_button = true;
+  std::unique_ptr<Notification> notification = std::make_unique<Notification>(
+      message_center::NOTIFICATION_TYPE_CUSTOM, kDefaultNotificationId,
+      base::UTF8ToUTF16("title"), base::UTF8ToUTF16("message"), gfx::Image(),
+      base::UTF8ToUTF16("display source"), GURL(),
+      message_center::NotifierId(message_center::NotifierId::ARC_APPLICATION,
+                                 "test_app_id"),
+      rich_data, nullptr);
+
+  UpdateNotificationViews(*notification);
+
+  EXPECT_NE(nullptr,
+            notification_view()->GetControlButtonsView()->snooze_button());
+}
+
 #endif  // defined(OS_CHROMEOS)
 
 TEST_F(NotificationViewMDTest, ExpandLongMessage) {
-  notification()->set_type(NotificationType::NOTIFICATION_TYPE_SIMPLE);
+  std::unique_ptr<Notification> notification = CreateSimpleNotification();
+  notification->set_type(NotificationType::NOTIFICATION_TYPE_SIMPLE);
   // Test in a case where left_content_ does not have views other than
   // message_view_.
   // Without doing this, inappropriate fix such as
   // message_view_->GetPreferredSize() returning gfx::Size() can pass.
-  notification()->set_title(base::string16());
-  notification()->set_message(base::ASCIIToUTF16(
+  notification->set_title(base::string16());
+  notification->set_message(base::ASCIIToUTF16(
       "consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore "
       "et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud "
       "exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."));
 
-  UpdateNotificationViews();
+  UpdateNotificationViews(*notification);
   EXPECT_FALSE(notification_view()->expanded_);
   const int collapsed_height = notification_view()->message_view_->height();
   const int collapsed_preferred_height =
@@ -694,8 +733,9 @@
   constexpr SkColor kActionButtonTextColor = gfx::kGoogleBlue700;
   constexpr SkColor kCustomAccentColor = gfx::kGoogleYellow900;
 
-  notification()->set_buttons(CreateButtons(2));
-  UpdateNotificationViews();
+  std::unique_ptr<Notification> notification = CreateSimpleNotification();
+  notification->set_buttons(CreateButtons(2));
+  UpdateNotificationViews(*notification);
   widget()->Show();
 
   // Action buttons are hidden by collapsed state.
@@ -716,8 +756,8 @@
 
   // If custom accent color is set, the header and the buttons should have the
   // same accent color.
-  notification()->set_accent_color(kCustomAccentColor);
-  UpdateNotificationViews();
+  notification->set_accent_color(kCustomAccentColor);
+  UpdateNotificationViews(*notification);
   EXPECT_EQ(kCustomAccentColor,
             notification_view()->header_row_->accent_color_for_testing());
   EXPECT_EQ(
@@ -732,12 +772,13 @@
   // TODO(tetsui): Remove duplicated integer literal in CreateOrUpdateIconView.
   const int kNotificationIconSize = 30;
 
-  notification()->set_type(NotificationType::NOTIFICATION_TYPE_IMAGE);
-  notification()->set_icon(
+  std::unique_ptr<Notification> notification = CreateSimpleNotification();
+  notification->set_type(NotificationType::NOTIFICATION_TYPE_IMAGE);
+  notification->set_icon(
       CreateTestImage(kNotificationIconSize, kNotificationIconSize));
 
   // Test normal notification.
-  UpdateNotificationViews();
+  UpdateNotificationViews(*notification);
   EXPECT_FALSE(notification_view()->expanded_);
   EXPECT_TRUE(notification_view()->icon_view_->visible());
   EXPECT_TRUE(notification_view()->right_content_->visible());
@@ -752,8 +793,8 @@
   EXPECT_FALSE(notification_view()->expanded_);
 
   // Test notification with |use_image_for_icon| e.g. screenshot preview.
-  notification()->set_icon(gfx::Image());
-  UpdateNotificationViews();
+  notification->set_icon(gfx::Image());
+  UpdateNotificationViews(*notification);
   EXPECT_TRUE(notification_view()->icon_view_->visible());
   EXPECT_TRUE(notification_view()->right_content_->visible());
 
@@ -765,9 +806,10 @@
 }
 
 TEST_F(NotificationViewMDTest, NotificationWithoutIcon) {
-  notification()->set_icon(gfx::Image());
-  notification()->set_image(gfx::Image());
-  UpdateNotificationViews();
+  std::unique_ptr<Notification> notification = CreateSimpleNotification();
+  notification->set_icon(gfx::Image());
+  notification->set_image(gfx::Image());
+  UpdateNotificationViews(*notification);
 
   // If the notification has no icon, |icon_view_| shouldn't be created.
   EXPECT_FALSE(notification_view()->icon_view_);
@@ -780,8 +822,9 @@
 }
 
 TEST_F(NotificationViewMDTest, InlineSettings) {
-  notification()->set_type(NOTIFICATION_TYPE_SIMPLE);
-  UpdateNotificationViews();
+  std::unique_ptr<Notification> notification = CreateSimpleNotification();
+  notification->set_type(NOTIFICATION_TYPE_SIMPLE);
+  UpdateNotificationViews(*notification);
 
   // Inline settings will be shown by clicking settings button.
   EXPECT_FALSE(notification_view()->settings_row_->visible());
diff --git a/ui/message_center/views/notification_view_unittest.cc b/ui/message_center/views/notification_view_unittest.cc
index 583b2a7..8a5890a 100644
--- a/ui/message_center/views/notification_view_unittest.cc
+++ b/ui/message_center/views/notification_view_unittest.cc
@@ -644,7 +644,6 @@
       ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
 
   UpdateNotificationViews();
-  notification_view()->SetIsNested();
   std::string notification_id = notification()->id();
 
   BeginScroll();
diff --git a/ui/webui/resources/cr_elements/BUILD.gn b/ui/webui/resources/cr_elements/BUILD.gn
index 4914a0d..664e3c3 100644
--- a/ui/webui/resources/cr_elements/BUILD.gn
+++ b/ui/webui/resources/cr_elements/BUILD.gn
@@ -14,7 +14,6 @@
     "cr_dialog:closure_compile",
     "cr_drawer:closure_compile",
     "cr_expand_button:closure_compile",
-    "cr_input:closure_compile",
     "cr_link_row:closure_compile",
     "cr_profile_avatar_selector:closure_compile",
     "cr_radio_button:closure_compile",
diff --git a/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html b/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html
index 9ccc6cc..09e909e 100644
--- a/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html
+++ b/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html
@@ -99,7 +99,7 @@
         box-sizing: border-box;
         display: flex;
         flex-direction: column;
-        min-height: 60px; /* Minimum reasonably usable height. */
+        min-height: 1.375rem; /* Minimum reasonably usable height. */
         overflow: auto;
 
         @apply --cr-dialog-body-container;
diff --git a/ui/webui/resources/cr_elements/cr_input/cr_input.html b/ui/webui/resources/cr_elements/cr_input/cr_input.html
index ce54984c..6b3d132 100644
--- a/ui/webui/resources/cr_elements/cr_input/cr_input.html
+++ b/ui/webui/resources/cr_elements/cr_input/cr_input.html
@@ -27,7 +27,7 @@
         margin-top: 8px;
       }
 
-      :host(:focus-within:not([readonly]):not([invalid])) #label {
+      :host(:focus-within) #label {
         color: var(--cr-input-focus-color);
       }
 
@@ -50,7 +50,6 @@
         box-sizing: border-box;
         caret-color: var(--cr-input-focus-color);
         color: inherit;
-        font-size: inherit;
         line-height: inherit;
         outline: none;
         padding: 6px 8px;
@@ -65,10 +64,6 @@
         caret-color: var(--cr-input-error-color);
       }
 
-      :host([readonly]) input {
-        opacity: 0.6;
-      }
-
       /* Underline styling below. */
       #underline {
         border-bottom: 2px solid var(--cr-input-focus-color);
@@ -88,7 +83,7 @@
       }
 
       :host([invalid]) #underline,
-      :host(:focus-within:not([readonly])) #underline {
+      :host(:focus-within) #underline {
         opacity: 1;
         transition: width 180ms ease-out, opacity 120ms ease-in;
         width: 100%;
@@ -118,12 +113,8 @@
     </style>
     <div id="label" hidden="[[!label]]">[[label]]</div>
     <div id="input-container">
-      <!-- Only attributes that are named inconsistently between html and js
-           need to use attr$="", such as |tabindex| vs .tabIndex and |readonly|
-           vs .readOnly. -->
       <input id="input" disabled="[[disabled]]" autofocus="[[autofocus]]"
-          value="{{value::input}}" tabindex$="[[tabIndex]]" type="[[type]]"
-          readonly$="[[readonly]]">
+          value="{{value::input}}" tabindex$="[[tabIndex]]">
       <div id="underline"></div>
     </div>
     <div id="error">[[errorMessage]]</div>
diff --git a/ui/webui/resources/cr_elements/cr_input/cr_input.js b/ui/webui/resources/cr_elements/cr_input/cr_input.js
index 0305876..2810bf9a 100644
--- a/ui/webui/resources/cr_elements/cr_input/cr_input.js
+++ b/ui/webui/resources/cr_elements/cr_input/cr_input.js
@@ -43,15 +43,8 @@
       observer: 'placeholderChanged_',
     },
 
-    readonly: Boolean,
-
     tabIndex: String,
 
-    type: {
-      type: String,
-      value: 'text',  // Only 'text' and 'password' are currently supported.
-    },
-
     value: {
       type: String,
       value: '',
@@ -68,16 +61,10 @@
     'input.change': 'onInputChange_',
   },
 
-  /** @return {!HTMLInputElement} */
-  get inputElement() {
-    return this.$.input;
-  },
-
   /** @private */
   disabledChanged_: function() {
     this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
-    // In case input was focused when disabled changes.
-    this.inputElement.blur();
+    this.$.input.blur();  // In case input was focused when disabled changes.
   },
 
   /**
@@ -88,14 +75,9 @@
    */
   placeholderChanged_: function() {
     if (this.placeholder || this.placeholder == '')
-      this.inputElement.setAttribute('placeholder', this.placeholder);
+      this.$.input.setAttribute('placeholder', this.placeholder);
     else
-      this.inputElement.removeAttribute('placeholder');
-  },
-
-  focus: function() {
-    if (this.shadowRoot.activeElement != this.inputElement)
-      this.inputElement.focus();
+      this.$.input.removeAttribute('placeholder');
   },
 
   /**
@@ -107,5 +89,5 @@
    */
   onInputChange_: function(e) {
     this.fire('change', {sourceEvent: e});
-  },
+  }
 });
\ No newline at end of file
diff --git a/ui/webui/resources/cr_elements/shared_style_css.html b/ui/webui/resources/cr_elements/shared_style_css.html
index 28cabebb..eb7a18f 100644
--- a/ui/webui/resources/cr_elements/shared_style_css.html
+++ b/ui/webui/resources/cr_elements/shared_style_css.html
@@ -70,6 +70,12 @@
       #cr-container-shadow.has-shadow {
         opacity: var(--cr-container-shadow-max-opacity);
       }
+
+      /* Pre-allocate space for paper-input-error, which is absolutely
+       * positioned, to avoid any scrollbars from showing up. */
+      cr-dialog paper-input:last-of-type {
+        margin-bottom: 1.2em;
+      }
     </style>
   </template>
 </dom-module>