diff --git a/DEPS b/DEPS
index cc4c3abaa..9853fb9 100644
--- a/DEPS
+++ b/DEPS
@@ -137,7 +137,7 @@
   # 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': '844fc6c8246c3d623dda28af5056819ab79c87cd',
+  'v8_revision': '4e74864a971dc6992f308d476b1b7b779085ae14',
   # 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.
@@ -145,15 +145,15 @@
   # 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': '49c9dfe3b832a5dafefff299552ea68b83c9cd8a',
+  'angle_revision': 'c9bc33cff4832700e2da8e35496a18c9652c9607',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
-  'swiftshader_revision': '654540e86243fd2cab6db3d03d8c6a3d7425b4a1',
+  'swiftshader_revision': '3364227fa0d88a3681e03237461cf0d2e4c9b39e',
   # 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': 'c6f50282a2af22b8b27011507601feeb55d0b4f7',
+  'pdfium_revision': 'c924d0027a7dc280fba258b5bcc2d04c942c1565',
   # 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.
@@ -196,7 +196,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '4c54c5ccdebde32f537f4e5dfd3fb9dc9c45678b',
+  'catapult_revision': 'eb73833a2935a42bb618d0557e3d45ae6624c9e9',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -264,7 +264,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': '1e1c13ed87bae248e044fdd6fec9c5ab7efccf41',
+  'dawn_revision': '8d79f78c789d2607fcf03bd6865f7412f1c732a2',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -760,7 +760,7 @@
 
   # Build tools for Chrome OS. Note: This depends on third_party/pyelftools.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '9c082a6bae75b6aadc9d556b87e42f6701860466',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '96053d06c97b5ae20ee13c591ec557a1f745e540',
       'condition': 'checkout_linux',
   },
 
@@ -785,7 +785,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '8220b123a125e6d4cb368b6b6a48207d843be6f9',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '77e5d48a085ee4fe7f6e10f5dcbb12fbc59eb4d2',
 
   'src/third_party/devtools-node-modules':
     Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'),
@@ -854,7 +854,7 @@
   },
 
   'src/third_party/glslang/src':
-    Var('chromium_git') + '/external/github.com/KhronosGroup/glslang.git' + '@' + '40c16ec0b3ad03fc170f1369a58e7bbe662d82cd',
+    Var('chromium_git') + '/external/github.com/KhronosGroup/glslang.git' + '@' + '437a552f51ec2042aac7f52826b1fd8281998ff8',
 
   'src/third_party/google_toolbox_for_mac/src': {
       'url': Var('chromium_git') + '/external/github.com/google/google-toolbox-for-mac.git' + '@' + Var('google_toolbox_for_mac_revision'),
@@ -1127,7 +1127,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' +  '8bc65917405b0e98dc699346146b6f5d74e526dc',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' +  '28f71e89e3ee6c9f472a18f476199ee03c5d6c17',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78',
diff --git a/ash/app_list/app_list_controller_impl.cc b/ash/app_list/app_list_controller_impl.cc
index 8441bef..31258f2e 100644
--- a/ash/app_list/app_list_controller_impl.cc
+++ b/ash/app_list/app_list_controller_impl.cc
@@ -44,6 +44,7 @@
 #include "ui/base/ui_base_features.h"
 #include "ui/display/manager/display_manager.h"
 #include "ui/display/screen.h"
+#include "ui/wm/public/activation_client.h"
 
 namespace ash {
 
@@ -457,6 +458,8 @@
   if (!app_list_features::IsEmbeddedAssistantUIEnabled())
     return;
 
+  UpdateLauncherContainer();
+
   if (new_state == ash::AppListState::kStateEmbeddedAssistant) {
     // ShowUi will be no-op if the AssistantUiModel is already visible.
     Shell::Get()->assistant_controller()->ui_controller()->ShowUi(
@@ -623,6 +626,7 @@
 
   // Show the app list if the tablet mode starts.
   ShowHomeLauncher();
+  UpdateLauncherContainer();
 }
 
 void AppListControllerImpl::OnTabletModeEnded() {
@@ -631,6 +635,7 @@
 
   // Dismiss the app list if the tablet mode ends.
   DismissAppList();
+  UpdateLauncherContainer();
 }
 
 void AppListControllerImpl::OnWallpaperColorsChanged() {
@@ -693,12 +698,9 @@
     AssistantVisibility old_visibility,
     base::Optional<AssistantEntryPoint> entry_point,
     base::Optional<AssistantExitPoint> exit_point) {
-  // TODO(wutao): Handle tablet mode.
   switch (new_visibility) {
     case AssistantVisibility::kVisible:
-      if (IsTabletMode()) {
-        MinimizeAllWindows();
-      } else if (!IsVisible()) {
+      if (!IsVisible()) {
         Show(GetDisplayIdToShowAppListOn(), app_list::kAssistantEntryPoint,
              base::TimeTicks());
       }
@@ -751,6 +753,16 @@
   UpdateExpandArrowVisibility();
 }
 
+base::Optional<base::TimeDelta>
+AppListControllerImpl::GetOptionalAnimationDuration() {
+  if (model_->state() == ash::AppListState::kStateEmbeddedAssistant) {
+    // If Assistant is shown, we don't want any delay in animation transitions
+    // since the launcher is already shown.
+    return base::TimeDelta::Min();
+  }
+  return base::nullopt;
+}
+
 void AppListControllerImpl::Back() {
   presenter_.GetView()->Back();
 }
@@ -1188,4 +1200,38 @@
   StartSearch(base::string16());
 }
 
+void AppListControllerImpl::UpdateLauncherContainer() {
+  bool launcher_should_show_behind_apps =
+      IsTabletMode() &&
+      model_->state() != ash::AppListState::kStateEmbeddedAssistant;
+
+  aura::Window* window = presenter_.GetWindow();
+  if (!window)
+    return;
+
+  auto container_id = launcher_should_show_behind_apps
+                          ? ash::kShellWindowId_AppListTabletModeContainer
+                          : ash::kShellWindowId_AppListContainer;
+
+  aura::Window* root_window = window->GetRootWindow();
+  aura::Window* parent_window = root_window->GetChildById(container_id);
+  if (parent_window && !parent_window->Contains(window)) {
+    parent_window->AddChild(window);
+    bool is_showing_app_window = false;
+    for (auto* app_window :
+         Shell::Get()->mru_window_tracker()->BuildWindowForCycleList()) {
+      if (!parent_window->Contains(app_window) &&
+          !wm::GetWindowState(app_window)->IsMinimized()) {
+        is_showing_app_window = true;
+        break;
+      }
+    }
+    if (launcher_should_show_behind_apps && is_showing_app_window) {
+      // When move launcher back to behind apps, and there is app window
+      // showing, we release focus.
+      Shell::Get()->activation_client()->DeactivateWindow(window);
+    }
+  }
+}
+
 }  // namespace ash
diff --git a/ash/app_list/app_list_controller_impl.h b/ash/app_list/app_list_controller_impl.h
index 70545a0..f1ea3cde 100644
--- a/ash/app_list/app_list_controller_impl.h
+++ b/ash/app_list/app_list_controller_impl.h
@@ -259,6 +259,7 @@
       float opacity,
       UpdateAnimationSettingsCallback callback) override;
   void UpdateAfterHomeLauncherShown() override;
+  base::Optional<base::TimeDelta> GetOptionalAnimationDuration() override;
 
   bool onscreen_keyboard_shown() const { return onscreen_keyboard_shown_; }
 
@@ -308,6 +309,9 @@
 
   void ResetHomeLauncherIfShown();
 
+  // Updates which container the launcher window should be in.
+  void UpdateLauncherContainer();
+
   base::string16 last_raw_query_;
 
   mojom::AppListClientPtr client_;
diff --git a/ash/app_list/app_list_presenter_delegate_impl.cc b/ash/app_list/app_list_presenter_delegate_impl.cc
index 6e1a9c4..e932bc6e 100644
--- a/ash/app_list/app_list_presenter_delegate_impl.cc
+++ b/ash/app_list/app_list_presenter_delegate_impl.cc
@@ -6,7 +6,10 @@
 
 #include "ash/app_list/app_list_controller_impl.h"
 #include "ash/app_list/presenter/app_list_presenter_impl.h"
+#include "ash/app_list/views/app_list_main_view.h"
 #include "ash/app_list/views/app_list_view.h"
+#include "ash/app_list/views/contents_view.h"
+#include "ash/app_list/views/search_box_view.h"
 #include "ash/public/cpp/app_list/app_list_switches.h"
 #include "ash/public/cpp/ash_switches.h"
 #include "ash/public/cpp/shelf_types.h"
@@ -244,6 +247,21 @@
     if (!shelf_window || !shelf_window->Contains(target))
       presenter_->Dismiss(event->time_stamp());
   }
+
+  if (IsTabletMode() && presenter_->IsShowingEmbeddedAssistantUI()) {
+    auto* contents_view =
+        presenter_->GetView()->app_list_main_view()->contents_view();
+    if (target == contents_view->GetWidget()->GetNativeWindow() &&
+        contents_view->bounds().Contains(event->location())) {
+      // Keep Assistant open if event happen inside.
+      return;
+    }
+
+    // Touching anywhere else closes Assistant.
+    view_->Back();
+    view_->search_box_view()->ClearSearch();
+    view_->search_box_view()->SetSearchBoxActive(false, ui::ET_UNKNOWN);
+  }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/ash/app_list/views/app_list_view.cc b/ash/app_list/views/app_list_view.cc
index c8cd136..36df2ce 100644
--- a/ash/app_list/views/app_list_view.cc
+++ b/ash/app_list/views/app_list_view.cc
@@ -702,7 +702,8 @@
     return;
   }
 
-  if (!search_box_view_->is_search_box_active()) {
+  if (!search_box_view_->is_search_box_active() &&
+      model_->state() != ash::AppListState::kStateEmbeddedAssistant) {
     if (!is_tablet_mode())
       Dismiss();
     return;
@@ -1193,15 +1194,6 @@
                ? AppListViewState::FULLSCREEN_SEARCH
                : AppListViewState::FULLSCREEN_ALL_APPS);
 
-  // Put app list window in corresponding container based on whether the
-  // tablet mode is enabled.
-  aura::Window* window = GetWidget()->GetNativeWindow();
-  aura::Window* root_window = window->GetRootWindow();
-  aura::Window* parent_window =
-      root_window->GetChildById(ash::kShellWindowId_AppListTabletModeContainer);
-  if (parent_window && !parent_window->Contains(window))
-    parent_window->AddChild(window);
-
   // Update background color opacity.
   SetBackgroundShieldColor();
 
diff --git a/ash/app_list/views/assistant/assistant_main_view.cc b/ash/app_list/views/assistant/assistant_main_view.cc
index af630734..e479f41 100644
--- a/ash/app_list/views/assistant/assistant_main_view.cc
+++ b/ash/app_list/views/assistant/assistant_main_view.cc
@@ -10,6 +10,7 @@
 #include "ash/app_list/views/assistant/dialog_plate.h"
 #include "ash/assistant/ui/assistant_ui_constants.h"
 #include "ash/assistant/ui/assistant_view_delegate.h"
+#include "ui/chromeos/search_box/search_box_constants.h"
 #include "ui/views/layout/box_layout.h"
 
 namespace app_list {
@@ -59,7 +60,24 @@
   return dialog_plate_->FindFirstFocusableView();
 }
 
+void AssistantMainView::RequestFocus() {
+  dialog_plate_->RequestFocus();
+}
+
+void AssistantMainView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
+  layer_mask_->layer()->SetBounds(GetLocalBounds());
+}
+
 void AssistantMainView::InitLayout() {
+  SetPaintToLayer();
+  layer()->SetFillsBoundsOpaquely(false);
+
+  layer_mask_ = views::Painter::CreatePaintedLayer(
+      views::Painter::CreateSolidRoundRectPainter(
+          SK_ColorBLACK, search_box::kSearchBoxBorderCornerRadiusSearchResult));
+  layer_mask_->layer()->SetFillsBoundsOpaquely(false);
+  layer()->SetMaskLayer(layer_mask_->layer());
+
   views::BoxLayout* layout =
       SetLayoutManager(std::make_unique<views::BoxLayout>(
           views::BoxLayout::Orientation::kVertical));
@@ -78,8 +96,4 @@
   layout->SetFlexForView(main_stage_, 1);
 }
 
-void AssistantMainView::RequestFocus() {
-  dialog_plate_->RequestFocus();
-}
-
 }  // namespace app_list
diff --git a/ash/app_list/views/assistant/assistant_main_view.h b/ash/app_list/views/assistant/assistant_main_view.h
index 9a9534c..f47e72f 100644
--- a/ash/app_list/views/assistant/assistant_main_view.h
+++ b/ash/app_list/views/assistant/assistant_main_view.h
@@ -5,8 +5,11 @@
 #ifndef ASH_APP_LIST_VIEWS_ASSISTANT_ASSISTANT_MAIN_VIEW_H_
 #define ASH_APP_LIST_VIEWS_ASSISTANT_ASSISTANT_MAIN_VIEW_H_
 
+#include <memory>
+
 #include "ash/app_list/app_list_export.h"
 #include "base/macros.h"
+#include "ui/compositor/layer_owner.h"
 #include "ui/views/view.h"
 
 namespace ash {
@@ -29,6 +32,7 @@
   void ChildPreferredSizeChanged(views::View* child) override;
   void ChildVisibilityChanged(views::View* child) override;
   void RequestFocus() override;
+  void OnBoundsChanged(const gfx::Rect& previous_bounds) override;
 
   // Returns the first focusable view or nullptr to defer to views::FocusSearch.
   views::View* FindFirstFocusableView();
@@ -41,6 +45,9 @@
   DialogPlate* dialog_plate_;            // Owned by view hierarchy.
   AssistantMainStage* main_stage_;       // Owned by view hierarchy.
 
+  // Used to enforce child layers clip to rounded corner bounds.
+  std::unique_ptr<ui::LayerOwner> layer_mask_;
+
   DISALLOW_COPY_AND_ASSIGN(AssistantMainView);
 };
 
diff --git a/ash/app_list/views/assistant/assistant_page_view.cc b/ash/app_list/views/assistant/assistant_page_view.cc
index 13002cf7..173c094 100644
--- a/ash/app_list/views/assistant/assistant_page_view.cc
+++ b/ash/app_list/views/assistant/assistant_page_view.cc
@@ -20,6 +20,7 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/chromeos/search_box/search_box_constants.h"
 #include "ui/views/background.h"
+#include "ui/views/bubble/bubble_border.h"
 #include "ui/views/focus/focus_manager.h"
 #include "ui/views/layout/fill_layout.h"
 
@@ -31,6 +32,9 @@
 // animation.
 constexpr int kSearchBoxHeightDip = 56;
 
+// The shadow elevation value for the shadow of the Assistant search box.
+constexpr int kShadowElevation = 12;
+
 }  // namespace
 
 AssistantPageView::AssistantPageView(
@@ -52,13 +56,19 @@
   SetPaintToLayer();
   layer()->SetFillsBoundsOpaquely(false);
 
-  SetBackground(views::CreateSolidBackground(SK_ColorWHITE));
+  // Create and set a shadow to be displayed as a border for this view.
+  auto shadow_border = std::make_unique<views::BubbleBorder>(
+      views::BubbleBorder::NONE, views::BubbleBorder::SMALL_SHADOW,
+      SK_ColorWHITE);
+  shadow_border->SetCornerRadius(
+      search_box::kSearchBoxBorderCornerRadiusSearchResult);
+  shadow_border->set_md_shadow_elevation(kShadowElevation);
+  SetBorder(std::move(shadow_border));
 
-  mask_ = views::Painter::CreatePaintedLayer(
+  SetBackground(views::CreateBackgroundFromPainter(
       views::Painter::CreateSolidRoundRectPainter(
-          SK_ColorBLACK, search_box::kSearchBoxBorderCornerRadiusSearchResult));
-  mask_->layer()->SetFillsBoundsOpaquely(false);
-  layer()->SetMaskLayer(mask_->layer());
+          SK_ColorWHITE, search_box::kSearchBoxBorderCornerRadiusSearchResult,
+          border()->GetInsets())));
 
   SetLayoutManager(std::make_unique<views::FillLayout>());
 
@@ -103,10 +113,6 @@
   }
 }
 
-void AssistantPageView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
-  mask_->layer()->SetBounds(GetLocalBounds());
-}
-
 void AssistantPageView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
   View::GetAccessibleNodeData(node_data);
   node_data->SetName(l10n_util::GetStringUTF16(IDS_ASH_ASSISTANT_WINDOW));
@@ -140,29 +146,26 @@
 
 gfx::Rect AssistantPageView::GetPageBoundsForState(
     ash::AppListState state) const {
-  gfx::Rect onscreen_bounds;
-
+  gfx::Rect bounds;
   if (state != ash::AppListState::kStateEmbeddedAssistant) {
     // Hides this view behind the search box by using the same bounds.
-    onscreen_bounds =
-        AppListPage::contents_view()->GetSearchBoxBoundsForState(state);
+    bounds = AppListPage::contents_view()->GetSearchBoxBoundsForState(state);
   } else {
-    onscreen_bounds = AppListPage::GetSearchBoxBounds();
-    onscreen_bounds.Offset(
-        (onscreen_bounds.width() - ash::kPreferredWidthDip) / 2, 0);
-    onscreen_bounds.set_size(GetPreferredSize());
+    bounds = AppListPage::GetSearchBoxBounds();
+    bounds.Offset((bounds.width() - ash::kPreferredWidthDip) / 2, 0);
+    bounds.set_size(GetPreferredSize());
   }
 
-  return onscreen_bounds;
+  return AddShadowBorderToBounds(bounds);
 }
 
 gfx::Rect AssistantPageView::GetSearchBoxBounds() const {
-  gfx::Rect rect(AppListPage::GetSearchBoxBounds());
+  gfx::Rect bounds(AppListPage::GetSearchBoxBounds());
 
-  rect.Offset((rect.width() - ash::kPreferredWidthDip) / 2, 0);
-  rect.set_size(gfx::Size(ash::kPreferredWidthDip, kSearchBoxHeightDip));
+  bounds.Offset((bounds.width() - ash::kPreferredWidthDip) / 2, 0);
+  bounds.set_size(gfx::Size(ash::kPreferredWidthDip, kSearchBoxHeightDip));
 
-  return rect;
+  return bounds;
 }
 
 views::View* AssistantPageView::GetFirstFocusableView() {
@@ -217,4 +220,11 @@
   }
 }
 
+gfx::Rect AssistantPageView::AddShadowBorderToBounds(
+    const gfx::Rect& bounds) const {
+  gfx::Rect new_bounds(bounds);
+  new_bounds.Inset(-border()->GetInsets());
+  return new_bounds;
+}
+
 }  // namespace app_list
diff --git a/ash/app_list/views/assistant/assistant_page_view.h b/ash/app_list/views/assistant/assistant_page_view.h
index 66bb00cc..530af9d 100644
--- a/ash/app_list/views/assistant/assistant_page_view.h
+++ b/ash/app_list/views/assistant/assistant_page_view.h
@@ -17,10 +17,6 @@
 class AssistantWebView;
 }  // namespace ash
 
-namespace ui {
-class LayerOwner;
-}  // namespace ui
-
 namespace app_list {
 
 class AssistantMainView;
@@ -39,7 +35,6 @@
   const char* GetClassName() const override;
   gfx::Size CalculatePreferredSize() const override;
   void RequestFocus() override;
-  void OnBoundsChanged(const gfx::Rect& previous_bounds) override;
   void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
 
   // ui::EventHandler:
@@ -60,6 +55,8 @@
       base::Optional<ash::AssistantEntryPoint> entry_point,
       base::Optional<ash::AssistantExitPoint> exit_point) override;
 
+  gfx::Rect AddShadowBorderToBounds(const gfx::Rect& bounds) const;
+
  private:
   ash::AssistantViewDelegate* const assistant_view_delegate_;
 
@@ -67,9 +64,6 @@
   AssistantMainView* assistant_main_view_ = nullptr;
   ash::AssistantWebView* assistant_web_view_ = nullptr;
 
-  // Used to enforce round corners on the Assistant view hierarchy.
-  std::unique_ptr<ui::LayerOwner> mask_;
-
   DISALLOW_COPY_AND_ASSIGN(AssistantPageView);
 };
 
diff --git a/ash/assistant/assistant_screen_context_controller.cc b/ash/assistant/assistant_screen_context_controller.cc
index a8c22bc..cb00a35 100644
--- a/ash/assistant/assistant_screen_context_controller.cc
+++ b/ash/assistant/assistant_screen_context_controller.cc
@@ -84,10 +84,14 @@
 
   aura::Window* app_list_container =
       ash::Shell::GetContainer(root_window, kShellWindowId_AppListContainer);
+  aura::Window* app_list_tablet_mode_container = ash::Shell::GetContainer(
+      root_window, kShellWindowId_AppListTabletModeContainer);
 
   // Ignore app list to prevent interfering with app list animations.
   if (app_list_container)
     excluded_layers.insert(app_list_container->layer());
+  if (app_list_tablet_mode_container)
+    excluded_layers.insert(app_list_tablet_mode_container->layer());
 
   MruWindowTracker::WindowList windows =
       Shell::Get()->mru_window_tracker()->BuildMruWindowList();
diff --git a/ash/home_screen/home_launcher_gesture_handler.cc b/ash/home_screen/home_launcher_gesture_handler.cc
index a03895d9..51bbbbd7 100644
--- a/ash/home_screen/home_launcher_gesture_handler.cc
+++ b/ash/home_screen/home_launcher_gesture_handler.cc
@@ -4,6 +4,10 @@
 
 #include "ash/home_screen/home_launcher_gesture_handler.h"
 
+#include <algorithm>
+#include <memory>
+
+#include "ash/app_list/app_list_controller_impl.h"
 #include "ash/home_screen/home_launcher_gesture_handler_observer.h"
 #include "ash/home_screen/home_screen_controller.h"
 #include "ash/home_screen/home_screen_delegate.h"
@@ -24,7 +28,6 @@
 #include "ash/wm/workspace_controller.h"
 #include "base/bind.h"
 #include "base/bind_helpers.h"
-#include "base/logging.h"
 #include "base/metrics/user_metrics.h"
 #include "base/numerics/ranges.h"
 #include "services/ws/public/mojom/window_tree_constants.mojom.h"
@@ -558,9 +561,16 @@
 void HomeLauncherGestureHandler::UpdateSettings(
     ui::ScopedLayerAnimationSettings* settings,
     bool observe) {
-  settings->SetTransitionDuration(IsDragInProgress()
-                                      ? kAnimationDurationMs
-                                      : kActivationChangedAnimationDurationMs);
+  auto duration_ms = kActivationChangedAnimationDurationMs;
+  if (IsDragInProgress())
+    duration_ms = kAnimationDurationMs;
+
+  HomeScreenDelegate* home_screen_delegate =
+      Shell::Get()->home_screen_controller()->delegate();
+  duration_ms = home_screen_delegate->GetOptionalAnimationDuration().value_or(
+      duration_ms);
+
+  settings->SetTransitionDuration(duration_ms);
   settings->SetTweenType(IsDragInProgress() ? gfx::Tween::LINEAR
                                             : gfx::Tween::FAST_OUT_SLOW_IN);
   settings->SetPreemptionStrategy(
diff --git a/ash/home_screen/home_screen_delegate.h b/ash/home_screen/home_screen_delegate.h
index 314fbf9..461cae4f 100644
--- a/ash/home_screen/home_screen_delegate.h
+++ b/ash/home_screen/home_screen_delegate.h
@@ -30,6 +30,10 @@
 
   // Updates the home launcher view after its show animation has completed.
   virtual void UpdateAfterHomeLauncherShown() = 0;
+
+  // Returns an optional animation duration which is going to be used to set
+  // the transition animation if provided.
+  virtual base::Optional<base::TimeDelta> GetOptionalAnimationDuration() = 0;
 };
 
 }  // namespace ash
diff --git a/ash/public/cpp/ash_switches.cc b/ash/public/cpp/ash_switches.cc
index e4c1dbb..afcf31f7 100644
--- a/ash/public/cpp/ash_switches.cc
+++ b/ash/public/cpp/ash_switches.cc
@@ -81,12 +81,7 @@
 const char kAshHideNotificationsForFactory[] =
     "ash-hide-notifications-for-factory";
 
-// Enables the shelf color to be derived from the wallpaper.
-const char kAshShelfColor[] = "ash-shelf-color";
-const char kAshShelfColorEnabled[] = "enabled";
-const char kAshShelfColorDisabled[] = "disabled";
-
-// The color scheme to be used when the |kAshShelfColor| feature is enabled.
+// The color scheme to be used.
 const char kAshShelfColorScheme[] = "ash-shelf-color-scheme";
 const char kAshShelfColorSchemeLightMuted[] = "light_muted";
 const char kAshShelfColorSchemeLightVibrant[] = "light_vibrant";
diff --git a/ash/shelf/shelf_background_animator_unittest.cc b/ash/shelf/shelf_background_animator_unittest.cc
index f26b981..d8fc943 100644
--- a/ash/shelf/shelf_background_animator_unittest.cc
+++ b/ash/shelf/shelf_background_animator_unittest.cc
@@ -277,15 +277,6 @@
   ShelfBackgroundTargetColorTest() = default;
   ~ShelfBackgroundTargetColorTest() override = default;
 
-  // AshTestBase:
-  void SetUp() override {
-    // Do not allow the shelf color to be derived from the wallpaper, in order
-    // to have a fixed color in tests.
-    base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
-        switches::kAshShelfColor, switches::kAshShelfColorDisabled);
-    AshTestBase::SetUp();
-  }
-
  protected:
   // Helper function to notify session state changes.
   void NotifySessionStateChanged(session_manager::SessionState state) {
diff --git a/ash/wallpaper/wallpaper_controller.cc b/ash/wallpaper/wallpaper_controller.cc
index 45130f45..6da2f6f 100644
--- a/ash/wallpaper/wallpaper_controller.cc
+++ b/ash/wallpaper/wallpaper_controller.cc
@@ -231,23 +231,6 @@
   return gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
 }
 
-// Returns true if a color should be extracted from the wallpaper based on the
-// command kAshShelfColor line arg.
-bool IsShelfColoringEnabled() {
-  const std::string explicit_switch_value =
-      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
-          switches::kAshShelfColor);
-
-  // Always enabled, unless explicitly disabled.
-  if (explicit_switch_value == switches::kAshShelfColorDisabled) {
-    LOG(WARNING) << "Shelf coloring explicitly disabled. "
-                 << "This should only happen in tests.";
-    return false;
-  }
-
-  return true;
-}
-
 // Gets the color profiles for extracting wallpaper prominent colors.
 std::vector<ColorProfile> GetProminentColorProfiles() {
   return {ColorProfile(LumaRange::DARK, SaturationRange::VIBRANT),
@@ -2009,8 +1992,7 @@
 
 bool WallpaperController::ShouldCalculateColors() const {
   gfx::ImageSkia image = GetWallpaper();
-  return IsShelfColoringEnabled() &&
-         Shell::Get()->session_controller()->GetSessionState() ==
+  return Shell::Get()->session_controller()->GetSessionState() ==
              session_manager::SessionState::ACTIVE &&
          !image.isNull();
 }
diff --git a/build/android/pylib/local/machine/local_machine_junit_test_run.py b/build/android/pylib/local/machine/local_machine_junit_test_run.py
index 411995fe8..dbfc505d 100644
--- a/build/android/pylib/local/machine/local_machine_junit_test_run.py
+++ b/build/android/pylib/local/machine/local_machine_junit_test_run.py
@@ -37,19 +37,17 @@
       # Extract resources needed for test.
       # TODO(mikecase): Investigate saving md5sums of zipfiles, and only
       # extract zipfiles when they change.
-      def extract_resource_zip(resource_zip):
+      def extract_resource_zip(resource_zip, filename):
         def helper():
-          # Flatten name to avoid needing to create directories.
-          extract_dest = os.path.join(temp_dir,
-                                      resource_zip.replace(os.path.sep, '_'))
+          extract_dest = os.path.join(temp_dir, filename)
           with zipfile.ZipFile(resource_zip, 'r') as zf:
             zf.extractall(extract_dest)
           return extract_dest
         return helper
 
       resource_dirs = reraiser_thread.RunAsync(
-          extract_resource_zip(resource_zip)
-          for resource_zip in self._test_instance.resource_zips)
+          extract_resource_zip(resource_zip, 'resources_%d' % index) for index,
+          resource_zip in enumerate(self._test_instance.resource_zips))
 
       java_script = os.path.join(
           constants.GetOutDirectory(), 'bin', 'helper',
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index 5b64dbd2..b27180b 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-b32c720f683bc5b45aaf65927e64cfb4ac681c30
\ No newline at end of file
+899835ec9999d050acd4e023fd0d2d0d2cae3cfe
\ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index e862d4a..0190d9f 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-a3036378e07c7639416fd05c38eb24a6a0b4dcb7
\ No newline at end of file
+0900e4c1124c1a676543334b56671bac962641c1
\ No newline at end of file
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
index 3bd3fb2b..ececd22 100644
--- a/chrome/BUILD.gn
+++ b/chrome/BUILD.gn
@@ -5,7 +5,6 @@
 import("//build/config/chrome_build.gni")
 import("//build/config/compiler/compiler.gni")
 import("//build/config/compiler/pgo/pgo.gni")
-import("//build/config/coverage/coverage.gni")
 import("//build/config/features.gni")
 import("//build/config/linux/pangocairo/pangocairo.gni")
 import("//build/config/locales.gni")
@@ -310,9 +309,7 @@
         data_deps += [ "//mojo/core:shared_library" ]
       }
 
-      # We skip building mojo for ARC in a coverage build because we lack clang
-      # runtime profiling libraries for Android. crbug.com/865376
-      if (is_chromeos && !use_clang_coverage) {
+      if (is_chromeos) {
         data_deps += [ "//mojo/core:shared_libraries_for_arc" ]
       }
 
diff --git a/chrome/VERSION b/chrome/VERSION
index 81c9992..71278e9c 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=75
 MINOR=0
-BUILD=3731
+BUILD=3732
 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/send_tab_to_self/NotificationManager.java b/chrome/android/java/src/org/chromium/chrome/browser/send_tab_to_self/NotificationManager.java
index 3c9f2de..25f64a6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/send_tab_to_self/NotificationManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/send_tab_to_self/NotificationManager.java
@@ -33,6 +33,7 @@
 import org.chromium.chrome.browser.notifications.NotificationUmaTracker;
 import org.chromium.chrome.browser.notifications.PendingIntentProvider;
 import org.chromium.chrome.browser.notifications.channels.ChannelDefinitions;
+import org.chromium.chrome.browser.profiles.Profile;
 
 import java.util.HashSet;
 import java.util.Set;
@@ -44,8 +45,6 @@
 public class NotificationManager {
     private static final String NOTIFICATION_GUID_EXTRA = "send_tab_to_self.notification.guid";
 
-    private static final String PREF_CHANNEL_CREATED =
-            "send_tab_to_self.notification.channel_created";
     // Tracks which GUIDs there is an active notification for.
     private static final String PREF_ACTIVE_NOTIFICATIONS = "send_tab_to_self.notification.active";
     private static final String PREF_NEXT_NOTIFICATION_ID = "send_tab_to_self.notification.next_id";
@@ -56,6 +55,7 @@
         public void onReceive(Context context, Intent intent) {
             String guid = intent.getStringExtra(NOTIFICATION_GUID_EXTRA);
             hideNotification(guid);
+            SendTabToSelfAndroidBridge.dismissEntry(Profile.getLastUsedProfile(), guid);
         }
     }
 
@@ -66,6 +66,7 @@
             openUrl(intent.getData());
             String guid = intent.getStringExtra(NOTIFICATION_GUID_EXTRA);
             hideNotification(guid);
+            SendTabToSelfAndroidBridge.deleteEntry(Profile.getLastUsedProfile(), guid);
         }
     }
 
@@ -75,6 +76,7 @@
         public void onReceive(Context context, Intent intent) {
             String guid = intent.getStringExtra(NOTIFICATION_GUID_EXTRA);
             hideNotification(guid);
+            SendTabToSelfAndroidBridge.dismissEntry(Profile.getLastUsedProfile(), guid);
         }
     }
 
@@ -104,6 +106,7 @@
      *
      * @param guid The GUID of the notification to hide.
      */
+    @CalledByNative
     private static void hideNotification(@Nullable String guid) {
         ActiveNotification activeNotification = findActiveNotification(guid);
         if (!removeActiveNotification(guid)) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java
index b4fb256..11af81e 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java
@@ -915,6 +915,7 @@
     }
 
     @Test
+    @DisabledTest(message = "crbug.com/940831")
     @LargeTest
     @Feature({"Android-TabSwitcher"})
     @Restriction({UiRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
index a4552ab..b639588 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
@@ -1588,10 +1588,12 @@
      */
     @Test
     @SmallTest
-    @DisableIf.Build(sdk_is_less_than = Build.VERSION_CODES.LOLLIPOP, message = "crbug.com/837998")
     @Feature({"ContextualSearch"})
-    public void testLongPressGestureFollowedByTapDoesntSelect()
-            throws InterruptedException, TimeoutException {
+    @DisableIf.Build(message = "Flaky except on M-Phone.  See https://crbug.com/837998",
+            sdk_is_less_than = Build.VERSION_CODES.M, sdk_is_greater_than = Build.VERSION_CODES.M)
+    @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE)
+    public void
+    testLongPressGestureFollowedByTapDoesntSelect() throws InterruptedException, TimeoutException {
         longPressNode("intelligence");
         waitForPanelToPeek();
         clickWordNode("states-far");
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index 38b2066..34830df 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-74.0.3729.5_rc-r1-merged.afdo.bz2
\ No newline at end of file
+chromeos-chrome-amd64-74.0.3729.6_rc-r1-merged.afdo.bz2
\ No newline at end of file
diff --git a/chrome/app/onboarding_welcome_strings.grdp b/chrome/app/onboarding_welcome_strings.grdp
index cf399a9..b9ed172 100644
--- a/chrome/app/onboarding_welcome_strings.grdp
+++ b/chrome/app/onboarding_welcome_strings.grdp
@@ -79,6 +79,9 @@
   <message name="IDS_ONBOARDING_WELCOME_NTP_BACKGROUND_PREVIEW_UPDATED" desc="String read for accessibility to inform the user that the background of the New Tab Page (referred to as 'start page') has been changed to a specific photo.">
     Start page background has been changed to <ph name="CATEGORY">$1<ex>Geometric shapes</ex></ph>.
   </message>
+  <message name="IDS_ONBOARDING_WELCOME_NTP_BACKGROUND_RESET" desc="String read for accessibility to inform the user that the background of the New Tab Page (referred to as 'start page') has been reset to the default background.">
+    Start page background has been reset to the default background.
+  </message>
 
   <!-- NUX set default module -->
   <message name="IDS_ONBOARDING_WELCOME_NUX_SET_AS_DEFAULT_HEADER" desc="Header for the page that prompts user to set Chrome as their default browser.">
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 6ebd6034..92221ba 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -473,13 +473,6 @@
      switches::kNewTabButtonPosition, switches::kNewTabButtonPositionTrailing}};
 
 #if defined(OS_CHROMEOS)
-const FeatureEntry::Choice kAshShelfColorChoices[] = {
-    {flags_ui::kGenericExperimentChoiceDefault, "", ""},
-    {flags_ui::kGenericExperimentChoiceEnabled, ash::switches::kAshShelfColor,
-     ash::switches::kAshShelfColorEnabled},
-    {flags_ui::kGenericExperimentChoiceDisabled, ash::switches::kAshShelfColor,
-     ash::switches::kAshShelfColorDisabled}};
-
 const FeatureEntry::Choice kAshShelfColorSchemeChoices[] = {
     {flags_ui::kGenericExperimentChoiceDefault, "", ""},
     {flag_descriptions::kAshShelfColorSchemeLightVibrant,
@@ -1462,9 +1455,6 @@
         kOsAll,
         SINGLE_VALUE_TYPE(ash::switches::kAshDebugShortcuts),
     },
-    {"ash-shelf-color", flag_descriptions::kAshShelfColorName,
-     flag_descriptions::kAshShelfColorDescription, kOsCrOS,
-     MULTI_VALUE_TYPE(kAshShelfColorChoices)},
     {"ash-shelf-color-scheme", flag_descriptions::kAshShelfColorScheme,
      flag_descriptions::kAshShelfColorSchemeDescription, kOsCrOS,
      MULTI_VALUE_TYPE(kAshShelfColorSchemeChoices)},
@@ -4081,6 +4071,12 @@
      flag_descriptions::kNativeFilesystemAPIDescription, kOsAll,
      FEATURE_VALUE_TYPE(blink::features::kNativeFilesystemAPI)},
 
+#if !defined(OS_ANDROID)
+    {"enable-intent-picker", flag_descriptions::kIntentPickerName,
+     flag_descriptions::kIntentPickerDescription, kOsMac | kOsWin | kOsLinux,
+     FEATURE_VALUE_TYPE(features::kIntentPicker)},
+#endif  // !defined(OS_ANDROID)
+
     // NOTE: Adding a new flag requires adding a corresponding entry to enum
     // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag
     // Histograms" in tools/metrics/histograms/README.md (run the
diff --git a/chrome/browser/accessibility/accessibility_labels_service.cc b/chrome/browser/accessibility/accessibility_labels_service.cc
index 122e4ddc..64dddcc 100644
--- a/chrome/browser/accessibility/accessibility_labels_service.cc
+++ b/chrome/browser/accessibility/accessibility_labels_service.cc
@@ -56,10 +56,13 @@
           weak_factory_.GetWeakPtr()));
 
   // Log whether the feature is enabled after startup.
+  // TODO(dmazzoni) re-enable. http://crbug.com/940805
+#if 0
   content::BrowserAccessibilityState::GetInstance()->AddHistogramCallback(
       base::BindRepeating(
           &AccessibilityLabelsService::UpdateAccessibilityLabelsHistograms,
           weak_factory_.GetWeakPtr()));
+#endif
 }
 
 AccessibilityLabelsService::AccessibilityLabelsService(Profile* profile)
@@ -124,6 +127,9 @@
 }
 
 void AccessibilityLabelsService::UpdateAccessibilityLabelsHistograms() {
+  if (!profile_ || !profile_->GetPrefs())
+    return;
+
   base::UmaHistogramBoolean("Accessibility.ImageLabels",
                             profile_->GetPrefs()->GetBoolean(
                                 prefs::kAccessibilityImageLabelsEnabled));
diff --git a/chrome/browser/accessibility/accessibility_state_utils.cc b/chrome/browser/accessibility/accessibility_state_utils.cc
index aa248b0..12e43e0 100644
--- a/chrome/browser/accessibility/accessibility_state_utils.cc
+++ b/chrome/browser/accessibility/accessibility_state_utils.cc
@@ -15,7 +15,8 @@
 
 bool IsScreenReaderEnabled() {
 #if defined(OS_CHROMEOS)
-  return chromeos::AccessibilityManager::Get()->IsSpokenFeedbackEnabled();
+  return chromeos::AccessibilityManager::Get() &&
+         chromeos::AccessibilityManager::Get()->IsSpokenFeedbackEnabled();
 #else
   // TODO(katie): Can we use AXMode in Chrome OS as well? May need to stop
   // Switch Access and Select-to-Speak from setting kScreenReader.
diff --git a/chrome/browser/accessibility/image_annotation_browsertest.cc b/chrome/browser/accessibility/image_annotation_browsertest.cc
index 25a23e5..ac3e62d 100644
--- a/chrome/browser/accessibility/image_annotation_browsertest.cc
+++ b/chrome/browser/accessibility/image_annotation_browsertest.cc
@@ -5,6 +5,7 @@
 #include "base/feature_list.h"
 #include "base/logging.h"
 #include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
 #include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "chrome/browser/ui/browser.h"
@@ -24,7 +25,10 @@
 #include "services/service_manager/public/cpp/connector.h"
 #include "services/service_manager/public/cpp/service.h"
 #include "services/service_manager/public/cpp/service_binding.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/accessibility/ax_enum_util.h"
+#include "ui/accessibility/ax_tree.h"
 #include "url/gurl.h"
 
 constexpr base::FilePath::CharType kDocRoot[] =
@@ -32,6 +36,27 @@
 
 namespace {
 
+void DescribeNodesWithAnnotations(const ui::AXNode& node,
+                                  std::vector<std::string>* descriptions) {
+  std::string annotation =
+      node.GetStringAttribute(ax::mojom::StringAttribute::kImageAnnotation);
+  if (!annotation.empty()) {
+    descriptions->push_back(ui::ToString(node.data().role) + std::string(" ") +
+                            annotation);
+  }
+  for (int i = 0; i < node.child_count(); i++)
+    DescribeNodesWithAnnotations(*node.children()[i], descriptions);
+}
+
+std::vector<std::string> DescribeNodesWithAnnotations(
+    const ui::AXTreeUpdate& tree_update) {
+  ui::AXTree tree(tree_update);
+  std::vector<std::string> descriptions;
+  DCHECK(tree.root());
+  DescribeNodesWithAnnotations(*tree.root(), &descriptions);
+  return descriptions;
+}
+
 // A fake implementation of the Annotator mojo interface that
 // returns predictable results based on the filename of the image
 // it's asked to annotate. Enables us to test the rest of the
@@ -166,3 +191,52 @@
   content::WaitForAccessibilityTreeToContainNodeWithName(
       web_contents, "Appears to say: red.png Annotation");
 }
+
+IN_PROC_BROWSER_TEST_F(ImageAnnotationBrowserTest, ImagesInLinks) {
+  ui_test_utils::NavigateToURL(
+      browser(), https_server_.GetURL("/image_annotation_link.html"));
+
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+
+  content::WaitForAccessibilityTreeToContainNodeWithName(
+      web_contents, "Appears to say: red.png Annotation");
+
+  ui::AXTreeUpdate ax_tree_update =
+      content::GetAccessibilityTreeSnapshot(web_contents);
+
+  // All images should be annotated. Only links that contain exactly one image
+  // should be annotated.
+
+  EXPECT_THAT(
+      DescribeNodesWithAnnotations(ax_tree_update),
+      testing::ElementsAre("image Appears to say: red.png Annotation",
+                           "link Appears to say: green.png Annotation",
+                           "image Appears to say: green.png Annotation",
+                           "image Appears to say: red.png Annotation",
+                           "image Appears to say: printer.png Annotation",
+                           "image Appears to say: red.png Annotation",
+                           "link Appears to say: printer.png Annotation",
+                           "image Appears to say: printer.png Annotation"));
+}
+
+IN_PROC_BROWSER_TEST_F(ImageAnnotationBrowserTest, ImageDoc) {
+  ui_test_utils::NavigateToURL(
+      browser(), https_server_.GetURL("/image_annotation_doc.html"));
+
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+
+  content::WaitForAccessibilityTreeToContainNodeWithName(
+      web_contents, "Appears to say: red.png Annotation");
+
+  ui::AXTreeUpdate ax_tree_update =
+      content::GetAccessibilityTreeSnapshot(web_contents);
+
+  // When a document contains exactly one image, the document should be
+  // annotated with the image's annotation, too.
+  EXPECT_THAT(
+      DescribeNodesWithAnnotations(ax_tree_update),
+      testing::ElementsAre("rootWebArea Appears to say: red.png Annotation",
+                           "image Appears to say: red.png Annotation"));
+}
diff --git a/chrome/browser/android/send_tab_to_self/android_notification_handler.cc b/chrome/browser/android/send_tab_to_self/android_notification_handler.cc
index da3259bb..fe69045 100644
--- a/chrome/browser/android/send_tab_to_self/android_notification_handler.cc
+++ b/chrome/browser/android/send_tab_to_self/android_notification_handler.cc
@@ -4,6 +4,9 @@
 
 #include "chrome/browser/android/send_tab_to_self/android_notification_handler.h"
 
+#include <string>
+#include <vector>
+
 #include "base/android/jni_string.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
@@ -30,8 +33,14 @@
       expiraton_time.ToJavaTime());
 }
 
-void AndroidNotificationHandler::DismissEntry(const SendTabToSelfEntry* entry) {
-  // TODO(https://crbug.com/939027): Add code for dismissing an entry
+void AndroidNotificationHandler::DismissEntries(
+    const std::vector<std::string>& guids) {
+  JNIEnv* env = AttachCurrentThread();
+
+  for (const std::string& guid : guids) {
+    Java_NotificationManager_hideNotification(
+        env, ConvertUTF8ToJavaString(env, guid));
+  }
 }
 
 }  // namespace send_tab_to_self
diff --git a/chrome/browser/android/send_tab_to_self/android_notification_handler.h b/chrome/browser/android/send_tab_to_self/android_notification_handler.h
index 67e9e78..9951f7f8 100644
--- a/chrome/browser/android/send_tab_to_self/android_notification_handler.h
+++ b/chrome/browser/android/send_tab_to_self/android_notification_handler.h
@@ -5,6 +5,9 @@
 #ifndef CHROME_BROWSER_ANDROID_SEND_TAB_TO_SELF_ANDROID_NOTIFICATION_HANDLER_H_
 #define CHROME_BROWSER_ANDROID_SEND_TAB_TO_SELF_ANDROID_NOTIFICATION_HANDLER_H_
 
+#include <string>
+#include <vector>
+
 #include "chrome/browser/send_tab_to_self/receiving_ui_handler.h"
 
 namespace send_tab_to_self {
@@ -21,7 +24,7 @@
  private:
   // ReceivingUiHandler implementation.
   void DisplayNewEntry(const SendTabToSelfEntry* entry) override;
-  void DismissEntry(const SendTabToSelfEntry* entry) override;
+  void DismissEntries(const std::vector<std::string>& guids) override;
 };
 
 }  // namespace send_tab_to_self
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index f0c2346f..c8f90de 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -110,7 +110,7 @@
       <include name="IDR_ACCESSIBILITY_CSS" file="resources\accessibility\accessibility.css" compress="gzip" type="BINDATA" />
       <include name="IDR_ACCESSIBILITY_JS" file="resources\accessibility\accessibility.js" flattenhtml="true" compress="gzip" type="BINDATA" />
       <include name="IDR_AD_NETWORK_HASHES" file="resources\ad_networks.dat" type="BINDATA" />
-      <include name="IDR_AUTOFILL_INTERNALS_HTML" file="resources\autofill_internals.html" compress="gzip" type="BINDATA" />
+      <include name="IDR_AUTOFILL_INTERNALS_HTML" file="resources\autofill_internals\autofill_internals.html" compress="gzip" type="BINDATA" />
       <include name="IDR_BLUETOOTH_ADAPTER_MOJO_JS" file="${root_gen_dir}\device\bluetooth\public\mojom\adapter.mojom-lite.js" use_base_dir="false" type="BINDATA" compress="gzip" />
       <include name="IDR_BLUETOOTH_DEVICE_MOJO_JS" file="${root_gen_dir}\device\bluetooth\public\mojom\device.mojom-lite.js" use_base_dir="false" type="BINDATA" compress="gzip" />
       <include name="IDR_BLUETOOTH_UUID_MOJO_JS" file="${root_gen_dir}\device\bluetooth\public\mojom\uuid.mojom-lite.js" use_base_dir="false" type="BINDATA" compress="gzip" />
diff --git a/chrome/browser/chrome_browser_main_browsertest.cc b/chrome/browser/chrome_browser_main_browsertest.cc
index 75ad33a..3fa3a8bf 100644
--- a/chrome/browser/chrome_browser_main_browsertest.cc
+++ b/chrome/browser/chrome_browser_main_browsertest.cc
@@ -74,8 +74,15 @@
 // none to connected. This is a regression test for https://crbug.com/826930.
 // TODO(crbug.com/905714): This test should use a mock variations server
 // instead of performing an actual request.
+#if defined(OS_CHROMEOS)
+#define MAYBE_VariationsServiceStartsRequestOnNetworkChange \
+  DISABLED_VariationsServiceStartsRequestOnNetworkChange
+#else
+#define MAYBE_VariationsServiceStartsRequestOnNetworkChange \
+  VariationsServiceStartsRequestOnNetworkChange
+#endif
 IN_PROC_BROWSER_TEST_F(ChromeBrowserMainBrowserTest,
-                       VariationsServiceStartsRequestOnNetworkChange) {
+                       MAYBE_VariationsServiceStartsRequestOnNetworkChange) {
   variations::VariationsService* variations_service =
       g_browser_process->variations_service();
   variations_service->CancelCurrentRequestForTesting();
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 76e755fc..c436942 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -704,6 +704,8 @@
     "dbus/drive_file_stream_service_provider.h",
     "dbus/kiosk_info_service_provider.cc",
     "dbus/kiosk_info_service_provider.h",
+    "dbus/libvda_service_provider.cc",
+    "dbus/libvda_service_provider.h",
     "dbus/metrics_event_service_provider.cc",
     "dbus/metrics_event_service_provider.h",
     "dbus/plugin_vm_service_provider.cc",
@@ -2035,6 +2037,7 @@
     "dbus/org.chromium.ComponentUpdaterService.conf",
     "dbus/org.chromium.DriveFileStreamService.conf",
     "dbus/org.chromium.KioskAppService.conf",
+    "dbus/org.chromium.LibvdaService.conf",
     "dbus/org.chromium.MetricsEventService.conf",
     "dbus/org.chromium.NetworkProxyService.conf",
     "dbus/org.chromium.PluginVmService.conf",
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
index d46e714b..87861d65 100644
--- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
+++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -50,6 +50,7 @@
 #include "chrome/browser/chromeos/dbus/dbus_helper.h"
 #include "chrome/browser/chromeos/dbus/drive_file_stream_service_provider.h"
 #include "chrome/browser/chromeos/dbus/kiosk_info_service_provider.h"
+#include "chrome/browser/chromeos/dbus/libvda_service_provider.h"
 #include "chrome/browser/chromeos/dbus/metrics_event_service_provider.h"
 #include "chrome/browser/chromeos/dbus/plugin_vm_service_provider.h"
 #include "chrome/browser/chromeos/dbus/proxy_resolution_service_provider.h"
@@ -148,6 +149,7 @@
 #include "chromeos/tpm/install_attributes.h"
 #include "chromeos/tpm/tpm_token_loader.h"
 #include "components/account_id/account_id.h"
+#include "components/arc/arc_util.h"
 #include "components/browser_sync/browser_sync_switches.h"
 #include "components/device_event_log/device_event_log.h"
 #include "components/metrics/metrics_service.h"
@@ -353,6 +355,14 @@
         CrosDBusService::CreateServiceProviderList(
             std::make_unique<DriveFileStreamServiceProvider>()));
 
+    if (arc::IsArcVmEnabled()) {
+      libvda_service_ = CrosDBusService::Create(
+          system_bus, libvda::kLibvdaServiceName,
+          dbus::ObjectPath(libvda::kLibvdaServicePath),
+          CrosDBusService::CreateServiceProviderList(
+              std::make_unique<LibvdaServiceProvider>()));
+    }
+
     // Initialize PowerDataCollector after DBusThreadManager is initialized.
     PowerDataCollector::Initialize();
     ProcessDataCollector::Initialize();
@@ -411,6 +421,7 @@
   std::unique_ptr<CrosDBusService> chrome_features_service_;
   std::unique_ptr<CrosDBusService> vm_applications_service_;
   std::unique_ptr<CrosDBusService> drive_file_stream_service_;
+  std::unique_ptr<CrosDBusService> libvda_service_;
 
   DISALLOW_COPY_AND_ASSIGN(DBusServices);
 };
diff --git a/chrome/browser/chromeos/dbus/libvda_service_provider.cc b/chrome/browser/chromeos/dbus/libvda_service_provider.cc
new file mode 100644
index 0000000..c6ed2d48
--- /dev/null
+++ b/chrome/browser/chromeos/dbus/libvda_service_provider.cc
@@ -0,0 +1,77 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/chromeos/dbus/libvda_service_provider.h"
+
+#include <memory>
+#include <utility>
+
+#include "base/bind.h"
+#include "chrome/browser/chromeos/arc/arc_session_manager.h"
+#include "chrome/browser/chromeos/arc/video/gpu_arc_video_service_host.h"
+#include "chrome/browser/profiles/profile.h"
+#include "dbus/bus.h"
+#include "dbus/message.h"
+#include "mojo/public/cpp/system/platform_handle.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
+
+namespace chromeos {
+
+LibvdaServiceProvider::LibvdaServiceProvider() : weak_ptr_factory_(this) {}
+
+LibvdaServiceProvider::~LibvdaServiceProvider() = default;
+
+void LibvdaServiceProvider::Start(
+    scoped_refptr<dbus::ExportedObject> exported_object) {
+  exported_object->ExportMethod(
+      libvda::kLibvdaServiceInterface, libvda::kProvideMojoConnectionMethod,
+      base::BindRepeating(&LibvdaServiceProvider::ProvideMojoConnection,
+                          weak_ptr_factory_.GetWeakPtr()),
+      base::BindRepeating(&LibvdaServiceProvider::OnExported,
+                          weak_ptr_factory_.GetWeakPtr()));
+}
+
+void LibvdaServiceProvider::OnExported(const std::string& interface_name,
+                                       const std::string& method_name,
+                                       bool success) {
+  LOG_IF(ERROR, !success) << "Failed to export " << interface_name << "."
+                          << method_name;
+}
+
+void LibvdaServiceProvider::ProvideMojoConnection(
+    dbus::MethodCall* method_call,
+    dbus::ExportedObject::ResponseSender response_sender) {
+  arc::ArcSessionManager* arc_session_manager = arc::ArcSessionManager::Get();
+  if (!arc_session_manager) {
+    response_sender.Run(dbus::ErrorResponse::FromMethodCall(
+        method_call, DBUS_ERROR_FAILED, "Could not find ARC session manager"));
+    return;
+  }
+  // LibvdaService will return the GpuArcVideoServiceHost instance that
+  // corresponds to the same profile used by ARC++. This might have to be
+  // changed if callers other than ARCVM use this service.
+  arc::GpuArcVideoServiceHost* gpu_arc_video_service_host =
+      arc::GpuArcVideoServiceHost::GetForBrowserContext(
+          arc_session_manager->profile());
+  gpu_arc_video_service_host->OnBootstrapVideoAcceleratorFactory(base::BindOnce(
+      &LibvdaServiceProvider::OnBootstrapVideoAcceleratorFactoryCallback,
+      weak_ptr_factory_.GetWeakPtr(), method_call, std::move(response_sender)));
+}
+
+void LibvdaServiceProvider::OnBootstrapVideoAcceleratorFactoryCallback(
+    dbus::MethodCall* method_call,
+    dbus::ExportedObject::ResponseSender response_sender,
+    mojo::ScopedHandle handle,
+    const std::string& pipe_name) {
+  base::ScopedFD fd = mojo::UnwrapPlatformHandle(std::move(handle)).TakeFD();
+
+  std::unique_ptr<dbus::Response> response =
+      dbus::Response::FromMethodCall(method_call);
+  dbus::MessageWriter writer(response.get());
+  writer.AppendFileDescriptor(fd.get());
+  writer.AppendString(pipe_name);
+  response_sender.Run(std::move(response));
+}
+
+}  // namespace chromeos
diff --git a/chrome/browser/chromeos/dbus/libvda_service_provider.h b/chrome/browser/chromeos/dbus/libvda_service_provider.h
new file mode 100644
index 0000000..a9c02cf
--- /dev/null
+++ b/chrome/browser/chromeos/dbus/libvda_service_provider.h
@@ -0,0 +1,61 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_CHROMEOS_DBUS_LIBVDA_SERVICE_PROVIDER_H_
+#define CHROME_BROWSER_CHROMEOS_DBUS_LIBVDA_SERVICE_PROVIDER_H_
+
+#include <string>
+
+#include "base/compiler_specific.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "chromeos/dbus/services/cros_dbus_service.h"
+#include "dbus/exported_object.h"
+#include "mojo/public/cpp/system/core.h"
+
+namespace dbus {
+class MethodCall;
+}
+
+namespace chromeos {
+
+// This class exports a D-Bus method that libvda will call to establish a
+// mojo pipe to the VideoAcceleratorFactory interface.
+class LibvdaServiceProvider : public CrosDBusService::ServiceProviderInterface {
+ public:
+  LibvdaServiceProvider();
+  ~LibvdaServiceProvider() override;
+
+  // CrosDBusService::ServiceProviderInterface overrides:
+  void Start(scoped_refptr<dbus::ExportedObject> exported_object) override;
+
+ private:
+  // Called from ExportedObject when a handler is exported as a D-Bus
+  // method or failed to be exported.
+  void OnExported(const std::string& interface_name,
+                  const std::string& method_name,
+                  bool success);
+
+  // Called on UI thread in response to D-Bus requests.
+  void ProvideMojoConnection(
+      dbus::MethodCall* method_call,
+      dbus::ExportedObject::ResponseSender response_sender);
+
+  void OnBootstrapVideoAcceleratorFactoryCallback(
+      dbus::MethodCall* method_call,
+      dbus::ExportedObject::ResponseSender response_sender,
+      mojo::ScopedHandle handle,
+      const std::string& s);
+
+  // Keep this last so that all weak pointers will be invalidated at the
+  // beginning of destruction.
+  base::WeakPtrFactory<LibvdaServiceProvider> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(LibvdaServiceProvider);
+};
+
+}  // namespace chromeos
+
+#endif  // CHROME_BROWSER_CHROMEOS_DBUS_LIBVDA_SERVICE_PROVIDER_H_
diff --git a/chrome/browser/chromeos/dbus/org.chromium.LibvdaService.conf b/chrome/browser/chromeos/dbus/org.chromium.LibvdaService.conf
new file mode 100644
index 0000000..c4aab88
--- /dev/null
+++ b/chrome/browser/chromeos/dbus/org.chromium.LibvdaService.conf
@@ -0,0 +1,23 @@
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+  "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<!--
+  Copyright 2019 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.
+-->
+<busconfig>
+  <policy user="chronos">
+    <allow own="org.chromium.LibvdaService"/>
+    <allow receive_sender="org.chromium.LibvdaService"
+           receive_interface="org.chromium.LibvdaService"/>
+  </policy>
+
+  <!--
+    libvda (via crosvm, running as root) uses this service to ask Chrome to
+    provide a mojo connection FD.
+  -->
+  <policy user="root">
+    <allow send_destination="org.chromium.LibvdaService"
+           send_interface="org.chromium.LibvdaService"/>
+  </policy>
+</busconfig>
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
index 80b07fb..a10c1d60 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -583,6 +583,7 @@
         TestCase("dirContextMenuPlayFiles"),
         TestCase("dirContextMenuUsbs"),
         TestCase("dirContextMenuFsp"),
+        TestCase("dirContextMenuDocumentsProvider").EnableDocumentsProvider(),
         TestCase("dirContextMenuShortcut")));
 
 WRAPPED_INSTANTIATE_TEST_SUITE_P(
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
index c12b008c..02c5b92 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
@@ -654,6 +654,8 @@
                                                  "text.txt", "hello.txt")
                     .SetMimeType("text/plain"));
 
+    CreateEntry(AddEntriesMessage::TestEntryInfo(AddEntriesMessage::DIRECTORY,
+                                                 "", "Folder"));
     base::RunLoop().RunUntilIdle();
     return true;
   }
diff --git a/chrome/browser/chromeos/login/hwid_checker.cc b/chrome/browser/chromeos/login/hwid_checker.cc
index 1dca2223..ed5eb44 100644
--- a/chrome/browser/chromeos/login/hwid_checker.cc
+++ b/chrome/browser/chromeos/login/hwid_checker.cc
@@ -8,6 +8,7 @@
 
 #include "base/command_line.h"
 #include "base/logging.h"
+#include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/system/sys_info.h"
 #include "chrome/common/chrome_switches.h"
@@ -88,12 +89,51 @@
 bool IsCorrectHWIDv3(const std::string& hwid) {
   if (IsExceptionalHWID(hwid))
     return false;
-  std::string regex =
-      "([A-Z0-9]+ (?:[A-Z2-7][2-9][A-Z2-7]-)*[A-Z2-7])([2-9][A-Z2-7])";
+
+  // HWIDv3 format:
+  //   Regular: "<MODEL> <COMPONENT><CHECKSUM>"
+  //   Extended: "<MODEL>-<RLZ> <CONFIGLESS> <COMPONENT><CHECKSUM>"
+  std::vector<std::string> parts =
+      base::SplitString(hwid, " ", base::WhitespaceHandling::TRIM_WHITESPACE,
+                        base::SplitResult::SPLIT_WANT_ALL);
   std::string not_checksum, checksum;
-  if (!RE2::FullMatch(hwid, regex, &not_checksum, &checksum))
+
+  constexpr char model[] = "[-A-Z0-9]+";
+  constexpr char configless_field[] = "(?:[[:xdigit:]]+-){3}[[:xdigit:]]+";
+  constexpr char component_and_checksum[] =
+      "(?:[A-Z2-7][2-9][A-Z2-7]-)*[A-Z2-7][2-9][A-Z2-7]";
+
+  int component_field_index;
+
+  if (parts.size() == 2) {
+    //   Regular: "<MODEL> <COMPONENT><CHECKSUM>"
+    if (!RE2::FullMatch(parts[0], model) ||
+        !RE2::FullMatch(parts[1], component_and_checksum)) {
+      return false;
+    }
+    component_field_index = 1;
+  } else if (parts.size() == 3) {
+    //   Extended: "<MODEL>-<RLZ> <CONFIGLESS> <COMPONENT><CHECKSUM>"
+    if (!RE2::FullMatch(parts[0], model) ||
+        !RE2::FullMatch(parts[1], configless_field) ||
+        !RE2::FullMatch(parts[2], component_and_checksum)) {
+      return false;
+    }
+    component_field_index = 2;
+  } else {
     return false;
-  base::RemoveChars(not_checksum, "-", &not_checksum);
+  }
+
+  // Modify component_field before computing checksum.
+  std::string& component_field = parts[component_field_index];
+  // Last 2 characters are checksum.
+  checksum = component_field.substr(component_field.size() - 2);
+  component_field = component_field.substr(0, component_field.size() - 2);
+  // When computing checksum, "-" is removed from component field.
+  base::RemoveChars(component_field, "-", &component_field);
+
+  // Construct not_checksum to compute checksum.
+  not_checksum = base::JoinString(parts, " ");
   return CalculateHWIDv3Checksum(not_checksum) == checksum;
 }
 
diff --git a/chrome/browser/chromeos/login/hwid_checker_unittest.cc b/chrome/browser/chromeos/login/hwid_checker_unittest.cc
index 2c08e79..3188ea5e 100644
--- a/chrome/browser/chromeos/login/hwid_checker_unittest.cc
+++ b/chrome/browser/chromeos/login/hwid_checker_unittest.cc
@@ -77,6 +77,9 @@
   EXPECT_TRUE(IsHWIDCorrect("SPRING E2B-C3D-E8X"));
   EXPECT_TRUE(IsHWIDCorrect("SPRING E2B-C3D-E8X-D8J"));
   EXPECT_TRUE(IsHWIDCorrect("FALCO B67-36Y"));
+  // New HWIDv3 extended format.
+  EXPECT_TRUE(
+      IsHWIDCorrect("SARIEN-MCOO 0-20-1DC-180 B2B-A6J-23P-43A-B2L-A7I"));
 
   // Exceptions.
   EXPECT_FALSE(IsHWIDCorrect("SPRING D2B-C3D-E5D"));
@@ -125,6 +128,10 @@
 
   EXPECT_TRUE(IsHWIDCorrect("SAMS ALEX GAMMA DVT 9247"));
   EXPECT_FALSE(IsHWIDCorrect("SAMS ALPX GAMMA DVT 9247"));
+
+  // New HWIDv3 extended format.
+  EXPECT_TRUE(
+      IsHWIDCorrect("SARIEN-MCOO 0-20-1DC-180 B2B-A6J-23P-43A-B2L-A7I"));
 }
 
 #if defined(GOOGLE_CHROME_BUILD)
diff --git a/chrome/browser/chromeos/login/saml/saml_browsertest.cc b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
index d4e64ce..78d2740 100644
--- a/chrome/browser/chromeos/login/saml/saml_browsertest.cc
+++ b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
@@ -455,16 +455,7 @@
 // Tests that signin frame should have 'saml' class and 'cancel' button is
 // visible when SAML IdP page is loaded. And 'cancel' button goes back to
 // gaia on clicking.
-//
-// Times out on CrOS MSAN. https://crbug.com/504141
-// Times out on CrOS ASAN/LSAN. https://crbug.com/830322
-#if defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER) || \
-    defined(ADDRESS_SANITIZER)
-#define MAYBE_SamlUI DISABLED_SamlUI
-#else
-#define MAYBE_SamlUI SamlUI
-#endif
-IN_PROC_BROWSER_TEST_F(SamlTest, MAYBE_SamlUI) {
+IN_PROC_BROWSER_TEST_F(SamlTest, SamlUI) {
   fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
   StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail);
 
@@ -495,14 +486,7 @@
 }
 
 // Tests the sign-in flow when the credentials passing API is used.
-//
-// Flaky. See http://crbug.com/659992
-#if defined(OS_LINUX)
-#define MAYBE_CredentialPassingAPI DISABLED_CredentialPassingAPI
-#else
-#define MAYBE_CredentialPassingAPI CredentialPassingAPI
-#endif
-IN_PROC_BROWSER_TEST_F(SamlTest, MAYBE_CredentialPassingAPI) {
+IN_PROC_BROWSER_TEST_F(SamlTest, CredentialPassingAPI) {
   fake_saml_idp()->SetLoginHTMLTemplate("saml_api_login.html");
   fake_saml_idp()->SetLoginAuthHTMLTemplate("saml_api_login_auth.html");
   StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail);
@@ -531,14 +515,7 @@
 }
 
 // Tests the single password scraped flow.
-//
-// Disabled since it's occasionally timed out: https://crbug.com/830322.
-#if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER)
-#define MAYBE_ScrapedSingle DISABLED_ScrapedSingle
-#else
-#define MAYBE_ScrapedSingle ScrapedSingle
-#endif
-IN_PROC_BROWSER_TEST_F(SamlTest, MAYBE_ScrapedSingle) {
+IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedSingle) {
   fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
   StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail);
 
@@ -570,14 +547,7 @@
 }
 
 // Tests password scraping from a dynamically created password field.
-//
-// Disabled since it's occasionally timed out: https://crbug.com/830322.
-#if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER)
-#define MAYBE_ScrapedDynamic DISABLED_ScrapedDynamic
-#else
-#define MAYBE_ScrapedDynamic ScrapedDynamic
-#endif
-IN_PROC_BROWSER_TEST_F(SamlTest, MAYBE_ScrapedDynamic) {
+IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedDynamic) {
   fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
   StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail);
 
@@ -603,14 +573,7 @@
 }
 
 // Tests the multiple password scraped flow.
-//
-// Disabled due to flakiness: crbug.com/834703
-#if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER)
-#define MAYBE_ScrapedMultiple DISABLED_ScrapedMultiple
-#else
-#define MAYBE_ScrapedMultiple ScrapedMultiple
-#endif
-IN_PROC_BROWSER_TEST_F(SamlTest, MAYBE_ScrapedMultiple) {
+IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedMultiple) {
   fake_saml_idp()->SetLoginHTMLTemplate("saml_login_two_passwords.html");
 
   StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail);
@@ -666,15 +629,7 @@
 // Types |bob@corp.example.com| into the GAIA login form but then authenticates
 // as |alice@corp.example.com| via SAML. Verifies that the logged-in user is
 // correctly identified as Alice.
-//
-// Disabled since it's occasionally timed out: https://crbug.com/830322.
-#if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER)
-#define MAYBE_UseAutenticatedUserEmailAddress \
-  DISABLED_UseAutenticatedUserEmailAddress
-#else
-#define MAYBE_UseAutenticatedUserEmailAddress UseAutenticatedUserEmailAddress
-#endif
-IN_PROC_BROWSER_TEST_F(SamlTest, MAYBE_UseAutenticatedUserEmailAddress) {
+IN_PROC_BROWSER_TEST_F(SamlTest, UseAutenticatedUserEmailAddress) {
   fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
   // Type |bob@corp.example.com| into the GAIA login form.
   StartSamlAndWaitForIdpPageLoad(kSecondSAMLUserEmail);
@@ -715,14 +670,7 @@
 
 // Tests the password confirm flow when more than one password is scraped: show
 // error on the first failure and fatal error on the second failure.
-//
-// Disabled since it's occasionally timed out: https://crbug.com/830322.
-#if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER)
-#define MAYBE_PasswordConfirmFlow DISABLED_PasswordConfirmFlow
-#else
-#define MAYBE_PasswordConfirmFlow PasswordConfirmFlow
-#endif
-IN_PROC_BROWSER_TEST_F(SamlTest, MAYBE_PasswordConfirmFlow) {
+IN_PROC_BROWSER_TEST_F(SamlTest, PasswordConfirmFlow) {
   fake_saml_idp()->SetLoginHTMLTemplate("saml_login_two_passwords.html");
   StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail);
 
@@ -756,14 +704,7 @@
 // Verifies that when the login flow redirects from one host to another, the
 // notice shown to the user is updated. This guards against regressions of
 // http://crbug.com/447818.
-//
-// Disabled since it's occasionally timed out: https://crbug.com/830322.
-#if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER)
-#define MAYBE_NoticeUpdatedOnRedirect DISABLED_NoticeUpdatedOnRedirect
-#else
-#define MAYBE_NoticeUpdatedOnRedirect NoticeUpdatedOnRedirect
-#endif
-IN_PROC_BROWSER_TEST_F(SamlTest, MAYBE_NoticeUpdatedOnRedirect) {
+IN_PROC_BROWSER_TEST_F(SamlTest, NoticeUpdatedOnRedirect) {
   // Start another https server at |kAdditionalIdPHost|.
   HTTPSForwarder saml_https_forwarder_2;
   ASSERT_TRUE(saml_https_forwarder_2.Initialize(
@@ -828,14 +769,7 @@
 // Verifies that when GAIA attempts to redirect to a page served over http, not
 // https, via an HTML meta refresh, the redirect is blocked and an error message
 // is shown. This guards against regressions of http://crbug.com/359515.
-//
-// Disabled since it's occasionally timed out: https://crbug.com/830322.
-#if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER)
-#define MAYBE_MetaRefreshToHTTPDisallowed DISABLED_MetaRefreshToHTTPDisallowed
-#else
-#define MAYBE_MetaRefreshToHTTPDisallowed MetaRefreshToHTTPDisallowed
-#endif
-IN_PROC_BROWSER_TEST_F(SamlTest, MAYBE_MetaRefreshToHTTPDisallowed) {
+IN_PROC_BROWSER_TEST_F(SamlTest, MetaRefreshToHTTPDisallowed) {
   const GURL url = embedded_test_server()->base_url().Resolve("/SSO");
   fake_saml_idp()->SetLoginHTMLTemplate("saml_login_instant_meta_refresh.html");
   fake_saml_idp()->SetRefreshURL(url);
@@ -922,13 +856,7 @@
   return content::WebContents::FromRenderFrameHost(frame_host);
 }
 
-// Flaky. See crbug.com/766953.
-#if defined(ADDRESS_SANITIZER)
-#define MAYBE_WithoutCredentialsPassingAPI DISABLED_WithoutCredentialsPassingAPI
-#else
-#define MAYBE_WithoutCredentialsPassingAPI WithoutCredentialsPassingAPI
-#endif
-IN_PROC_BROWSER_TEST_F(SAMLEnrollmentTest, MAYBE_WithoutCredentialsPassingAPI) {
+IN_PROC_BROWSER_TEST_F(SAMLEnrollmentTest, WithoutCredentialsPassingAPI) {
   fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
   StartSamlAndWaitForIdpPageLoad(kFirstSAMLUserEmail);
 
@@ -940,12 +868,6 @@
   OobeBaseTest::WaitForEnrollmentSuccess();
 }
 
-// Flaky. See crbug.com/766953.
-#if defined(ADDRESS_SANITIZER)
-#define MAYBE_WithCredentialsPassingAPI DISABLED_WithCredentialsPassingAPI
-#else
-#define MAYBE_WithCredentialsPassingAPI WithCredentialsPassingAPI
-#endif
 IN_PROC_BROWSER_TEST_F(SAMLEnrollmentTest, WithCredentialsPassingAPI) {
   fake_saml_idp()->SetLoginHTMLTemplate("saml_api_login.html");
   fake_saml_idp()->SetLoginAuthHTMLTemplate("saml_api_login_auth.html");
@@ -1353,19 +1275,7 @@
   EXPECT_EQ(kSAMLIdPCookieValue2, GetCookieValue(kSAMLIdPCookieName));
 }
 
-// PRE_TransferCookiesUnaffiliated and TransferCookiesUnaffiliated are flaky on
-// MSAN, ASAN, Debug due to time out - most likely, because of the general
-// slowness of the test. See crbug.com/683161, crbug.com/714167.
-#if defined(MEMORY_SANITIZER) || defined(ADDRESS_SANITIZER) || !defined(NDEBUG)
-#define MAYBE_PRE_TransferCookiesUnaffiliated \
-  DISABLED_PRE_TransferCookiesUnaffiliated
-#define MAYBE_TransferCookiesUnaffiliated DISABLED_TransferCookiesUnaffiliated
-#else
-#define MAYBE_PRE_TransferCookiesUnaffiliated PRE_TransferCookiesUnaffiliated
-#define MAYBE_TransferCookiesUnaffiliated TransferCookiesUnaffiliated
-#endif
-
-IN_PROC_BROWSER_TEST_F(SAMLPolicyTest, MAYBE_PRE_TransferCookiesUnaffiliated) {
+IN_PROC_BROWSER_TEST_F(SAMLPolicyTest, PRE_TransferCookiesUnaffiliated) {
   fake_saml_idp()->SetCookieValue(kSAMLIdPCookieValue1);
   LogInWithSAML(kDifferentDomainSAMLUserEmail, kTestAuthSIDCookie1,
                 kTestAuthLSIDCookie1);
@@ -1380,7 +1290,7 @@
 // IdP are not transferred to a user's profile on subsequent login if the user
 // does not belong to the domain that the device is enrolled into. Also verifies
 // that GAIA cookies are not transferred.
-IN_PROC_BROWSER_TEST_F(SAMLPolicyTest, MAYBE_TransferCookiesUnaffiliated) {
+IN_PROC_BROWSER_TEST_F(SAMLPolicyTest, TransferCookiesUnaffiliated) {
   fake_saml_idp()->SetCookieValue(kSAMLIdPCookieValue2);
   fake_saml_idp()->SetLoginHTMLTemplate("saml_login.html");
   ShowGAIALoginForm();
diff --git a/chrome/browser/chromeos/network_change_manager_client_browsertest.cc b/chrome/browser/chromeos/network_change_manager_client_browsertest.cc
index 0a93bbc..9b28770 100644
--- a/chrome/browser/chromeos/network_change_manager_client_browsertest.cc
+++ b/chrome/browser/chromeos/network_change_manager_client_browsertest.cc
@@ -113,8 +113,9 @@
 
 // Tests that network changes from shill are received by both the
 // NetworkChangeNotifier and NetworkConnectionTracker.
+// TODO(crbug.com/934583): Fix the flakiness.
 IN_PROC_BROWSER_TEST_F(NetworkChangeManagerClientBrowserTest,
-                       ReceiveNotifications) {
+                       DISABLED_ReceiveNotifications) {
   NetObserver net_observer;
   NetworkServiceObserver network_service_observer;
 
diff --git a/chrome/browser/extensions/api/automation_internal/automation_internal_api.cc b/chrome/browser/extensions/api/automation_internal/automation_internal_api.cc
index 255ab9d..3c17fc2 100644
--- a/chrome/browser/extensions/api/automation_internal/automation_internal_api.cc
+++ b/chrome/browser/extensions/api/automation_internal/automation_internal_api.cc
@@ -479,6 +479,7 @@
       break;
     }
     case api::automation::ACTION_TYPE_ANNOTATEPAGEIMAGES:
+    case api::automation::ACTION_TYPE_SIGNALENDOFTEST:
     case api::automation::ACTION_TYPE_NONE:
       break;
   }
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index cdae64be..e22e0fc 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -172,11 +172,6 @@
     "expiry_milestone": 75
   },
   {
-    "name": "ash-shelf-color",
-    // "owners": [ "your-team" ],
-    "expiry_milestone": 76
-  },
-  {
     "name": "ash-shelf-color-scheme",
     "owners": [ "manucornet" ],
     "expiry_milestone": 76
@@ -1247,6 +1242,11 @@
     "expiry_milestone": 76
   },
   {
+    "name": "enable-intent-picker",
+    "owners": [ "chromeos-apps-foundation-team@google.com" ],
+    "expiry_milestone": 78
+  },
+  {
     "name": "enable-javascript-harmony",
     // "owners": [ "your-team" ],
     "expiry_milestone": 76
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index abbbaaf..68cd4fe 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -2755,6 +2755,11 @@
 const char kHappinessTrackingSurveysForDesktopDescription[] =
     "Enable showing Happiness Tracking Surveys to users on Desktop";
 
+const char kIntentPickerName[] = "Intent picker";
+const char kIntentPickerDescription[] =
+    "When going to a site that has URL managable by a PWA, show the intent"
+    "picker to allow user to open the URL in the app.";
+
 const char kLinkManagedNoticeToChromeUIManagementURLName[] =
     "Link managed notice to the management page";
 const char kLinkManagedNoticeToChromeUIManagementURLDescription[] =
@@ -3031,11 +3036,6 @@
     "Enable unified desktop mode which allows a window to span multiple "
     "displays.";
 
-const char kAshShelfColorName[] = "Shelf color in Chrome OS system UI";
-const char kAshShelfColorDescription[] =
-    "Enables/disables the shelf color to be a derived from the wallpaper. The "
-    "--ash-shelf-color-scheme flag defines how that color is derived.";
-
 const char kAshShelfColorScheme[] = "Shelf color scheme in Chrome OS System UI";
 const char kAshShelfColorSchemeDescription[] =
     "Specify how the color is derived from the wallpaper. This flag is only "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 30e5268..1a036d3 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -1621,6 +1621,9 @@
 extern const char kHappinessTrackingSurveysForDesktopName[];
 extern const char kHappinessTrackingSurveysForDesktopDescription[];
 
+extern const char kIntentPickerName[];
+extern const char kIntentPickerDescription[];
+
 extern const char kLinkManagedNoticeToChromeUIManagementURLName[];
 extern const char kLinkManagedNoticeToChromeUIManagementURLDescription[];
 
diff --git a/chrome/browser/loader/cors_origin_access_list_browsertest.cc b/chrome/browser/loader/cors_origin_access_list_browsertest.cc
index bd26bb80..469fc93 100644
--- a/chrome/browser/loader/cors_origin_access_list_browsertest.cc
+++ b/chrome/browser/loader/cors_origin_access_list_browsertest.cc
@@ -41,34 +41,16 @@
 const char kTestHostInDifferentCase[] = "CrossOrigin.example.com";
 const char kTestSubdomainHost[] = "subdomain.crossorigin.example.com";
 
-enum class TestMode {
-  kOutOfBlinkCorsWithServicification,
-  kOutOfBlinkCorsWithoutServicification,
-};
-
 // Tests end to end functionality of CORS access origin allow lists.
-class CorsOriginAccessListBrowserTest
-    : public InProcessBrowserTest,
-      public testing::WithParamInterface<TestMode> {
+class CorsOriginAccessListBrowserTest : public InProcessBrowserTest {
  public:
   CorsOriginAccessListBrowserTest() {
-    switch (GetParam()) {
-      case TestMode::kOutOfBlinkCorsWithServicification:
-        scoped_feature_list_.InitWithFeatures(
-            // Enabled features
-            {network::features::kOutOfBlinkCors,
-             network::features::kNetworkService},
-            // Disabled features
-            {});
-        break;
-      case TestMode::kOutOfBlinkCorsWithoutServicification:
-        scoped_feature_list_.InitWithFeatures(
-            // Enabled features
-            {network::features::kOutOfBlinkCors},
-            // Disabled features
-            {network::features::kNetworkService});
-        break;
-    }
+    scoped_feature_list_.InitWithFeatures(
+        // Enabled features
+        {network::features::kOutOfBlinkCors,
+         network::features::kNetworkService},
+        // Disabled features
+        {});
   }
 
  protected:
@@ -164,7 +146,7 @@
 };
 
 // Tests if specifying only protocol allows all hosts to pass.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowAll) {
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest, AllowAll) {
   SetAllowList("http", "", kAllowSubdomains);
 
   std::unique_ptr<content::TitleWatcher> watcher = CreateWatcher();
@@ -175,7 +157,7 @@
 }
 
 // Tests if specifying only protocol allows all IP address based hosts to pass.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowAllForIp) {
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest, AllowAllForIp) {
   SetAllowList("http", "", kAllowSubdomains);
 
   std::unique_ptr<content::TitleWatcher> watcher = CreateWatcher();
@@ -188,7 +170,7 @@
 }
 
 // Tests if complete allow list set allows only exactly matched host to pass.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowExactHost) {
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest, AllowExactHost) {
   SetAllowList("http", kTestHost, kDisallowSubdomains);
 
   std::unique_ptr<content::TitleWatcher> watcher = CreateWatcher();
@@ -200,7 +182,7 @@
 
 // Tests if complete allow list set allows host that matches exactly, but in
 // case insensitive way to pass.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest,
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest,
                        AllowExactHostInCaseInsensitive) {
   SetAllowList("http", kTestHost, kDisallowSubdomains);
 
@@ -214,7 +196,7 @@
 
 // Tests if complete allow list set does not allow a host with a different port
 // to pass.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, BlockDifferentPort) {
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest, BlockDifferentPort) {
   SetAllowList("http", kTestHost, kDisallowSubdomains);
 
   std::unique_ptr<content::TitleWatcher> watcher = CreateWatcher();
@@ -225,7 +207,7 @@
 }
 
 // Tests if complete allow list set allows a subdomain to pass if it is allowed.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, AllowSubdomain) {
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest, AllowSubdomain) {
   SetAllowList("http", kTestHost, kAllowSubdomains);
 
   std::unique_ptr<content::TitleWatcher> watcher = CreateWatcher();
@@ -236,7 +218,7 @@
 }
 
 // Tests if complete allow list set does not allow a subdomain to pass.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest, BlockSubdomain) {
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest, BlockSubdomain) {
   SetAllowList("http", kTestHost, kDisallowSubdomains);
 
   std::unique_ptr<content::TitleWatcher> watcher = CreateWatcher();
@@ -248,7 +230,7 @@
 
 // Tests if complete allow list set does not allow a host with a different
 // protocol to pass.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest,
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest,
                        BlockDifferentProtocol) {
   SetAllowList("https", kTestHost, kDisallowSubdomains);
 
@@ -260,7 +242,7 @@
 }
 
 // Tests if IP address based hosts should not follow subdomain match rules.
-IN_PROC_BROWSER_TEST_P(CorsOriginAccessListBrowserTest,
+IN_PROC_BROWSER_TEST_F(CorsOriginAccessListBrowserTest,
                        SubdomainMatchShouldNotBeAppliedForIPAddress) {
   SetAllowList("http", "*.0.0.1", kAllowSubdomains);
 
@@ -273,17 +255,4 @@
   EXPECT_EQ(fail_string(), watcher->WaitAndGetTitle()) << GetReason();
 }
 
-INSTANTIATE_TEST_SUITE_P(
-    OutOfBlinkCorsWithServicification,
-    CorsOriginAccessListBrowserTest,
-    ::testing::Values(TestMode::kOutOfBlinkCorsWithServicification));
-
-INSTANTIATE_TEST_SUITE_P(
-    OutOfBlinkCorsWithoutServicification,
-    CorsOriginAccessListBrowserTest,
-    ::testing::Values(TestMode::kOutOfBlinkCorsWithoutServicification));
-
-// TODO(toyoshim): Instantiates tests for the case kOutOfBlinkCors is disabled
-// and remove relevant web tests if it's possible.
-
 }  // namespace
diff --git a/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer.cc
index a1b70bad..5433289 100644
--- a/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer.cc
@@ -57,6 +57,10 @@
     "InteractiveTiming.FirstInputDelay3.Subframe";
 const char kHistogramAMPSubframeFirstInputDelayFullNavigation[] =
     "InteractiveTiming.FirstInputDelay3.Subframe.FullNavigation";
+const char kHistogramAMPSubframeLayoutStabilityJankScore[] =
+    "Experimental.LayoutStability.JankScore.Subframe";
+const char kHistogramAMPSubframeLayoutStabilityJankScoreFullNavigation[] =
+    "Experimental.LayoutStability.JankScore.Subframe.FullNavigation";
 
 // Host pattern for AMP Cache URLs.
 // See https://developers.google.com/amp/cache/overview#amp-cache-url-format
@@ -320,6 +324,20 @@
   it->second.timing = timing.Clone();
 }
 
+void AMPPageLoadMetricsObserver::OnSubFrameRenderDataUpdate(
+    content::RenderFrameHost* subframe_rfh,
+    const page_load_metrics::mojom::PageRenderData& render_data,
+    const page_load_metrics::PageLoadExtraInfo& extra_info) {
+  if (subframe_rfh == nullptr)
+    return;
+
+  auto it = amp_subframe_info_.find(subframe_rfh);
+  if (it == amp_subframe_info_.end())
+    return;
+
+  it->second.render_data = render_data.Clone();
+}
+
 void AMPPageLoadMetricsObserver::OnComplete(
     const page_load_metrics::mojom::PageLoadTiming& timing,
     const page_load_metrics::PageLoadExtraInfo& info) {
@@ -483,6 +501,32 @@
     }
   }
 
+  if (!subframe_info.render_data.is_null()) {
+    // Clamp the score to a max of 10, which is equivalent to a frame with 10
+    // full-frame janks.
+    float clamped_jank_score =
+        std::min(subframe_info.render_data->layout_jank_score, 10.0f);
+
+    // For UKM, report (jank_score * 100) as an int in the range [0, 1000].
+    builder.SetSubFrame_LayoutStability_JankScore(
+        static_cast<int>(roundf(clamped_jank_score * 100.0f)));
+
+    // For UMA, report (jank_score * 10) an an int in the range [0,100].
+    int32_t uma_value = static_cast<int>(roundf(clamped_jank_score * 10.0f));
+    if (current_main_frame_nav_info_->is_same_document_navigation) {
+      UMA_HISTOGRAM_COUNTS_100(
+          std::string(kHistogramPrefix)
+              .append(kHistogramAMPSubframeLayoutStabilityJankScore),
+          uma_value);
+    } else {
+      UMA_HISTOGRAM_COUNTS_100(
+          std::string(kHistogramPrefix)
+              .append(
+                  kHistogramAMPSubframeLayoutStabilityJankScoreFullNavigation),
+          uma_value);
+    }
+  }
+
   builder.Record(ukm::UkmRecorder::Get());
 }
 
diff --git a/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer.h
index 35b984e..9a6c7d8 100644
--- a/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer.h
+++ b/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer.h
@@ -88,6 +88,10 @@
       content::RenderFrameHost* subframe_rfh,
       const page_load_metrics::mojom::PageLoadTiming& timing,
       const page_load_metrics::PageLoadExtraInfo& extra_info) override;
+  void OnSubFrameRenderDataUpdate(
+      content::RenderFrameHost* subframe_rfh,
+      const page_load_metrics::mojom::PageRenderData& render_data,
+      const page_load_metrics::PageLoadExtraInfo& extra_info) override;
   void OnComplete(const page_load_metrics::mojom::PageLoadTiming& timing,
                   const page_load_metrics::PageLoadExtraInfo& info) override;
 
@@ -124,8 +128,9 @@
     // iframe. Timestamps in |timing| below are relative to this value.
     base::TimeTicks navigation_start;
 
-    // Timing metrics observed in the AMP iframe.
+    // Performance metrics observed in the AMP iframe.
     page_load_metrics::mojom::PageLoadTimingPtr timing;
+    page_load_metrics::mojom::PageRenderDataPtr render_data;
   };
 
   void ProcessMainFrameNavigation(content::NavigationHandle* navigation_handle,
diff --git a/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer_unittest.cc
index 028ce4e0..63c2d0d 100644
--- a/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer_unittest.cc
+++ b/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer_unittest.cc
@@ -429,6 +429,41 @@
       entry.get(), "SubFrame.PaintTiming.NavigationToLargestContentPaint", 10);
 }
 
+TEST_F(AMPPageLoadMetricsObserverTest, SubFrameMetrics_LayoutStability) {
+  GURL amp_url("https://www.google.com/amp/page");
+
+  NavigationSimulator::CreateRendererInitiated(
+      GURL("https://www.google.com/search"), main_rfh())
+      ->Commit();
+
+  NavigationSimulator::CreateRendererInitiated(amp_url, main_rfh())
+      ->CommitSameDocument();
+
+  content::RenderFrameHost* subframe =
+      NavigationSimulator::NavigateAndCommitFromDocument(
+          GURL("https://cdn.ampproject.org/page"
+               "#viewerUrl=https%3A%2F%2Fwww.google.com%2Famp%2Fpage"),
+          content::RenderFrameHostTester::For(web_contents()->GetMainFrame())
+              ->AppendChild("subframe"));
+
+  page_load_metrics::mojom::PageRenderData render_data(1.0);
+  SimulateRenderDataUpdate(render_data, subframe);
+
+  // Navigate the main frame to trigger metrics recording.
+  NavigationSimulator::CreateRendererInitiated(
+      GURL("https://www.google.com/amp/other"), main_rfh())
+      ->CommitSameDocument();
+
+  histogram_tester().ExpectUniqueSample(
+      "PageLoad.Clients.AMP.Experimental.LayoutStability.JankScore.Subframe",
+      10, 1);
+
+  ukm::mojom::UkmEntryPtr entry = GetAmpPageLoadUkmEntry();
+  test_ukm_recorder().ExpectEntrySourceHasUrl(entry.get(), amp_url);
+  test_ukm_recorder().ExpectEntryMetric(
+      entry.get(), "SubFrame.LayoutStability.JankScore", 100);
+}
+
 TEST_F(AMPPageLoadMetricsObserverTest, SubFrameMetricsFullNavigation) {
   GURL amp_url("https://www.google.com/amp/page");
 
diff --git a/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.cc b/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.cc
index 78d8d7d5..e6b2d67a 100644
--- a/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.cc
+++ b/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.cc
@@ -86,6 +86,12 @@
   tester_->SimulateRenderDataUpdate(render_data);
 }
 
+void PageLoadMetricsObserverTestHarness::SimulateRenderDataUpdate(
+    const mojom::PageRenderData& render_data,
+    content::RenderFrameHost* render_frame_host) {
+  tester_->SimulateRenderDataUpdate(render_data, render_frame_host);
+}
+
 void PageLoadMetricsObserverTestHarness::SimulateLoadedResource(
     const ExtraRequestCompleteInfo& info) {
   tester_->SimulateLoadedResource(info, content::GlobalRequestID());
diff --git a/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h b/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h
index d76b19e..5297c047 100644
--- a/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h
+++ b/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h
@@ -87,6 +87,8 @@
       const std::vector<mojom::ResourceDataUpdatePtr>& resources,
       content::RenderFrameHost* render_frame_host);
   void SimulateRenderDataUpdate(const mojom::PageRenderData& render_data);
+  void SimulateRenderDataUpdate(const mojom::PageRenderData& render_data,
+                                content::RenderFrameHost* rfh);
 
   // Simulates a loaded resource. Main frame resources must specify a
   // GlobalRequestID, using the SimulateLoadedResource() method that takes a
diff --git a/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_tester.cc b/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_tester.cc
index 2b3c078f..b8a7844 100644
--- a/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_tester.cc
+++ b/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_tester.cc
@@ -97,10 +97,17 @@
 
 void PageLoadMetricsObserverTester::SimulateRenderDataUpdate(
     const mojom::PageRenderData& render_data) {
-  SimulatePageLoadTimingUpdate(
-      mojom::PageLoadTiming(), mojom::PageLoadMetadata(),
-      mojom::PageLoadFeatures(), render_data, mojom::CpuTiming(),
-      web_contents()->GetMainFrame());
+  SimulateRenderDataUpdate(render_data, web_contents()->GetMainFrame());
+}
+
+void PageLoadMetricsObserverTester::SimulateRenderDataUpdate(
+    const mojom::PageRenderData& render_data,
+    content::RenderFrameHost* rfh) {
+  mojom::PageLoadTiming timing;
+  InitPageLoadTimingForTest(&timing);
+  SimulatePageLoadTimingUpdate(timing, mojom::PageLoadMetadata(),
+                               mojom::PageLoadFeatures(), render_data,
+                               mojom::CpuTiming(), rfh);
 }
 
 void PageLoadMetricsObserverTester::SimulatePageLoadTimingUpdate(
diff --git a/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_tester.h b/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_tester.h
index 3b6c0f0..7c452999 100644
--- a/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_tester.h
+++ b/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_tester.h
@@ -58,6 +58,8 @@
       const std::vector<mojom::ResourceDataUpdatePtr>& resources,
       content::RenderFrameHost* render_frame_host);
   void SimulateRenderDataUpdate(const mojom::PageRenderData& render_data);
+  void SimulateRenderDataUpdate(const mojom::PageRenderData& render_data,
+                                content::RenderFrameHost* render_frame_host);
 
   // Simulates a loaded resource. Main frame resources must specify a
   // GlobalRequestID, using the SimulateLoadedResource() method that takes a
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_observer.h b/chrome/browser/page_load_metrics/page_load_metrics_observer.h
index c359ca7..aca5a80 100644
--- a/chrome/browser/page_load_metrics/page_load_metrics_observer.h
+++ b/chrome/browser/page_load_metrics/page_load_metrics_observer.h
@@ -414,6 +414,14 @@
                               const mojom::PageLoadTiming& timing,
                               const PageLoadExtraInfo& extra_info) {}
 
+  // OnRenderDataUpdate is triggered when an updated PageRenderData is available
+  // at the subframe level. This method may be called multiple times over the
+  // course of the page load.
+  virtual void OnSubFrameRenderDataUpdate(
+      content::RenderFrameHost* subframe_rfh,
+      const mojom::PageRenderData& render_data,
+      const PageLoadExtraInfo& extra_info) {}
+
   // Triggered when an updated CpuTiming is available at the page or subframe
   // level. This method is intended for monitoring cpu usage and load across
   // the frames on a page during navigation.
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_update_dispatcher.cc b/chrome/browser/page_load_metrics/page_load_metrics_update_dispatcher.cc
index d72eb269..26739c4 100644
--- a/chrome/browser/page_load_metrics/page_load_metrics_update_dispatcher.cc
+++ b/chrome/browser/page_load_metrics/page_load_metrics_update_dispatcher.cc
@@ -465,7 +465,7 @@
   } else {
     UpdateSubFrameMetadata(std::move(new_metadata));
     UpdateSubFrameTiming(render_frame_host, std::move(new_timing));
-    // TODO: Handle subframe PageRenderData.
+    UpdateSubFrameRenderData(render_frame_host, std::move(render_data));
   }
   client_->UpdateFeaturesUsage(render_frame_host, *new_features);
 }
@@ -618,6 +618,12 @@
   main_frame_render_data_ = std::move(render_data);
 }
 
+void PageLoadMetricsUpdateDispatcher::UpdateSubFrameRenderData(
+    content::RenderFrameHost* render_frame_host,
+    mojom::PageRenderDataPtr render_data) {
+  client_->OnSubFrameRenderDataChanged(render_frame_host, *render_data);
+}
+
 void PageLoadMetricsUpdateDispatcher::MaybeDispatchTimingUpdates(
     bool should_buffer_timing_update_callback) {
   // If we merged a new timing value, then we should buffer updates for
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_update_dispatcher.h b/chrome/browser/page_load_metrics/page_load_metrics_update_dispatcher.h
index 874cfd9..e1b519d 100644
--- a/chrome/browser/page_load_metrics/page_load_metrics_update_dispatcher.h
+++ b/chrome/browser/page_load_metrics/page_load_metrics_update_dispatcher.h
@@ -108,6 +108,9 @@
         const mojom::PageLoadTiming& timing) = 0;
     virtual void OnMainFrameMetadataChanged() = 0;
     virtual void OnSubframeMetadataChanged() = 0;
+    virtual void OnSubFrameRenderDataChanged(
+        content::RenderFrameHost* rfh,
+        const mojom::PageRenderData& render_data) = 0;
     virtual void UpdateFeaturesUsage(
         content::RenderFrameHost* rfh,
         const mojom::PageLoadFeatures& new_features) = 0;
@@ -171,6 +174,8 @@
   void UpdateSubFrameMetadata(mojom::PageLoadMetadataPtr subframe_metadata);
 
   void UpdateMainFrameRenderData(mojom::PageRenderDataPtr render_data);
+  void UpdateSubFrameRenderData(content::RenderFrameHost* render_frame_host,
+                                mojom::PageRenderDataPtr render_data);
 
   void MaybeDispatchTimingUpdates(bool did_merge_new_timing_value);
   void DispatchTimingUpdates();
diff --git a/chrome/browser/page_load_metrics/page_load_tracker.cc b/chrome/browser/page_load_metrics/page_load_tracker.cc
index 27c2c90..65b03af1 100644
--- a/chrome/browser/page_load_metrics/page_load_tracker.cc
+++ b/chrome/browser/page_load_metrics/page_load_tracker.cc
@@ -658,6 +658,16 @@
   }
 }
 
+void PageLoadTracker::OnSubFrameRenderDataChanged(
+    content::RenderFrameHost* rfh,
+    const mojom::PageRenderData& render_data) {
+  PageLoadExtraInfo extra_info(ComputePageLoadExtraInfo());
+  DCHECK(rfh->GetParent());
+  for (const auto& observer : observers_) {
+    observer->OnSubFrameRenderDataUpdate(rfh, render_data, extra_info);
+  }
+}
+
 void PageLoadTracker::OnMainFrameMetadataChanged() {
   PageLoadExtraInfo extra_info(ComputePageLoadExtraInfo());
   for (const auto& observer : observers_) {
diff --git a/chrome/browser/page_load_metrics/page_load_tracker.h b/chrome/browser/page_load_metrics/page_load_tracker.h
index e961984..fe65252 100644
--- a/chrome/browser/page_load_metrics/page_load_tracker.h
+++ b/chrome/browser/page_load_metrics/page_load_tracker.h
@@ -178,6 +178,9 @@
   void OnTimingChanged() override;
   void OnSubFrameTimingChanged(content::RenderFrameHost* rfh,
                                const mojom::PageLoadTiming& timing) override;
+  void OnSubFrameRenderDataChanged(
+      content::RenderFrameHost* rfh,
+      const mojom::PageRenderData& render_data) override;
   void OnMainFrameMetadataChanged() override;
   void OnSubframeMetadataChanged() override;
   void UpdateFeaturesUsage(
diff --git a/chrome/browser/resources/autofill_internals.html b/chrome/browser/resources/autofill_internals/autofill_internals.html
similarity index 100%
rename from chrome/browser/resources/autofill_internals.html
rename to chrome/browser/resources/autofill_internals/autofill_internals.html
diff --git a/chrome/browser/resources/chromeos/camera/.eslintrc.js b/chrome/browser/resources/chromeos/camera/.eslintrc.js
index db8ffc2..be7e5f6 100644
--- a/chrome/browser/resources/chromeos/camera/.eslintrc.js
+++ b/chrome/browser/resources/chromeos/camera/.eslintrc.js
@@ -147,6 +147,7 @@
   },
   'extends': 'eslint:recommended',
   'globals': {
+    'cros': 'readable',
     'ImageCapture': 'readable',
     'webkitRequestFileSystem': 'readable',
   },
diff --git a/chrome/browser/resources/chromeos/camera/BUILD.gn b/chrome/browser/resources/chromeos/camera/BUILD.gn
index 1acc259..0e89b06 100644
--- a/chrome/browser/resources/chromeos/camera/BUILD.gn
+++ b/chrome/browser/resources/chromeos/camera/BUILD.gn
@@ -7,6 +7,7 @@
 group("chrome_camera_app") {
   deps = [
     ":chrome_camera_app_base",
+    ":chrome_camera_app_mojo",
     "//chrome/browser/resources/chromeos/camera/src/strings:camera_strings",
   ]
 }
@@ -25,3 +26,21 @@
     "$chrome_camera_app_dir/{{source_file_part}}",
   ]
 }
+
+copy("chrome_camera_app_mojo") {
+  sources = [
+    "$root_gen_dir/media/capture/mojom/image_capture.mojom-lite.js",
+    "$root_gen_dir/media/capture/video/chromeos/mojo/cros_image_capture.mojom-lite.js",
+    "$root_gen_dir/mojo/public/js/mojo_bindings_lite.js",
+  ]
+
+  deps = [
+    "//media/capture/mojom:image_capture_js",
+    "//media/capture/video/chromeos/mojo:cros_camera_js",
+    "//mojo/public/js:bindings_lite",
+  ]
+
+  outputs = [
+    "$chrome_camera_app_dir/js/mojo/{{source_file_part}}",
+  ]
+}
diff --git a/chrome/browser/resources/chromeos/camera/src/js/mojo/imagecapture.js b/chrome/browser/resources/chromeos/camera/src/js/mojo/imagecapture.js
new file mode 100644
index 0000000..712c8c82
--- /dev/null
+++ b/chrome/browser/resources/chromeos/camera/src/js/mojo/imagecapture.js
@@ -0,0 +1,90 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+'use strict';
+
+/**
+ * Namespace for the Camera app.
+ */
+var cca = cca || {};
+
+/**
+ * Namespace for mojo.
+ */
+cca.mojo = cca.mojo || {};
+
+/**
+ * Type definition for cca.mojo.PhotoCapabilities.
+ * @typedef {PhotoCapabilities} cca.mojo.PhotoCapabilities
+ * @property {Array<string>} [supportedEffects]
+ */
+cca.mojo.PhotoCapabilities;
+
+/**
+ * Creates the wrapper of JS image-capture and Mojo image-capture.
+ * @param {MediaStreamTrack} videoTrack A video track whose still images will be
+ *     taken.
+ * @constructor
+ */
+cca.mojo.ImageCapture = function(videoTrack) {
+  /**
+   * @type {ImageCapture}
+   * @private
+   */
+  this.capture_ = new ImageCapture(videoTrack);
+
+  /**
+   * @type {cros.mojom.CrosImageCaptureProxy}
+   * @private
+   */
+  this.mojoCapture_ = cros.mojom.CrosImageCapture.getProxy();
+
+  // End of properties, seal the object.
+  Object.seal(this);
+};
+
+/**
+ * Gets the photo capabilities with the available options/effects.
+ * @return {Promise<cca.mojo.PhotoCapabilities>} Promise for the result.
+ */
+cca.mojo.ImageCapture.prototype.getPhotoCapabilities = function() {
+  return Promise
+      .all([
+        this.capture_.getPhotoCapabilities(),
+        this.mojoCapture_.getSupportedEffects(),
+      ])
+      .then(([capabilities, effects]) => {
+        capabilities.supportedEffects = effects.supportedEffects;
+        return capabilities;
+      });
+};
+
+/**
+ * Takes single or multiple photo(s) with the specified settings and effects.
+ * The amount of result photo(s) depends on the specified settings and effects,
+ * and the first promise in the returned array will always resolve with the
+ * unreprocessed photo.
+ * @param {?Object} photoSettings Photo settings for ImageCapture's takePhoto().
+ * @param {?Array<cros.mojom.Effect>} photoEffects Photo effects to be applied.
+ * @return {Array<Promise<Blob>>} Array of promises for the result.
+ */
+cca.mojo.ImageCapture.prototype.takePhoto = function(
+    photoSettings, photoEffects) {
+  const takes = [];
+  if (photoEffects) {
+    photoEffects.forEach((effect) => {
+      takes.push((this.mojoCapture_.setReprocessOption(effect))
+                     .then(({status, blob}) => {
+                       if (status != 0) {
+                         throw new Error('Mojo image capture error: ' + status);
+                       }
+                       const {data, mimeType} = blob;
+                       return new Blob(
+                           [new Uint8Array(data)], {type: mimeType});
+                     }));
+    });
+  }
+  takes.splice(0, 0, this.capture_.takePhoto(photoSettings));
+  return takes;
+};
diff --git a/chrome/browser/resources/ntp4/BUILD.gn b/chrome/browser/resources/ntp4/BUILD.gn
index 7bd9966..af3b6cc 100644
--- a/chrome/browser/resources/ntp4/BUILD.gn
+++ b/chrome/browser/resources/ntp4/BUILD.gn
@@ -23,7 +23,6 @@
     "//ui/webui/resources/js/cr/ui/bubble.js",
     "//ui/webui/resources/js/cr/ui/card_slider.js",
     "//ui/webui/resources/js/cr/ui/command.js",
-    "//ui/webui/resources/js/cr/ui/context_menu_button.js",
     "//ui/webui/resources/js/cr/ui/context_menu_handler.js",
     "//ui/webui/resources/js/cr/ui/drag_wrapper.js",
     "//ui/webui/resources/js/cr/ui/expandable_bubble.js",
diff --git a/chrome/browser/resources/ntp4/new_tab.html b/chrome/browser/resources/ntp4/new_tab.html
index d6f57b23..1a017b05 100644
--- a/chrome/browser/resources/ntp4/new_tab.html
+++ b/chrome/browser/resources/ntp4/new_tab.html
@@ -49,7 +49,6 @@
 <script src="../../../../ui/webui/resources/js/cr/ui/menu.js"></script>
 <script src="../../../../ui/webui/resources/js/cr/ui/position_util.js"></script>
 <script src="../../../../ui/webui/resources/js/cr/ui/menu_button.js"></script>
-<script src="../../../../ui/webui/resources/js/cr/ui/context_menu_button.js"></script>
 <script src="../../../../ui/webui/resources/js/cr/ui/touch_handler.js"></script>
 
 <script src="tile_page.js"></script>
diff --git a/chrome/browser/resources/settings/device_page/display.html b/chrome/browser/resources/settings/device_page/display.html
index bbc54c4..0c4e163 100644
--- a/chrome/browser/resources/settings/device_page/display.html
+++ b/chrome/browser/resources/settings/device_page/display.html
@@ -210,9 +210,9 @@
               aria-labelledby="displayOrientation"
               on-change="onOrientationChange_">
             <option value="0">$i18n{displayOrientationStandard}</option>
-            <option value="90">90</option>
-            <option value="180">180</option>
-            <option value="270">270</option>
+            <option value="90">90&deg;</option>
+            <option value="180">180&deg;</option>
+            <option value="270">270&deg;</option>
           </select>
         </div>
       </template>
diff --git a/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.html b/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.html
index 6c65e29..4c86af0c 100644
--- a/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.html
+++ b/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.html
@@ -26,14 +26,18 @@
       <div slot="dialog-body" scrollable>
         <div class="settings-box first two-line">
           <cr-input class="printer-name-input" autofocus
+              id="printerName"
               value="{{activePrinter.printerName}}"
+              on-value-changed="onPrinterInfoChange_"
               label="$i18n{printerName}"
               maxlength=64>
           </cr-input>
         </div>
         <div class="settings-box two-line">
           <cr-input label="$i18n{printerAddress}"
+              id="printerAddress"
               value="{{activePrinter.printerAddress}}"
+              on-value-changed="onPrinterInfoChange_"
               disabled="[[!networkProtocolActive_]]"
               maxlength=128>
           </cr-input>
diff --git a/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js b/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js
index 17d358c..64d976cf 100644
--- a/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js
+++ b/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js
@@ -28,6 +28,17 @@
      */
     existingUserPPDMessage_: String,
 
+    /**
+     * If the printer info has changed since loading this dialog. This will
+     * only track the freeform input fields, since the other fields contain
+     * input selected from dropdown menus.
+     * @private
+     */
+    printerInfoChanged_: {
+      type: Boolean,
+      value: false,
+    },
+
     networkProtocolActive_: {
       type: Boolean,
       computed: 'isNetworkProtocol_(activePrinter.printerProtocol)',
@@ -35,7 +46,7 @@
   },
 
   observers: [
-    'printerInfoChanged_(activePrinter.*)',
+    'printerPathChanged_(activePrinter.*)',
   ],
 
   /** @override */
@@ -56,7 +67,7 @@
    * @param {!{path: string, value: string}} change
    * @private
    */
-  printerInfoChanged_: function(change) {
+  printerPathChanged_: function(change) {
     if (change.path != 'activePrinter.printerName') {
       this.needsReconfigured_ = true;
     }
@@ -71,6 +82,11 @@
   },
 
   /** @private */
+  onPrinterInfoChange_: function() {
+    this.printerInfoChanged_ = true;
+  },
+
+  /** @private */
   onCancelTap_: function() {
     this.$$('add-printer-dialog').close();
   },
@@ -143,9 +159,10 @@
    * @private
    */
   canSavePrinter_: function() {
-    return settings.printing.isNameAndAddressValid(this.activePrinter) &&
-        settings.printing.isPPDInfoValid(
-            this.activePrinter.ppdManufacturer, this.activePrinter.ppdModel,
-            this.activePrinter.printerPPDPath);
+    return !this.printerInfoChanged_ ||
+        (settings.printing.isNameAndAddressValid(this.activePrinter) &&
+         settings.printing.isPPDInfoValid(
+             this.activePrinter.ppdManufacturer, this.activePrinter.ppdModel,
+             this.activePrinter.printerPPDPath));
   },
 });
diff --git a/chrome/browser/resources/settings/settings_main/settings_main.html b/chrome/browser/resources/settings/settings_main/settings_main.html
index 1e1fc08b..1f40668c 100644
--- a/chrome/browser/resources/settings/settings_main/settings_main.html
+++ b/chrome/browser/resources/settings/settings_main/settings_main.html
@@ -18,7 +18,7 @@
 
 <dom-module id="settings-main">
   <template>
-    <style include="cr-hidden-style">
+    <style include="cr-hidden-style settings-shared">
       #overscroll {
         margin-top: 64px;
       }
diff --git a/chrome/browser/resources/welcome/dice_welcome/welcome.css b/chrome/browser/resources/welcome/dice_welcome/welcome.css
index 07febed0..e3641d8 100644
--- a/chrome/browser/resources/welcome/dice_welcome/welcome.css
+++ b/chrome/browser/resources/welcome/dice_welcome/welcome.css
@@ -14,6 +14,11 @@
   text-align: center;
 }
 
+[dark] body {
+  background: var(--md-background-color);
+  color: var(--cr-secondary-text-color);
+}
+
 .watermark {
   -webkit-mask-image: url(chrome://resources/images/google_logo.svg);
   -webkit-mask-repeat: no-repeat;
@@ -26,6 +31,10 @@
   width: 74px;
 }
 
+[dark] .watermark {
+  background: var(--cr-secondary-text-color);
+}
+
 @media(max-height: 608px) {
   .watermark {
     display: none;
diff --git a/chrome/browser/resources/welcome/dice_welcome/welcome.html b/chrome/browser/resources/welcome/dice_welcome/welcome.html
index 03f237ae..f9fc786 100644
--- a/chrome/browser/resources/welcome/dice_welcome/welcome.html
+++ b/chrome/browser/resources/welcome/dice_welcome/welcome.html
@@ -1,18 +1,22 @@
 <!doctype html>
-<html dir="$i18n{textdirection}" lang="$i18n{language}">
+<html dir="$i18n{textdirection}" lang="$i18n{language}" $i18n{dark}>
   <head>
     <meta charset="utf-8">
     <title>$i18n{headerText}</title>
 
     <link rel="import" href="chrome://resources/html/polymer.html">
+
+    <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
     <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
     <link rel="import" href="welcome_app.html">
 
+    <link rel="stylesheet" href="chrome://resources/css/md_colors.css">
     <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css">
     <link rel="stylesheet" href="chrome://welcome/welcome.css">
   </head>
   <body>
     <welcome-app></welcome-app>
     <div class="watermark"></div>
+    <link rel="import" href="chrome://resources/html/dark_mode.html">
   </body>
 </html>
diff --git a/chrome/browser/resources/welcome/dice_welcome/welcome_app.html b/chrome/browser/resources/welcome/dice_welcome/welcome_app.html
index d56baed..6dc83f1 100644
--- a/chrome/browser/resources/welcome/dice_welcome/welcome_app.html
+++ b/chrome/browser/resources/welcome/dice_welcome/welcome_app.html
@@ -102,6 +102,10 @@
         position: relative;
       }
 
+      :host-context([dark]) .heading-container {
+        color: var(--cr-primary-text-color);
+      }
+
       .heading {
         animation: fadeOutAndSlideUp 600ms 2.1s cubic-bezier(.4, .2, 0, 1) forwards;
         /* Makes sure fading-in/out doesn't impact the logo position. */
@@ -174,4 +178,4 @@
     </div>
   </template>
   <script src="welcome_app.js"></script>
-</dom-module>
\ No newline at end of file
+</dom-module>
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/ntp_background/nux_ntp_background.js b/chrome/browser/resources/welcome/onboarding_welcome/ntp_background/nux_ntp_background.js
index 5cc7999e..5c6e880 100644
--- a/chrome/browser/resources/welcome/onboarding_welcome/ntp_background/nux_ntp_background.js
+++ b/chrome/browser/resources/welcome/onboarding_welcome/ntp_background/nux_ntp_background.js
@@ -203,5 +203,9 @@
     this.finalized_ = true;
     this.metricsManager_.recordNoThanks();
     welcome.navigateToNextStep();
+
+    if (this.hasValidSelectedBackground_()) {
+      this.fire('iron-announce', {text: this.i18n('ntpBackgroundReset')});
+    }
   },
 });
diff --git a/chrome/browser/send_tab_to_self/desktop_notification_handler.cc b/chrome/browser/send_tab_to_self/desktop_notification_handler.cc
index d22ce2b5..aa4d17c 100644
--- a/chrome/browser/send_tab_to_self/desktop_notification_handler.cc
+++ b/chrome/browser/send_tab_to_self/desktop_notification_handler.cc
@@ -55,10 +55,12 @@
       NotificationHandler::Type::SEND_TAB_TO_SELF, notification);
 }
 
-void DesktopNotificationHandler::DismissEntry(const SendTabToSelfEntry* entry) {
-  const std::string& guid = entry->GetGUID();
-  NotificationDisplayServiceFactory::GetForProfile(profile_)->Close(
-      NotificationHandler::Type::SEND_TAB_TO_SELF, guid);
+void DesktopNotificationHandler::DismissEntries(
+    const std::vector<std::string>& guids) {
+  for (const std::string& guid : guids) {
+    NotificationDisplayServiceFactory::GetForProfile(profile_)->Close(
+        NotificationHandler::Type::SEND_TAB_TO_SELF, guid);
+  }
 }
 
 void DesktopNotificationHandler::OnClose(Profile* profile,
diff --git a/chrome/browser/send_tab_to_self/desktop_notification_handler.h b/chrome/browser/send_tab_to_self/desktop_notification_handler.h
index 40f4449..cb4cd86 100644
--- a/chrome/browser/send_tab_to_self/desktop_notification_handler.h
+++ b/chrome/browser/send_tab_to_self/desktop_notification_handler.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_SEND_TAB_TO_SELF_DESKTOP_NOTIFICATION_HANDLER_H_
 
 #include <string>
+#include <vector>
 
 #include "chrome/browser/notifications/notification_handler.h"
 #include "chrome/browser/send_tab_to_self/receiving_ui_handler.h"
@@ -27,7 +28,7 @@
 
   // ReceivingUiHandler implementation.
   void DisplayNewEntry(const SendTabToSelfEntry* entry) override;
-  void DismissEntry(const SendTabToSelfEntry* entry) override;
+  void DismissEntries(const std::vector<std::string>& guids) override;
 
   // NotificationHandler implementation.
   void OnClose(Profile* profile,
diff --git a/chrome/browser/send_tab_to_self/receiving_ui_handler.h b/chrome/browser/send_tab_to_self/receiving_ui_handler.h
index 36ba233f..65bd57053 100644
--- a/chrome/browser/send_tab_to_self/receiving_ui_handler.h
+++ b/chrome/browser/send_tab_to_self/receiving_ui_handler.h
@@ -5,7 +5,7 @@
 #ifndef CHROME_BROWSER_SEND_TAB_TO_SELF_RECEIVING_UI_HANDLER_H_
 #define CHROME_BROWSER_SEND_TAB_TO_SELF_RECEIVING_UI_HANDLER_H_
 
-#include <memory>
+#include <string>
 #include <vector>
 
 namespace send_tab_to_self {
@@ -29,7 +29,7 @@
   // modified by any implementors of this class.
   // TODO(crbug.com/935719): Figure out whether we need to pass the entire entry
   // or we can pass a smaller subset of information.
-  virtual void DismissEntry(const SendTabToSelfEntry* entry) = 0;
+  virtual void DismissEntries(const std::vector<std::string>& guids) = 0;
 };
 
 }  // namespace send_tab_to_self
diff --git a/chrome/browser/send_tab_to_self/send_tab_to_self_client_service.cc b/chrome/browser/send_tab_to_self/send_tab_to_self_client_service.cc
index abecc76..99630c7 100644
--- a/chrome/browser/send_tab_to_self/send_tab_to_self_client_service.cc
+++ b/chrome/browser/send_tab_to_self/send_tab_to_self_client_service.cc
@@ -6,14 +6,13 @@
 
 #include <memory>
 #include <string>
+#include <vector>
 
 #include "base/logging.h"
 #include "chrome/browser/send_tab_to_self/receiving_ui_handler.h"
 #include "chrome/browser/send_tab_to_self/receiving_ui_handler_registry.h"
 #include "components/send_tab_to_self/send_tab_to_self_model.h"
 
-class Profile;
-
 namespace send_tab_to_self {
 
 SendTabToSelfClientService::SendTabToSelfClientService(
@@ -47,7 +46,10 @@
 
 void SendTabToSelfClientService::EntriesRemovedRemotely(
     const std::vector<std::string>& guids) {
-  // Do nothing for now
+  for (std::unique_ptr<ReceivingUiHandler>& handler :
+       registry_->GetHandlers()) {
+    handler->DismissEntries(guids);
+  }
 }
 
 }  // namespace send_tab_to_self
diff --git a/chrome/browser/send_tab_to_self/send_tab_to_self_client_service.h b/chrome/browser/send_tab_to_self/send_tab_to_self_client_service.h
index 72e6f14..4fc750e 100644
--- a/chrome/browser/send_tab_to_self/send_tab_to_self_client_service.h
+++ b/chrome/browser/send_tab_to_self/send_tab_to_self_client_service.h
@@ -20,8 +20,8 @@
 class SendTabToSelfEntry;
 class SendTabToSelfModel;
 
-// Singleton that owns all SendTabToSelfClientServices and associates them with
-// Profile.
+// Service that listens for SendTabToSelf model changes and calls UI
+// handlers to update the UI accordingly.
 class SendTabToSelfClientService : public KeyedService,
                                    public SendTabToSelfModelObserver {
  public:
diff --git a/chrome/browser/ssl/ssl_browsertest.cc b/chrome/browser/ssl/ssl_browsertest.cc
index 969a272..95a6daf 100644
--- a/chrome/browser/ssl/ssl_browsertest.cc
+++ b/chrome/browser/ssl/ssl_browsertest.cc
@@ -7227,36 +7227,6 @@
                 frame->GetProcess()->GetID(), frame->GetRoutingID()));
 }
 
-IN_PROC_BROWSER_TEST_P(SSLUITest, NetworkErrorDoesntRevokeExemptions) {
-  ASSERT_TRUE(https_server_expired_.Start());
-  GURL expired_url = https_server_expired_.GetURL("/title1.html");
-  int server_port = expired_url.IntPort();
-
-  // Navigate to the expired cert URL, make sure we get an interstitial.
-  ui_test_utils::NavigateToURL(browser(), expired_url);
-  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
-  EXPECT_TRUE(IsShowingInterstitial(tab));
-
-  // Click through the interstitial.
-  ProceedThroughInterstitial(tab);
-
-  // Shut down the server and navigate again to cause a network error.
-  ASSERT_TRUE(https_server_expired_.ShutdownAndWaitUntilComplete());
-  ui_test_utils::NavigateToURL(browser(), expired_url);
-
-  // Create a new server in the same url (including port), the certificate
-  // should still be invalid.
-  net::EmbeddedTestServer new_https_server(net::EmbeddedTestServer::TYPE_HTTPS);
-  new_https_server.SetSSLConfig(net::EmbeddedTestServer::CERT_EXPIRED);
-  new_https_server.AddDefaultHandlers(base::FilePath(kDocRoot));
-  ASSERT_TRUE(new_https_server.Start(server_port));
-
-  ui_test_utils::NavigateToURL(browser(), expired_url);
-
-  // We shouldn't get an interstitial this time.
-  EXPECT_FALSE(IsShowingInterstitial(tab));
-}
-
 // This SPKI hash is from a self signed certificate generated using the
 // following openssl command:
 //  openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes
diff --git a/chrome/browser/ssl/ssl_error_navigation_throttle.cc b/chrome/browser/ssl/ssl_error_navigation_throttle.cc
index 0f2621c..006cc7c4 100644
--- a/chrome/browser/ssl/ssl_error_navigation_throttle.cc
+++ b/chrome/browser/ssl/ssl_error_navigation_throttle.cc
@@ -36,10 +36,11 @@
 SSLErrorNavigationThrottle::WillFailRequest() {
   DCHECK(base::FeatureList::IsEnabled(features::kSSLCommittedInterstitials));
   content::NavigationHandle* handle = navigation_handle();
-
-  // Check the network error code in case we are here due to a non-ssl related
-  // error
-  if (!net::IsCertificateError(handle->GetNetErrorCode())) {
+  const net::SSLInfo info = handle->GetSSLInfo().value_or(net::SSLInfo());
+  // If there was no certificate error, SSLInfo will be empty.
+  int cert_status = info.cert_status;
+  if (!net::IsCertStatusError(cert_status) ||
+      net::IsCertStatusMinorError(cert_status)) {
     return content::NavigationThrottle::PROCEED;
   }
 
@@ -49,8 +50,6 @@
     return content::NavigationThrottle::PROCEED;
   }
 
-  const net::SSLInfo info = handle->GetSSLInfo().value_or(net::SSLInfo());
-  int cert_status = info.cert_status;
   QueueShowInterstitial(std::move(handle_ssl_error_callback_),
                         handle->GetWebContents(), cert_status, info,
                         handle->GetURL(), std::move(ssl_cert_reporter_));
diff --git a/chrome/browser/ssl/ssl_error_navigation_throttle_unittest.cc b/chrome/browser/ssl/ssl_error_navigation_throttle_unittest.cc
index c00f983f..a82c435 100644
--- a/chrome/browser/ssl/ssl_error_navigation_throttle_unittest.cc
+++ b/chrome/browser/ssl/ssl_error_navigation_throttle_unittest.cc
@@ -92,6 +92,7 @@
 
     handle_ = std::make_unique<content::MockNavigationHandle>(web_contents());
     handle_->set_has_committed(true);
+    handle_->set_net_error_code(net::ERR_CERT_INVALID);
     async_ = GetParam();
     throttle_ = std::make_unique<TestSSLErrorNavigationThrottle>(
         handle_.get(), async_,
@@ -121,19 +122,35 @@
   DISALLOW_COPY_AND_ASSIGN(SSLErrorNavigationThrottleTest);
 };
 
-// Tests that the throttle ignores a request with a non SSL related network
-// error code.
-TEST_P(SSLErrorNavigationThrottleTest, NoSSLError) {
+// Tests that the throttle ignores a request without SSL info.
+TEST_P(SSLErrorNavigationThrottleTest, NoSSLInfo) {
   SCOPED_TRACE(::testing::Message()
                << "Asynchronous MockHandleSSLError: " << async_);
 
-  handle_->set_net_error_code(net::ERR_BLOCKED_BY_CLIENT);
   content::NavigationThrottle::ThrottleCheckResult result =
       throttle_->WillFailRequest();
+
+  EXPECT_FALSE(handle_->GetSSLInfo().has_value());
   EXPECT_EQ(content::NavigationThrottle::PROCEED, result);
 }
 
-// Tests that the throttle defers and cancels a request with a net error that
+// Tests that the throttle ignores a request with a cert status that is not an
+// cert error.
+TEST_P(SSLErrorNavigationThrottleTest, SSLInfoWithoutCertError) {
+  SCOPED_TRACE(::testing::Message()
+               << "Asynchronous MockHandleSSLError: " << async_);
+
+  net::SSLInfo ssl_info;
+  ssl_info.cert_status = net::CERT_STATUS_IS_EV;
+  handle_->set_ssl_info(ssl_info);
+  content::NavigationThrottle::ThrottleCheckResult result =
+      throttle_->WillFailRequest();
+
+  EXPECT_EQ(net::CERT_STATUS_IS_EV, handle_->GetSSLInfo()->cert_status);
+  EXPECT_EQ(content::NavigationThrottle::PROCEED, result);
+}
+
+// Tests that the throttle defers and cancels a request with a cert status that
 // is a cert error.
 TEST_P(SSLErrorNavigationThrottleTest, SSLInfoWithCertError) {
   SCOPED_TRACE(::testing::Message()
@@ -143,7 +160,6 @@
   ssl_info.cert =
       net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem");
   ssl_info.cert_status = net::CERT_STATUS_COMMON_NAME_INVALID;
-  handle_->set_net_error_code(net::ERR_CERT_INVALID);
   handle_->set_ssl_info(ssl_info);
   content::NavigationThrottle::ThrottleCheckResult synchronous_result =
       throttle_->WillFailRequest();
diff --git a/chrome/browser/sync/test/integration/migration_test.cc b/chrome/browser/sync/test/integration/migration_test.cc
index 955c4ed..04cc69d4 100644
--- a/chrome/browser/sync/test/integration/migration_test.cc
+++ b/chrome/browser/sync/test/integration/migration_test.cc
@@ -74,7 +74,7 @@
   explicit MigrationTest(TestType test_type) : SyncTest(test_type) {}
   ~MigrationTest() override {}
 
-  enum TriggerMethod { MODIFY_PREF, MODIFY_BOOKMARK, TRIGGER_NOTIFICATION };
+  enum TriggerMethod { MODIFY_PREF, MODIFY_BOOKMARK, TRIGGER_REFRESH };
 
   // Set up sync for all profiles and initialize all MigrationWatchers. This
   // helps ensure that all migration events are captured, even if they were to
@@ -152,8 +152,8 @@
       case MODIFY_BOOKMARK:
         ASSERT_TRUE(AddURL(0, IndexedURLTitle(0), GURL(IndexedURL(0))));
         break;
-      case TRIGGER_NOTIFICATION:
-        TriggerNotification(model_types);
+      case TRIGGER_REFRESH:
+        TriggerSyncForModelTypes(/*index=*/0, model_types);
         break;
       default:
         ADD_FAILURE();
@@ -173,15 +173,6 @@
   // trigger method.
   void RunMigrationTest(const MigrationList& migration_list,
                         TriggerMethod trigger_method) {
-    // If we have only one client, turn off notifications to avoid the
-    // possibility of spurious sync cycles.
-    bool do_test_without_notifications =
-        (trigger_method != TRIGGER_NOTIFICATION && num_clients() == 1);
-
-    if (do_test_without_notifications) {
-      DisableNotifications();
-    }
-
     // Make sure migration hasn't been triggered prematurely.
     for (int i = 0; i < num_clients(); ++i) {
       ASSERT_TRUE(migration_watchers_[i]->GetMigratedTypes().Empty());
@@ -204,19 +195,7 @@
     }
 
     // Phase 3: Wait for all clients to catch up.
-    //
-    // AwaitQuiescence() will not succeed when notifications are disabled.  We
-    // can safely avoid calling it because we know that, in the single client
-    // case, there is no one else to wait for.
-    //
-    // TODO(rlarocque, 97780): Remove the if condition when the test harness
-    // supports calling AwaitQuiescence() when notifications are disabled.
-    if (!do_test_without_notifications) {
-      AwaitQuiescence();
-    }
-
-    // TODO(rlarocque): It should be possible to re-enable notifications
-    // here, but doing so makes some windows tests flaky.
+    AwaitQuiescence();
   }
 
  private:
@@ -228,7 +207,7 @@
 
 class MigrationSingleClientTest : public MigrationTest {
  public:
-  MigrationSingleClientTest() : MigrationTest(SINGLE_CLIENT_LEGACY) {}
+  MigrationSingleClientTest() : MigrationTest(SINGLE_CLIENT) {}
   ~MigrationSingleClientTest() override {}
 
   void RunSingleClientMigrationTest(const MigrationList& migration_list,
@@ -252,17 +231,14 @@
                                MODIFY_BOOKMARK);
 }
 
-IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest,
-                       PrefsOnlyTriggerNotification) {
-  RunSingleClientMigrationTest(MakeList(syncer::PREFERENCES),
-                               TRIGGER_NOTIFICATION);
+IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, PrefsOnlyTriggerRefresh) {
+  RunSingleClientMigrationTest(MakeList(syncer::PREFERENCES), TRIGGER_REFRESH);
 }
 
 // Nigori is handled specially, so we test that separately.
 
 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, NigoriOnly) {
-  RunSingleClientMigrationTest(MakeList(syncer::PREFERENCES),
-                               TRIGGER_NOTIFICATION);
+  RunSingleClientMigrationTest(MakeList(syncer::PREFERENCES), TRIGGER_REFRESH);
 }
 
 // A little more complicated -- two data types.
@@ -281,12 +257,9 @@
 
 // Two data types with one being nigori.
 
-// See crbug.com/124480.
-IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest,
-                       DISABLED_PrefsNigoriIndividiaully) {
-  RunSingleClientMigrationTest(
-      MakeList(syncer::PREFERENCES, syncer::NIGORI),
-      TRIGGER_NOTIFICATION);
+IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, PrefsNigoriIndividiaully) {
+  RunSingleClientMigrationTest(MakeList(syncer::PREFERENCES, syncer::NIGORI),
+                               TRIGGER_REFRESH);
 }
 
 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, PrefsNigoriBoth) {
@@ -296,19 +269,15 @@
 }
 
 // The whole shebang -- all data types.
-// http://crbug.com/403778
-IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest,
-                       DISABLED_AllTypesIndividually) {
+IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, AllTypesIndividually) {
   ASSERT_TRUE(SetupClients());
   RunSingleClientMigrationTest(GetPreferredDataTypesList(), MODIFY_BOOKMARK);
 }
 
-// http://crbug.com/403778
 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest,
-                       DISABLED_AllTypesIndividuallyTriggerNotification) {
+                       AllTypesIndividuallyTriggerRefresh) {
   ASSERT_TRUE(SetupClients());
-  RunSingleClientMigrationTest(GetPreferredDataTypesList(),
-                               TRIGGER_NOTIFICATION);
+  RunSingleClientMigrationTest(GetPreferredDataTypesList(), TRIGGER_REFRESH);
 }
 
 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, AllTypesAtOnce) {
@@ -318,17 +287,16 @@
 }
 
 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest,
-                       AllTypesAtOnceTriggerNotification) {
+                       AllTypesAtOnceTriggerRefresh) {
   ASSERT_TRUE(SetupClients());
   RunSingleClientMigrationTest(MakeList(GetPreferredDataTypes()),
-                               TRIGGER_NOTIFICATION);
+                               TRIGGER_REFRESH);
 }
 
 // All data types plus nigori.
 
-// See crbug.com/124480.
 IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest,
-                       DISABLED_AllTypesWithNigoriIndividually) {
+                       AllTypesWithNigoriIndividually) {
   ASSERT_TRUE(SetupClients());
   MigrationList migration_list = GetPreferredDataTypesList();
   migration_list.push_front(MakeSet(syncer::NIGORI));
@@ -344,7 +312,7 @@
 
 class MigrationTwoClientTest : public MigrationTest {
  public:
-  MigrationTwoClientTest() : MigrationTest(TWO_CLIENT_LEGACY) {}
+  MigrationTwoClientTest() : MigrationTest(TWO_CLIENT) {}
   ~MigrationTwoClientTest() override {}
 
   // Helper function that verifies that preferences sync still works.
@@ -375,18 +343,15 @@
 
 // Easiest possible test of migration errors: triggers a server
 // migration on one datatype, then modifies some other datatype.
-// TODO(https://crbug.com/918124): Often times out on continuous build.
-IN_PROC_BROWSER_TEST_F(MigrationTwoClientTest,
-                       DISABLED_MigratePrefsThenModifyBookmark) {
+IN_PROC_BROWSER_TEST_F(MigrationTwoClientTest, MigratePrefsThenModifyBookmark) {
   RunTwoClientMigrationTest(MakeList(syncer::PREFERENCES),
                             MODIFY_BOOKMARK);
 }
 
 // Triggers a server migration on two datatypes, then makes a local
 // modification to one of them.
-// TODO(https://crbug.com/918124): Often times out on continuous build.
 IN_PROC_BROWSER_TEST_F(MigrationTwoClientTest,
-                       DISABLED_MigratePrefsAndBookmarksThenModifyBookmark) {
+                       MigratePrefsAndBookmarksThenModifyBookmark) {
   RunTwoClientMigrationTest(
       MakeList(syncer::PREFERENCES, syncer::BOOKMARKS),
       MODIFY_BOOKMARK);
@@ -408,7 +373,6 @@
   RunTwoClientMigrationTest(migration_list, MODIFY_BOOKMARK);
 }
 
-// See crbug.com/124480.
 IN_PROC_BROWSER_TEST_F(MigrationTwoClientTest,
                        DISABLED_MigrationHellWithNigori) {
   ASSERT_TRUE(SetupClients());
diff --git a/chrome/browser/sync/test/integration/sync_test.cc b/chrome/browser/sync/test/integration/sync_test.cc
index 8e5ba30..14dbad5 100644
--- a/chrome/browser/sync/test/integration/sync_test.cc
+++ b/chrome/browser/sync/test/integration/sync_test.cc
@@ -1148,68 +1148,15 @@
   return server_type_ == EXTERNAL_LIVE_SERVER;
 }
 
-bool SyncTest::ServerSupportsNotificationControl() const {
-  EXPECT_NE(SERVER_TYPE_UNDECIDED, server_type_);
-
-  // Supported only if we're using the python testserver.
-  return server_type_ == LOCAL_PYTHON_SERVER;
-}
-
-void SyncTest::DisableNotificationsImpl() {
-  ASSERT_TRUE(ServerSupportsNotificationControl());
-  std::string path = "chromiumsync/disablenotifications";
-  ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path));
-  ASSERT_EQ(
-      "Notifications disabled",
-      base::UTF16ToASCII(
-          browser()->tab_strip_model()->GetActiveWebContents()->GetTitle()));
-}
-
-void SyncTest::DisableNotifications() {
-  DisableNotificationsImpl();
-}
-
-void SyncTest::EnableNotificationsImpl() {
-  ASSERT_TRUE(ServerSupportsNotificationControl());
-  std::string path = "chromiumsync/enablenotifications";
-  ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path));
-  ASSERT_EQ(
-      "Notifications enabled",
-      base::UTF16ToASCII(
-          browser()->tab_strip_model()->GetActiveWebContents()->GetTitle()));
-}
-
-void SyncTest::EnableNotifications() {
-  EnableNotificationsImpl();
-}
-
-void SyncTest::TriggerNotification(syncer::ModelTypeSet changed_types) {
-  ASSERT_TRUE(ServerSupportsNotificationControl());
-  const std::string& data =
-      syncer::P2PNotificationData(
-          "from_server", syncer::NOTIFY_ALL,
-          syncer::ObjectIdInvalidationMap::InvalidateAll(
-              syncer::ModelTypeSetToObjectIdSet(changed_types)))
-          .ToString();
-  const std::string& path =
-      std::string("chromiumsync/sendnotification?channel=") +
-      syncer::kSyncP2PNotificationChannel + "&data=" + data;
-  ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path));
-  ASSERT_EQ(
-      "Notification sent",
-      base::UTF16ToASCII(
-          browser()->tab_strip_model()->GetActiveWebContents()->GetTitle()));
-}
-
-bool SyncTest::ServerSupportsErrorTriggering() const {
-  EXPECT_NE(SERVER_TYPE_UNDECIDED, server_type_);
-
-  // Supported only if we're using the python testserver.
-  return server_type_ == LOCAL_PYTHON_SERVER;
-}
-
 void SyncTest::TriggerMigrationDoneError(syncer::ModelTypeSet model_types) {
-  ASSERT_TRUE(ServerSupportsErrorTriggering());
+  ASSERT_TRUE(server_type_ == LOCAL_PYTHON_SERVER ||
+              server_type_ == IN_PROCESS_FAKE_SERVER);
+
+  if (server_type_ == IN_PROCESS_FAKE_SERVER) {
+    fake_server_->TriggerMigrationDoneError(model_types);
+    return;
+  }
+
   std::string path = "chromiumsync/migrate";
   char joiner = '?';
   for (syncer::ModelType type : model_types) {
diff --git a/chrome/browser/sync/test/integration/sync_test.h b/chrome/browser/sync/test/integration/sync_test.h
index 0bdb703..d29c9743 100644
--- a/chrome/browser/sync/test/integration/sync_test.h
+++ b/chrome/browser/sync/test/integration/sync_test.h
@@ -80,9 +80,8 @@
 
     // Tests that use one client profile and are not compatible with
     // FakeServer.
-    // TODO(pvalenzuela): Delete this value when all SINGLE_CLIENT_LEGACY tests
-    // are compatible with FakeServer and switched to SINGLE_CLIENT. See
-    // crbug.com/323265.
+    // TODO(crbug.com/406545): Delete this value when all SINGLE_CLIENT_LEGACY
+    // tests are compatible with FakeServer and switched to SINGLE_CLIENT.
     SINGLE_CLIENT_LEGACY,
 
     // Tests where two client profiles are synced with the server. Typically
@@ -91,9 +90,8 @@
 
     // Tests that use two client profiles and are not compatible with
     // FakeServer.
-    // TODO(pvalenzuela): Delete this value when all TWO_CLIENT_LEGACY tests are
-    // compatible with FakeServer and switched to TWO_CLIENT. See
-    // crbug.com/323265.
+    // TODO(crbug.com/406545): Delete this value when all TWO_CLIENT_LEGACY
+    // tests are compatible with FakeServer and switched to TWO_CLIENT.
     TWO_CLIENT_LEGACY
   };
 
@@ -207,32 +205,12 @@
   // Returns true if we are running tests against external servers.
   bool UsingExternalServers();
 
-  // Returns true if the server being used supports controlling
-  // notifications.
-  bool ServerSupportsNotificationControl() const;
-
-  // Disable notifications on the server.  This operation is available
-  // only if ServerSupportsNotificationControl() returned true.
-  void DisableNotifications();
-
-  // Enable notifications on the server.  This operation is available
-  // only if ServerSupportsNotificationControl() returned true.
-  void EnableNotifications();
-
   // Sets the mock gaia response for when an OAuth2 token is requested.
   // Each call to this method will overwrite responses that were previously set.
   void SetOAuth2TokenResponse(const std::string& response_data,
                               net::HttpStatusCode response_code,
                               net::URLRequestStatus::Status status);
 
-  // Trigger a notification to be sent to all clients.  This operation
-  // is available only if ServerSupportsNotificationControl() returned
-  // true.
-  void TriggerNotification(syncer::ModelTypeSet changed_types);
-
-  // Returns true if the server being used supports injecting errors.
-  bool ServerSupportsErrorTriggering() const;
-
   // Triggers a migration for one or more datatypes, and waits
   // for the server to complete it.  This operation is available
   // only if ServerSupportsErrorTriggering() returned true.
diff --git a/chrome/browser/ui/android/ssl_client_certificate_request.cc b/chrome/browser/ui/android/ssl_client_certificate_request.cc
index feda107..e0e66639 100644
--- a/chrome/browser/ui/android/ssl_client_certificate_request.cc
+++ b/chrome/browser/ui/android/ssl_client_certificate_request.cc
@@ -13,6 +13,7 @@
 #include "base/containers/queue.h"
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
+#include "base/metrics/histogram_macros.h"
 #include "base/task/post_task.h"
 #include "chrome/browser/ssl/ssl_client_certificate_selector.h"
 #include "chrome/browser/ui/android/view_android_helper.h"
@@ -20,6 +21,8 @@
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/client_certificate_delegate.h"
+#include "content/public/browser/navigation_handle.h"
+#include "content/public/browser/web_contents_observer.h"
 #include "jni/SSLClientCertificateRequest_jni.h"
 #include "net/base/host_port_pair.h"
 #include "net/cert/cert_database.h"
@@ -40,8 +43,6 @@
 
 class SSLClientCertPendingRequests;
 
-const char kSSLClientCertPendingRequests[] = "SSLClientCertPendingRequests";
-
 class ClientCertRequest {
  public:
   ClientCertRequest(
@@ -69,10 +70,12 @@
   DISALLOW_COPY_AND_ASSIGN(ClientCertRequest);
 };
 
-class SSLClientCertPendingRequests : public base::SupportsUserData::Data {
+class SSLClientCertPendingRequests
+    : public content::WebContentsUserData<SSLClientCertPendingRequests>,
+      public content::WebContentsObserver {
  public:
   explicit SSLClientCertPendingRequests(content::WebContents* web_contents)
-      : web_contents_(web_contents), weak_factory_(this) {}
+      : content::WebContentsObserver(web_contents), weak_factory_(this) {}
   ~SSLClientCertPendingRequests() override {}
 
   void AddRequest(std::unique_ptr<ClientCertRequest> request);
@@ -85,16 +88,48 @@
     return weak_factory_.GetWeakPtr();
   }
 
+  void ReadyToCommitNavigation(
+      content::NavigationHandle* navigation_handle) override;
+
+  void WebContentsDestroyed() override;
+
+  class CertificateDialogPolicy {
+   public:
+    // Has the maximum number of cert dialogs been exceeded?
+    // TODO(dmcardle) Once we have sufficient UMA data, change this to return
+    // |count_ > kMaxClientCertRequestDialogs|.
+    bool MaxExceeded() { return false; }
+    // Resets counter. Should be called on navigation.
+    void ResetCount() {
+      // Record sample right before the value is reset. This represents the
+      // maximum number of certificate dialogs displayed by sites in the wild.
+      UMA_HISTOGRAM_COUNTS_10000(
+          "Net.Certificate.ClientCertDialogCount.Android", count_);
+      count_ = 0;
+    }
+    // Increment the counter.
+    void IncrementCount() { count_++; }
+
+   private:
+    size_t count_ = 0;
+  };
+
  private:
   void PumpRequests();
 
   bool active_request_ = false;
-  base::queue<std::unique_ptr<ClientCertRequest>> pending_requests_;
 
-  content::WebContents* web_contents_;
+  CertificateDialogPolicy dialog_policy;
+  base::queue<std::unique_ptr<ClientCertRequest>> pending_requests_;
   base::WeakPtrFactory<SSLClientCertPendingRequests> weak_factory_;
+
+  friend class content::WebContentsUserData<SSLClientCertPendingRequests>;
+
+  WEB_CONTENTS_USER_DATA_KEY_DECL();
 };
 
+WEB_CONTENTS_USER_DATA_KEY_IMPL(SSLClientCertPendingRequests)
+
 static void StartClientCertificateRequest(
     std::unique_ptr<ClientCertRequest> request,
     content::WebContents* web_contents) {
@@ -199,7 +234,32 @@
       std::move(pending_requests_.front());
   pending_requests_.pop();
 
-  StartClientCertificateRequest(std::move(next), web_contents_);
+  // Check if this page is allowed to show any more client cert dialogs.
+  if (!dialog_policy.MaxExceeded()) {
+    dialog_policy.IncrementCount();
+    StartClientCertificateRequest(std::move(next), web_contents());
+  }
+}
+
+void SSLClientCertPendingRequests::ReadyToCommitNavigation(
+    content::NavigationHandle* navigation_handle) {
+  // Be careful to only reset the the client certificate dialog counter when the
+  // navigation is user-initiated. Note that |HasUserGesture| does not capture
+  // browser-initiated navigations. The negation of |IsRendererInitiated| tells
+  // us whether the navigation is browser-generated.
+  if (navigation_handle->IsInMainFrame() &&
+      (navigation_handle->HasUserGesture() ||
+       !navigation_handle->IsRendererInitiated())) {
+    // TODO(dmcardle) Flush any remaining dialogs before resetting the
+    // counter. On Android, these are System UI dialogs.
+
+    dialog_policy.ResetCount();
+  }
+}
+
+void SSLClientCertPendingRequests::WebContentsDestroyed() {
+  // Record UMA sample for last page loaded in WebContents.
+  dialog_policy.ResetCount();
 }
 
 void ClientCertRequest::CertificateSelected(
@@ -303,15 +363,9 @@
     return;
   }
 
+  SSLClientCertPendingRequests::CreateForWebContents(contents);
   SSLClientCertPendingRequests* active_requests =
-      static_cast<SSLClientCertPendingRequests*>(
-          contents->GetUserData(&kSSLClientCertPendingRequests));
-
-  if (active_requests == nullptr) {
-    active_requests = new SSLClientCertPendingRequests(contents);
-    contents->SetUserData(&kSSLClientCertPendingRequests,
-                          base::WrapUnique(active_requests));
-  }
+      SSLClientCertPendingRequests::FromWebContents(contents);
 
   active_requests->AddRequest(std::make_unique<ClientCertRequest>(
       active_requests->GetWeakPtr(), cert_request_info, std::move(delegate)));
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h
index 009cf8a1..80c1456e 100644
--- a/chrome/browser/ui/browser_window.h
+++ b/chrome/browser/ui/browser_window.h
@@ -175,6 +175,9 @@
   // frames may need to refresh their title bar.
   virtual void UpdateTitleBar() = 0;
 
+  // Inform the frame that its color has changed.
+  virtual void UpdateFrameColor() = 0;
+
   // Invoked when the state of the bookmark bar changes. This is only invoked if
   // the state changes for the current tab, it is not sent when switching tabs.
   virtual void BookmarkBarStateChanged(
diff --git a/chrome/browser/ui/extensions/hosted_app_browser_controller.cc b/chrome/browser/ui/extensions/hosted_app_browser_controller.cc
index 085e9067..6560d51e 100644
--- a/chrome/browser/ui/extensions/hosted_app_browser_controller.cc
+++ b/chrome/browser/ui/extensions/hosted_app_browser_controller.cc
@@ -146,7 +146,8 @@
 }
 
 HostedAppBrowserController::HostedAppBrowserController(Browser* browser)
-    : browser_(browser),
+    : content::WebContentsObserver(nullptr),
+      browser_(browser),
       extension_id_(web_app::GetAppIdFromApplicationName(browser->app_name())),
       // If a bookmark app has a URL handler, then it is a PWA.
       // TODO(https://crbug.com/774918): Replace once there is a more explicit
@@ -266,18 +267,27 @@
 }
 
 base::Optional<SkColor> HostedAppBrowserController::GetThemeColor() const {
-  ExtensionRegistry* registry = ExtensionRegistry::Get(browser_->profile());
-  const Extension* extension =
-      registry->GetExtensionById(extension_id_, ExtensionRegistry::EVERYTHING);
-  if (extension) {
-    const base::Optional<SkColor> color =
-        AppThemeColorInfo::GetThemeColor(extension);
-    if (color) {
-      // The frame/tabstrip code expects an opaque color.
-      return SkColorSetA(*color, SK_AlphaOPAQUE);
-    }
+  base::Optional<SkColor> result;
+
+  const Extension* extension = GetExtension();
+  if (extension)
+    result = AppThemeColorInfo::GetThemeColor(extension);
+
+  // HTML meta theme-color tag overrides manifest theme_color, see spec:
+  // https://www.w3.org/TR/appmanifest/#theme_color-member
+  content::WebContents* web_contents =
+      browser_->tab_strip_model()->GetActiveWebContents();
+  if (web_contents) {
+    SkColor color = web_contents->GetThemeColor();
+    if (color != SK_ColorTRANSPARENT)
+      result = color;
   }
-  return base::nullopt;
+
+  if (!result)
+    return base::nullopt;
+
+  // The frame/tabstrip code expects an opaque color.
+  return SkColorSetA(*result, SK_AlphaOPAQUE);
 }
 
 base::string16 HostedAppBrowserController::GetTitle() const {
@@ -360,11 +370,20 @@
   }
 }
 
+void HostedAppBrowserController::DidChangeThemeColor(SkColor theme_color) {
+  browser_->window()->UpdateFrameColor();
+}
+
 void HostedAppBrowserController::OnTabInserted(content::WebContents* contents) {
+  DCHECK(!web_contents()) << "Hosted app windows are single tabbed only";
   HostedAppBrowserController::SetAppPrefsForWebContents(this, contents);
+  content::WebContentsObserver::Observe(contents);
 }
 
 void HostedAppBrowserController::OnTabRemoved(content::WebContents* contents) {
+  DCHECK_EQ(contents, web_contents());
+  content::WebContentsObserver::Observe(nullptr);
+
   auto* rvh = contents->GetRenderViewHost();
 
   contents->GetMutableRendererPrefs()->can_accept_load_drops = true;
diff --git a/chrome/browser/ui/extensions/hosted_app_browser_controller.h b/chrome/browser/ui/extensions/hosted_app_browser_controller.h
index 645c0bb..988b47b 100644
--- a/chrome/browser/ui/extensions/hosted_app_browser_controller.h
+++ b/chrome/browser/ui/extensions/hosted_app_browser_controller.h
@@ -12,6 +12,7 @@
 #include "base/strings/string16.h"
 #include "chrome/browser/extensions/extension_uninstall_dialog.h"
 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
+#include "content/public/browser/web_contents_observer.h"
 #include "third_party/skia/include/core/SkColor.h"
 
 class Browser;
@@ -33,7 +34,8 @@
 
 // Class to encapsulate logic to control the browser UI for hosted apps.
 class HostedAppBrowserController : public TabStripModelObserver,
-                                   public ExtensionUninstallDialog::Delegate {
+                                   public ExtensionUninstallDialog::Delegate,
+                                   public content::WebContentsObserver {
  public:
   // Returns whether |browser| uses the experimental hosted app experience.
   // Convenience wrapper for checking IsForExperimentalHostedAppBrowser() on
@@ -116,6 +118,9 @@
       const TabStripModelChange& change,
       const TabStripSelectionChange& selection) override;
 
+  // content::WebContentsObserver:
+  void DidChangeThemeColor(SkColor theme_color) override;
+
  private:
   // Called by OnTabstripModelChanged().
   void OnTabInserted(content::WebContents* contents);
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc
index 2c50892..7e08fab 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc
@@ -137,6 +137,11 @@
   return !browser_view_->browser()->hosted_app_controller();
 }
 
+SkColor BrowserNonClientFrameView::GetCaptionColor(
+    ActiveState active_state) const {
+  return color_utils::GetColorWithMaxContrast(GetFrameColor(active_state));
+}
+
 SkColor BrowserNonClientFrameView::GetFrameColor(
     ActiveState active_state) const {
   ThemeProperties::OverwritableByUserThemeProperty color_id;
@@ -157,6 +162,14 @@
                                           browser_view_->IsIncognito());
 }
 
+void BrowserNonClientFrameView::UpdateFrameColor() {
+  // Only hosted app windows support dynamic frame colors set by HTML meta tags.
+  if (!hosted_app_button_container_)
+    return;
+  hosted_app_button_container_->UpdateCaptionColors();
+  SchedulePaint();
+}
+
 SkColor BrowserNonClientFrameView::GetToolbarTopSeparatorColor() const {
   const int color_id =
       ShouldPaintAsActive()
@@ -224,11 +237,6 @@
     hosted_app_button_container_->UpdateStatusIconsVisibility();
 }
 
-SkColor BrowserNonClientFrameView::GetCaptionColor(
-    ActiveState active_state) const {
-  return color_utils::GetColorWithMaxContrast(GetFrameColor(active_state));
-}
-
 bool BrowserNonClientFrameView::ShouldPaintAsActive(
     ActiveState active_state) const {
   return (active_state == kUseCurrent) ? ShouldPaintAsActive()
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view.h b/chrome/browser/ui/views/frame/browser_non_client_frame_view.h
index 2660986..7059ce23 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view.h
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view.h
@@ -93,10 +93,18 @@
   // Returns whether tab strokes can be drawn.
   virtual bool CanDrawStrokes() const;
 
+  // Returns the color to use for text, caption buttons, and other title bar
+  // elements.
+  virtual SkColor GetCaptionColor(ActiveState active_state = kUseCurrent) const;
+
   // Returns the color of the browser frame, which is also the color of the
   // tabstrip background.
   SkColor GetFrameColor(ActiveState active_state = kUseCurrent) const;
 
+  // Called by BrowserView to signal the frame color has changed and needs
+  // to be repainted.
+  void UpdateFrameColor();
+
   // Returns COLOR_TOOLBAR_TOP_SEPARATOR[,_INACTIVE] depending on the activation
   // state of the window.
   SkColor GetToolbarTopSeparatorColor() const;
@@ -130,10 +138,6 @@
   }
 
  protected:
-  // Returns the color to use for text, caption buttons, and other title bar
-  // elements.
-  virtual SkColor GetCaptionColor(ActiveState active_state = kUseCurrent) const;
-
   // Converts an ActiveState to a bool representing whether the frame should be
   // treated as active.
   bool ShouldPaintAsActive(ActiveState active_state) const;
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc
index ce441fef..0c60b8be 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_browsertest.cc
@@ -18,6 +18,7 @@
 #include "chrome/common/web_application_info.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/ui_test_utils.h"
+#include "content/public/test/browser_test_utils.h"
 #include "content/public/test/test_navigation_observer.h"
 #include "ui/base/theme_provider.h"
 
@@ -30,6 +31,7 @@
   void SetUpOnMainThread() override {
     ExtensionBrowserTest::SetUpOnMainThread();
     scoped_feature_list_.InitAndEnableFeature(features::kDesktopPWAWindowing);
+    ASSERT_TRUE(embedded_test_server()->Start());
   }
 
   // Note: A "bookmark app" is a type of hosted app. All of these tests apply
@@ -62,7 +64,7 @@
   BrowserNonClientFrameView* app_frame_view_ = nullptr;
 
  private:
-  GURL GetAppURL() { return GURL("https://test.org"); }
+  GURL GetAppURL() { return embedded_test_server()->GetURL("/hello.html"); }
 
   base::test::ScopedFeatureList scoped_feature_list_;
 
@@ -186,3 +188,24 @@
   EXPECT_TRUE(
       app_frame_view_->browser_view()->toolbar()->custom_tab_bar()->IsDrawn());
 }
+
+// Tests that hosted app frames reflect the theme color set by HTML meta tags.
+IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewBrowserTest,
+                       HTMLMetaThemeColorOverridesManifest) {
+  // Ensure we're not using the system theme on Linux.
+  ThemeService* theme_service =
+      ThemeServiceFactory::GetForProfile(browser()->profile());
+  theme_service->UseDefaultTheme();
+
+  InstallAndLaunchBookmarkApp();
+  EXPECT_EQ(app_frame_view_->GetFrameColor(), *app_theme_color_);
+
+  content::WebContents* web_contents =
+      app_frame_view_->browser_view()->GetActiveWebContents();
+  EXPECT_TRUE(content::ExecuteScript(web_contents, R"(
+      document.documentElement.innerHTML =
+          '<meta name="theme-color" content="yellow">';
+  )"));
+  EXPECT_EQ(app_frame_view_->GetFrameColor(), SK_ColorYELLOW);
+  DCHECK_NE(*app_theme_color_, SK_ColorYELLOW);
+}
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index 850df04f..c00e524 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -762,6 +762,10 @@
     frame_->UpdateWindowIcon();
 }
 
+void BrowserView::UpdateFrameColor() {
+  frame_->GetFrameView()->UpdateFrameColor();
+}
+
 void BrowserView::BookmarkBarStateChanged(
     BookmarkBar::AnimateChangeType change_type) {
   if (bookmark_bar_view_.get()) {
@@ -1632,6 +1636,12 @@
     TabStripModel* tab_strip_model,
     const TabStripModelChange& change,
     const TabStripSelectionChange& selection) {
+  // When the selected tab changes, elements in the omnibox can change, which
+  // can change its preferred size. Re-lay-out the toolbar to reflect the
+  // possible change.
+  if (selection.selection_changed())
+    toolbar_->InvalidateLayout();
+
   if (change.type() != TabStripModelChange::kInserted)
     return;
 
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h
index b36a7ee8..797ed0d 100644
--- a/chrome/browser/ui/views/frame/browser_view.h
+++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -305,6 +305,7 @@
   void SetTopControlsGestureScrollInProgress(bool in_progress) override;
   StatusBubble* GetStatusBubble() override;
   void UpdateTitleBar() override;
+  void UpdateFrameColor() override;
   void BookmarkBarStateChanged(
       BookmarkBar::AnimateChangeType change_type) override;
   void UpdateDevTools() override;
diff --git a/chrome/browser/ui/views/frame/glass_browser_frame_view.cc b/chrome/browser/ui/views/frame/glass_browser_frame_view.cc
index 3a05a4e0..c75aa9e 100644
--- a/chrome/browser/ui/views/frame/glass_browser_frame_view.cc
+++ b/chrome/browser/ui/views/frame/glass_browser_frame_view.cc
@@ -195,6 +195,14 @@
   return BrowserNonClientFrameView::CanDrawStrokes();
 }
 
+SkColor GlassBrowserFrameView::GetCaptionColor(ActiveState active_state) const {
+  const SkAlpha title_alpha = ShouldPaintAsActive(active_state)
+                                  ? SK_AlphaOPAQUE
+                                  : kInactiveTitlebarFeatureAlpha;
+  return SkColorSetA(GetReadableFeatureColor(GetFrameColor(active_state)),
+                     title_alpha);
+}
+
 void GlassBrowserFrameView::UpdateThrobber(bool running) {
   if (ShowCustomIcon())
     window_icon_->Update();
@@ -229,14 +237,6 @@
   return min_size;
 }
 
-SkColor GlassBrowserFrameView::GetCaptionColor(ActiveState active_state) const {
-  const SkAlpha title_alpha = ShouldPaintAsActive(active_state)
-                                  ? SK_AlphaOPAQUE
-                                  : kInactiveTitlebarFeatureAlpha;
-  return SkColorSetA(GetReadableFeatureColor(GetFrameColor(active_state)),
-                     title_alpha);
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 // GlassBrowserFrameView, views::NonClientFrameView implementation:
 
diff --git a/chrome/browser/ui/views/frame/glass_browser_frame_view.h b/chrome/browser/ui/views/frame/glass_browser_frame_view.h
index 7c8da89..90eb6b2 100644
--- a/chrome/browser/ui/views/frame/glass_browser_frame_view.h
+++ b/chrome/browser/ui/views/frame/glass_browser_frame_view.h
@@ -40,9 +40,9 @@
   int GetThemeBackgroundXInset() const override;
   bool HasVisibleBackgroundTabShapes(ActiveState active_state) const override;
   bool CanDrawStrokes() const override;
+  SkColor GetCaptionColor(ActiveState active_state) const override;
   void UpdateThrobber(bool running) override;
   gfx::Size GetMinimumSize() const override;
-  SkColor GetCaptionColor(ActiveState active_state) const override;
 
   // views::NonClientFrameView:
   gfx::Rect GetBoundsForClientView() const override;
diff --git a/chrome/browser/ui/views/frame/hosted_app_button_container.cc b/chrome/browser/ui/views/frame/hosted_app_button_container.cc
index a1183f7..d808a89a7 100644
--- a/chrome/browser/ui/views/frame/hosted_app_button_container.cc
+++ b/chrome/browser/ui/views/frame/hosted_app_button_container.cc
@@ -214,7 +214,7 @@
   params.types_enabled.push_back(PageActionIconType::kTranslate);
   params.types_enabled.push_back(PageActionIconType::kZoom);
   params.icon_size = GetLayoutConstant(HOSTED_APP_PAGE_ACTION_ICON_SIZE);
-  params.icon_color = GetIconColor();
+  params.icon_color = GetCaptionColor();
   params.between_icon_spacing = HorizontalPaddingBetweenItems();
   params.browser = browser_view_->browser();
   params.command_updater = browser_view_->browser()->command_controller();
@@ -259,6 +259,16 @@
   page_action_icon_container_view_->UpdateAll();
 }
 
+void HostedAppButtonContainer::UpdateCaptionColors() {
+  const BrowserNonClientFrameView* frame_view =
+      browser_view_->frame()->GetFrameView();
+  active_color_ = frame_view->GetCaptionColor(
+      BrowserNonClientFrameView::ActiveState::kActive);
+  inactive_color_ = frame_view->GetCaptionColor(
+      BrowserNonClientFrameView::ActiveState::kInactive);
+  UpdateChildrenColor();
+}
+
 void HostedAppButtonContainer::SetPaintAsActive(bool active) {
   if (paint_as_active_ == active)
     return;
@@ -311,7 +321,7 @@
 }
 
 SkColor HostedAppButtonContainer::GetContentSettingInkDropColor() const {
-  return GetIconColor();
+  return GetCaptionColor();
 }
 
 content::WebContents* HostedAppButtonContainer::GetContentSettingWebContents() {
@@ -337,7 +347,7 @@
 }
 
 SkColor HostedAppButtonContainer::GetPageActionInkDropColor() const {
-  return GetIconColor();
+  return GetCaptionColor();
 }
 
 content::WebContents*
@@ -454,12 +464,12 @@
   return content_settings_container_->GetContentSettingViewsForTesting();
 }
 
-SkColor HostedAppButtonContainer::GetIconColor() const {
+SkColor HostedAppButtonContainer::GetCaptionColor() const {
   return paint_as_active_ ? active_color_ : inactive_color_;
 }
 
 void HostedAppButtonContainer::UpdateChildrenColor() {
-  SkColor icon_color = GetIconColor();
+  SkColor icon_color = GetCaptionColor();
   hosted_app_origin_text_->SetTextColor(icon_color);
   content_settings_container_->SetIconColor(icon_color);
   page_action_icon_container_view_->SetIconColor(icon_color);
diff --git a/chrome/browser/ui/views/frame/hosted_app_button_container.h b/chrome/browser/ui/views/frame/hosted_app_button_container.h
index dd732b68..f8aa41b 100644
--- a/chrome/browser/ui/views/frame/hosted_app_button_container.h
+++ b/chrome/browser/ui/views/frame/hosted_app_button_container.h
@@ -16,6 +16,7 @@
 #include "chrome/browser/ui/views/location_bar/content_setting_image_view.h"
 #include "chrome/browser/ui/views/page_action/page_action_icon_view.h"
 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h"
+#include "ui/gfx/color_palette.h"
 #include "ui/views/accessible_pane_view.h"
 #include "ui/views/controls/button/menu_button.h"
 #include "ui/views/controls/button/menu_button_listener.h"
@@ -71,6 +72,8 @@
 
   void UpdateStatusIconsVisibility();
 
+  void UpdateCaptionColors();
+
   // Sets the container to paints its buttons the active/inactive color.
   void SetPaintAsActive(bool active);
 
@@ -151,7 +154,7 @@
   const std::vector<ContentSettingImageView*>&
   GetContentSettingViewsForTesting() const;
 
-  SkColor GetIconColor() const;
+  SkColor GetCaptionColor() const;
   void UpdateChildrenColor();
 
   // Whether we're waiting for the widget to become visible.
@@ -168,8 +171,8 @@
 
   // Button and text colors.
   bool paint_as_active_ = true;
-  const SkColor active_color_;
-  const SkColor inactive_color_;
+  SkColor active_color_;
+  SkColor inactive_color_;
 
   // Owned by the views hierarchy.
   HostedAppOriginText* hosted_app_origin_text_ = nullptr;
diff --git a/chrome/browser/ui/views/location_bar/OWNERS b/chrome/browser/ui/views/location_bar/OWNERS
index ac9b56c..ff16bf51 100644
--- a/chrome/browser/ui/views/location_bar/OWNERS
+++ b/chrome/browser/ui/views/location_bar/OWNERS
@@ -1,6 +1,6 @@
 estade@chromium.org
 file://components/omnibox/OWNERS
 
-per-file custom_tab_bar_view.*=harrisjay@chromium.org
+per-file custom_tab_bar_view*=harrisjay@chromium.org
 
 # COMPONENT: UI>Browser>Omnibox
diff --git a/chrome/browser/ui/views/location_bar/custom_tab_bar_view.cc b/chrome/browser/ui/views/location_bar/custom_tab_bar_view.cc
index 167da107..d911043 100644
--- a/chrome/browser/ui/views/location_bar/custom_tab_bar_view.cc
+++ b/chrome/browser/ui/views/location_bar/custom_tab_bar_view.cc
@@ -93,7 +93,7 @@
     title_label_->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT);
 
     location_label_->SetBackgroundColor(background_color);
-    location_label_->SetElideBehavior(gfx::ElideBehavior::ELIDE_TAIL);
+    location_label_->SetElideBehavior(gfx::ElideBehavior::ELIDE_HEAD);
     location_label_->SetHorizontalAlignment(
         gfx::HorizontalAlignment::ALIGN_LEFT);
 
@@ -183,8 +183,8 @@
       new CustomTabBarTitleOriginView(kCustomTabBarViewBackgroundColor);
   AddChildView(title_origin_view_);
 
-  auto* layout = SetLayoutManager(std::make_unique<views::FlexLayout>());
-  layout->SetOrientation(views::LayoutOrientation::kHorizontal)
+  layout_manager_ = SetLayoutManager(std::make_unique<views::FlexLayout>());
+  layout_manager_->SetOrientation(views::LayoutOrientation::kHorizontal)
       .SetMainAxisAlignment(views::LayoutAlignment::kStart)
       .SetCrossAxisAlignment(views::LayoutAlignment::kCenter)
       .SetInteriorMargin(GetLayoutInsets(LayoutInset::TOOLBAR_INTERIOR_MARGIN))
@@ -213,9 +213,10 @@
   base::string16 title, location;
   if (entry) {
     title = Browser::FormatTitleForDisplay(entry->GetTitleForDisplay());
-    location = url_formatter::FormatUrl(
-        entry->GetVirtualURL(), url_formatter::kFormatUrlOmitDefaults,
-        net::UnescapeRule::NORMAL, nullptr, nullptr, nullptr);
+    location = url_formatter::FormatUrl(entry->GetVirtualURL().GetOrigin(),
+                                        url_formatter::kFormatUrlOmitDefaults,
+                                        net::UnescapeRule::NORMAL, nullptr,
+                                        nullptr, nullptr);
   }
 
   title_origin_view_->Update(title, location);
@@ -231,7 +232,7 @@
   // ToolbarView::GetMinimumSize() uses the preferred size of its children, so
   // tell it the minimum size this control will fit into (its layout will
   // automatically have this control fill available space).
-  return gfx::Size(GetInsets().width() +
+  return gfx::Size(layout_manager_->interior_margin().width() +
                        title_origin_view_->GetMinimumSize().width() +
                        close_button_->GetPreferredSize().width() +
                        location_icon_view_->GetPreferredSize().width(),
diff --git a/chrome/browser/ui/views/location_bar/custom_tab_bar_view.h b/chrome/browser/ui/views/location_bar/custom_tab_bar_view.h
index b209df4a..2b9aeba 100644
--- a/chrome/browser/ui/views/location_bar/custom_tab_bar_view.h
+++ b/chrome/browser/ui/views/location_bar/custom_tab_bar_view.h
@@ -17,6 +17,10 @@
 class Rect;
 }
 
+namespace views {
+class FlexLayout;
+}
+
 class CustomTabBarTitleOriginView;
 class BrowserView;
 
@@ -87,6 +91,8 @@
   CustomTabBarTitleOriginView* title_origin_view_ = nullptr;
   ScopedObserver<TabStripModel, CustomTabBarView> tab_strip_model_observer_;
 
+  views::FlexLayout* layout_manager_;
+
   DISALLOW_COPY_AND_ASSIGN(CustomTabBarView);
 };
 
diff --git a/chrome/browser/ui/views/location_bar/custom_tab_bar_view_browsertest.cc b/chrome/browser/ui/views/location_bar/custom_tab_bar_view_browsertest.cc
index 6ae70b6b..08905cd 100644
--- a/chrome/browser/ui/views/location_bar/custom_tab_bar_view_browsertest.cc
+++ b/chrome/browser/ui/views/location_bar/custom_tab_bar_view_browsertest.cc
@@ -257,8 +257,10 @@
   SetTitleAndLocation(app_view->GetActiveWebContents(),
                       base::ASCIIToUTF16("FooBar"), navigate_to);
 
-  EXPECT_EQ(base::ASCIIToUTF16(navigate_to.spec()),
-            app_view->toolbar()->custom_tab_bar()->location_for_testing());
+  std::string expected_origin = navigate_to.GetOrigin().spec();
+  EXPECT_EQ(base::ASCIIToUTF16(expected_origin),
+            app_view->toolbar()->custom_tab_bar()->location_for_testing() +
+                base::ASCIIToUTF16("/"));
   EXPECT_EQ(base::ASCIIToUTF16("FooBar"),
             app_view->toolbar()->custom_tab_bar()->title_for_testing());
 }
@@ -389,7 +391,8 @@
   EXPECT_EQ(app_url, web_contents->GetLastCommittedURL());
 }
 
-IN_PROC_BROWSER_TEST_F(CustomTabBarViewBrowserTest, URLsWithEmojiArePunyCoded) {
+IN_PROC_BROWSER_TEST_F(CustomTabBarViewBrowserTest,
+                       OriginsWithEmojiArePunyCoded) {
   ASSERT_TRUE(https_server()->Start());
 
   const GURL& app_url = https_server()->GetURL("app.com", "/ssl/google.html");
@@ -405,14 +408,14 @@
   SetTitleAndLocation(app_view->GetActiveWebContents(),
                       base::ASCIIToUTF16("FooBar"), navigate_to);
 
-  EXPECT_EQ(base::UTF8ToUTF16("https://xn--lv8h.example/ssl/blank_page.html"),
+  EXPECT_EQ(base::UTF8ToUTF16("https://xn--lv8h.example"),
             app_view->toolbar()->custom_tab_bar()->location_for_testing());
   EXPECT_EQ(base::ASCIIToUTF16("FooBar"),
             app_view->toolbar()->custom_tab_bar()->title_for_testing());
 }
 
 IN_PROC_BROWSER_TEST_F(CustomTabBarViewBrowserTest,
-                       URLsWithNonASCIICharactersDisplayNormally) {
+                       OriginsWithNonASCIICharactersDisplayNormally) {
   ASSERT_TRUE(https_server()->Start());
 
   const GURL& app_url = https_server()->GetURL("app.com", "/ssl/google.html");
@@ -428,30 +431,7 @@
   SetTitleAndLocation(app_view->GetActiveWebContents(),
                       base::ASCIIToUTF16("FooBar"), navigate_to);
 
-  EXPECT_EQ(base::UTF8ToUTF16("https://ΐ.example/ssl/blank_page.html"),
-            app_view->toolbar()->custom_tab_bar()->location_for_testing());
-  EXPECT_EQ(base::ASCIIToUTF16("FooBar"),
-            app_view->toolbar()->custom_tab_bar()->title_for_testing());
-}
-
-IN_PROC_BROWSER_TEST_F(CustomTabBarViewBrowserTest,
-                       BannedCharactersAreURLEncoded) {
-  ASSERT_TRUE(https_server()->Start());
-
-  const GURL& app_url = https_server()->GetURL("app.com", "/ssl/google.html");
-  const GURL& navigate_to = GURL("https://ΐ.example/🔒/blank_page.html");
-
-  InstallPWA(app_url);
-
-  EXPECT_TRUE(app_browser_);
-
-  BrowserView* app_view = BrowserView::GetBrowserViewForBrowser(app_browser_);
-  EXPECT_NE(app_view, browser_view_);
-
-  SetTitleAndLocation(app_view->GetActiveWebContents(),
-                      base::ASCIIToUTF16("FooBar"), navigate_to);
-
-  EXPECT_EQ(base::UTF8ToUTF16("https://ΐ.example/%F0%9F%94%92/blank_page.html"),
+  EXPECT_EQ(base::UTF8ToUTF16("https://ΐ.example"),
             app_view->toolbar()->custom_tab_bar()->location_for_testing());
   EXPECT_EQ(base::ASCIIToUTF16("FooBar"),
             app_view->toolbar()->custom_tab_bar()->title_for_testing());
diff --git a/chrome/browser/ui/webui/welcome/welcome_ui.cc b/chrome/browser/ui/webui/welcome/welcome_ui.cc
index 6708bb1..83251fb 100644
--- a/chrome/browser/ui/webui/welcome/welcome_ui.cc
+++ b/chrome/browser/ui/webui/welcome/welcome_ui.cc
@@ -101,6 +101,7 @@
        IDS_ONBOARDING_WELCOME_NTP_BACKGROUND_DEFAULT_TITLE},
       {"ntpBackgroundPreviewUpdated",
        IDS_ONBOARDING_WELCOME_NTP_BACKGROUND_PREVIEW_UPDATED},
+      {"ntpBackgroundReset", IDS_ONBOARDING_WELCOME_NTP_BACKGROUND_RESET},
 
       // Set as default module strings.
       {"setDefaultHeader", IDS_ONBOARDING_WELCOME_NUX_SET_AS_DEFAULT_HEADER},
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index 23585e76..309a107 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -354,6 +354,18 @@
 #endif
 
 #if !defined(OS_ANDROID)
+// Enables or disables intent picker.
+const base::Feature kIntentPicker {
+  "IntentPicker",
+#if defined(OS_CHROMEOS)
+      base::FEATURE_ENABLED_BY_DEFAULT
+#else
+      base::FEATURE_DISABLED_BY_DEFAULT
+#endif  //  defined(OS_CHROMEOS)
+};
+#endif  // !defined(OS_ANDROID)
+
+#if !defined(OS_ANDROID)
 // Enables Casting a Presentation API-enabled website to a secondary display.
 const base::Feature kLocalScreenCasting{"LocalScreenCasting",
                                         base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h
index 07dbaefed..4f0ad0a 100644
--- a/chrome/common/chrome_features.h
+++ b/chrome/common/chrome_features.h
@@ -236,6 +236,11 @@
 
 #if !defined(OS_ANDROID)
 COMPONENT_EXPORT(CHROME_FEATURES)
+extern const base::Feature kIntentPicker;
+#endif
+
+#if !defined(OS_ANDROID)
+COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kLocalScreenCasting;
 #endif
 
diff --git a/chrome/common/extensions/api/automation.idl b/chrome/common/extensions/api/automation.idl
index 91818708..8c4bfd39 100644
--- a/chrome/common/extensions/api/automation.idl
+++ b/chrome/common/extensions/api/automation.idl
@@ -23,6 +23,7 @@
     clicked,
     documentSelectionChanged,
     documentTitleChanged,
+    endOfTest,
     expandedChanged,
     focus,
     focusContext,
@@ -311,7 +312,8 @@
     setSelection,
     setSequentialFocusNavigationStartingPoint,
     setValue,
-    showContextMenu
+    showContextMenu,
+    signalEndOfTest
   };
 
   // Possible changes to the automation tree. For any given atomic change
diff --git a/chrome/common/prerender_url_loader_throttle.cc b/chrome/common/prerender_url_loader_throttle.cc
index fc0a5063..7672a88 100644
--- a/chrome/common/prerender_url_loader_throttle.cc
+++ b/chrome/common/prerender_url_loader_throttle.cc
@@ -158,8 +158,11 @@
   }
 
   std::string follow_only_when_prerender_shown_header;
-  response_head.headers->GetNormalizedHeader(
-      kFollowOnlyWhenPrerenderShown, &follow_only_when_prerender_shown_header);
+  if (response_head.headers) {
+    response_head.headers->GetNormalizedHeader(
+        kFollowOnlyWhenPrerenderShown,
+        &follow_only_when_prerender_shown_header);
+  }
   // Abort any prerenders with requests which redirect to invalid schemes.
   if (!DoesURLHaveValidScheme(redirect_info->new_url)) {
     delegate_->CancelWithError(net::ERR_ABORTED);
diff --git a/chrome/renderer/extensions/automation_ax_tree_wrapper.cc b/chrome/renderer/extensions/automation_ax_tree_wrapper.cc
index ea7ec71a..4f628ed 100644
--- a/chrome/renderer/extensions/automation_ax_tree_wrapper.cc
+++ b/chrome/renderer/extensions/automation_ax_tree_wrapper.cc
@@ -43,6 +43,8 @@
       return api::automation::EVENT_TYPE_DOCUMENTSELECTIONCHANGED;
     case ax::mojom::Event::kDocumentTitleChanged:
       return api::automation::EVENT_TYPE_DOCUMENTTITLECHANGED;
+    case ax::mojom::Event::kEndOfTest:
+      return api::automation::EVENT_TYPE_ENDOFTEST;
     case ax::mojom::Event::kExpandedChanged:
       return api::automation::EVENT_TYPE_EXPANDEDCHANGED;
     case ax::mojom::Event::kFocus:
@@ -418,6 +420,7 @@
     case api::automation::EVENT_TYPE_NONE:
     case api::automation::EVENT_TYPE_AUTOCORRECTIONOCCURED:
     case api::automation::EVENT_TYPE_CLICKED:
+    case api::automation::EVENT_TYPE_ENDOFTEST:
     case api::automation::EVENT_TYPE_FOCUSCONTEXT:
     case api::automation::EVENT_TYPE_HITTESTRESULT:
     case api::automation::EVENT_TYPE_HOVER:
diff --git a/chrome/test/base/test_browser_window.h b/chrome/test/base/test_browser_window.h
index b892b9d..4e125ab 100644
--- a/chrome/test/base/test_browser_window.h
+++ b/chrome/test/base/test_browser_window.h
@@ -60,6 +60,7 @@
   void SetTopControlsGestureScrollInProgress(bool in_progress) override;
   StatusBubble* GetStatusBubble() override;
   void UpdateTitleBar() override {}
+  void UpdateFrameColor() override {}
   void BookmarkBarStateChanged(
       BookmarkBar::AnimateChangeType change_type) override {}
   void UpdateDevTools() override {}
diff --git a/chrome/test/data/accessibility/image_annotation_doc.html b/chrome/test/data/accessibility/image_annotation_doc.html
new file mode 100644
index 0000000..a2638fb
--- /dev/null
+++ b/chrome/test/data/accessibility/image_annotation_doc.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<body>
+  <!-- In a doc with exactly one image, the whole doc
+       should get the image's annotation, too. -->
+  <img src="red.png" width=16 height=16>
+</body>
diff --git a/chrome/test/data/accessibility/image_annotation_link.html b/chrome/test/data/accessibility/image_annotation_link.html
new file mode 100644
index 0000000..eb55a07
--- /dev/null
+++ b/chrome/test/data/accessibility/image_annotation_link.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<body>
+  <!-- An image should be annotated. -->
+  <img src="red.png" width=16 height=16>
+
+  <!-- If there's an image in a link, both should be annotated. -->
+  <a href="#">
+    <img src="green.png" width=16 height=16>
+  </a>
+
+  <!-- If there are two images, the link should not be annotated. -->
+  <a href="#">
+    <img src="red.png">
+    <img src="printer.png">
+  </a>
+
+  <!-- If there's text and an image, the link should not be annotated. -->
+  <a href="#">
+    <img src="red.png">
+    Text
+  </a>
+
+  <!-- An extra div is fine, we should still annotate the link. -->
+  <a href="#">
+    <div>
+      <img src="printer.png" width=16 height=16>
+    </div>
+  </a>
+
+</body>
diff --git a/chrome/test/data/webui/settings/cups_printer_page_tests.js b/chrome/test/data/webui/settings/cups_printer_page_tests.js
index 3104331..9874a19 100644
--- a/chrome/test/data/webui/settings/cups_printer_page_tests.js
+++ b/chrome/test/data/webui/settings/cups_printer_page_tests.js
@@ -530,7 +530,7 @@
       printerModel: '',
       printerMakeAndModel: '',
       printerName: 'Test Printer',
-      printerPPDPath: '',
+      printerPPDPath: 'http://myfakeppddownload.com',
       printerPpdReference: {
         userSuppliedPpdUrl: '',
         effectiveMakeAndModel: '',
@@ -550,9 +550,56 @@
     assertTrue(!!nameField);
     nameField.value = 'edited printer';
 
-    // Assert that the "Add" button is enabled.
-    const addButton = dialog.$$('.action-button');
-    assertTrue(!!addButton);
-    assertTrue(!addButton.disabled);
+    // Assert that the "Save" button is enabled.
+    const saveButton = dialog.$$('.action-button');
+    assertTrue(!!saveButton);
+    assertTrue(!saveButton.disabled);
+  });
+
+  /**
+   * Test that the save button is disabled when the printer address or name is
+   * invalid.
+   */
+  test('EditPrinter', function() {
+    dialog.activePrinter = {
+      ppdManufacturer: '',
+      ppdModel: '',
+      printerAddress: '192.168.1.13',
+      printerAutoconf: false,
+      printerDescription: '',
+      printerId: '',
+      printerManufacturer: '',
+      printerModel: 'HP',
+      printerMakeAndModel: 'Printmaster2000',
+      printerName: 'My Test Printer',
+      printerPPDPath: 'http://myfakeppddownload.com',
+      printerPpdReference: {
+        userSuppliedPpdUrl: '',
+        effectiveMakeAndModel: '',
+        autoconf: false,
+      },
+      printerProtocol: 'ipps',
+      printerQueue: 'moreinfohere',
+      printerStatus: '',
+    };
+
+    assertTrue(!!dialog.$$('#printerName'));
+    assertTrue(!!dialog.$$('#printerAddress'));
+
+    const saveButton = dialog.$$('.action-button');
+    assertTrue(!!saveButton);
+    assertFalse(saveButton.disabled);
+
+    // Change printer address to something invalid.
+    dialog.$.printerAddress.value = 'abcdef:';
+    assertTrue(saveButton.disabled);
+
+    // Change back to something valid.
+    dialog.$.printerAddress.value = 'abcdef:1234';
+    assertFalse(saveButton.disabled);
+
+    // Change printer name to empty
+    dialog.$.printerName.value = '';
+    assertTrue(saveButton.disabled);
   });
 });
diff --git a/chromecast/browser/extensions/api/automation_internal/automation_internal_api.cc b/chromecast/browser/extensions/api/automation_internal/automation_internal_api.cc
index 39f15f0..4cc5c58 100644
--- a/chromecast/browser/extensions/api/automation_internal/automation_internal_api.cc
+++ b/chromecast/browser/extensions/api/automation_internal/automation_internal_api.cc
@@ -426,6 +426,7 @@
       action->end_index = get_text_location_params.end_index;
       break;
     }
+    case api::automation::ACTION_TYPE_SIGNALENDOFTEST:
     case api::automation::ACTION_TYPE_NONE:
       break;
   }
diff --git a/chromecast/common/extensions_api/automation.idl b/chromecast/common/extensions_api/automation.idl
index d684388..06759e3 100644
--- a/chromecast/common/extensions_api/automation.idl
+++ b/chromecast/common/extensions_api/automation.idl
@@ -23,6 +23,7 @@
     clicked,
     documentSelectionChanged,
     documentTitleChanged,
+    endOfTest,
     expandedChanged,
     focus,
     focusContext,
@@ -310,7 +311,8 @@
     setSelection,
     setSequentialFocusNavigationStartingPoint,
     setValue,
-    showContextMenu
+    showContextMenu,
+    signalEndOfTest
   };
 
   // Possible changes to the automation tree. For any given atomic change
diff --git a/chromecast/renderer/extensions/automation_ax_tree_wrapper.cc b/chromecast/renderer/extensions/automation_ax_tree_wrapper.cc
index 2ff74c0..2fd7345 100644
--- a/chromecast/renderer/extensions/automation_ax_tree_wrapper.cc
+++ b/chromecast/renderer/extensions/automation_ax_tree_wrapper.cc
@@ -44,6 +44,8 @@
       return api::automation::EVENT_TYPE_DOCUMENTSELECTIONCHANGED;
     case ax::mojom::Event::kDocumentTitleChanged:
       return api::automation::EVENT_TYPE_DOCUMENTTITLECHANGED;
+    case ax::mojom::Event::kEndOfTest:
+      return api::automation::EVENT_TYPE_ENDOFTEST;
     case ax::mojom::Event::kExpandedChanged:
       return api::automation::EVENT_TYPE_EXPANDEDCHANGED;
     case ax::mojom::Event::kFocus:
@@ -418,6 +420,7 @@
     case api::automation::EVENT_TYPE_NONE:
     case api::automation::EVENT_TYPE_AUTOCORRECTIONOCCURED:
     case api::automation::EVENT_TYPE_CLICKED:
+    case api::automation::EVENT_TYPE_ENDOFTEST:
     case api::automation::EVENT_TYPE_FOCUSCONTEXT:
     case api::automation::EVENT_TYPE_HITTESTRESULT:
     case api::automation::EVENT_TYPE_HOVER:
diff --git a/components/journey/proto/BUILD.gn b/components/journey/proto/BUILD.gn
index 38bfdf1..0556af1 100644
--- a/components/journey/proto/BUILD.gn
+++ b/components/journey/proto/BUILD.gn
@@ -8,5 +8,4 @@
   sources = [
     "batch_get_switcher_journey_from_pageload_request.proto",
   ]
-  deps = []
 }
diff --git a/components/policy/proto/device_management_backend.proto b/components/policy/proto/device_management_backend.proto
index 194575b..3c4855e 100644
--- a/components/policy/proto/device_management_backend.proto
+++ b/components/policy/proto/device_management_backend.proto
@@ -8,6 +8,9 @@
 
 package enterprise_management;
 
+// Everything below this comment will be synchronized between client and server
+// repos ( go/cros-proto-sync ).
+
 // This enum needs to be shared between DeviceRegisterRequest and
 // LicenseAvailability protos. With java_api_version 1, this means that enum
 // needs to be wrapped into a message.
diff --git a/components/security_state/content/content_utils.cc b/components/security_state/content/content_utils.cc
index 8ac2ce8..c8d55bf 100644
--- a/components/security_state/content/content_utils.cc
+++ b/components/security_state/content/content_utils.cc
@@ -77,10 +77,9 @@
 void ExplainSafeBrowsingSecurity(
     const security_state::SecurityInfo& security_info,
     content::SecurityStyleExplanations* security_style_explanations) {
-  if (security_info.malicious_content_status ==
-      security_state::MALICIOUS_CONTENT_STATUS_NONE) {
-    return;
-  }
+  DCHECK_NE(security_info.malicious_content_status,
+            MALICIOUS_CONTENT_STATUS_NONE);
+
   // Override the main summary for the page.
   security_style_explanations->summary =
       l10n_util::GetStringUTF8(IDS_SAFEBROWSING_WARNING);
@@ -435,8 +434,19 @@
   const blink::WebSecurityStyle security_style =
       SecurityLevelToSecurityStyle(security_info.security_level);
 
-  ExplainHTTPSecurity(security_info, security_style_explanations);
-  ExplainSafeBrowsingSecurity(security_info, security_style_explanations);
+  if (security_info.malicious_content_status !=
+      security_state::MALICIOUS_CONTENT_STATUS_NONE) {
+    ExplainSafeBrowsingSecurity(security_info, security_style_explanations);
+  } else if (security_info.is_non_cert_error_page) {
+    security_style_explanations->summary =
+        l10n_util::GetStringUTF8(IDS_ERROR_PAGE_SUMMARY);
+    // In the case of a non cert error page, we usually don't have a
+    // certificate, connection, or content that needs to be explained, e.g. in
+    // the case of a net error, so we can early return.
+    return security_style;
+  } else {
+    ExplainHTTPSecurity(security_info, security_style_explanations);
+  }
 
   // Check if the page is HTTP; if so, no more explanations are needed. Note
   // that SecurityStyleUnauthenticated does not necessarily mean that
diff --git a/components/security_state/content/content_utils_unittest.cc b/components/security_state/content/content_utils_unittest.cc
index ee7f25a..fd58adb 100644
--- a/components/security_state/content/content_utils_unittest.cc
+++ b/components/security_state/content/content_utils_unittest.cc
@@ -189,6 +189,37 @@
             explanations.summary);
 }
 
+// Tests that SecurityInfo flags for non cert errors result in an appropriate
+// summary in SecurityStyleExplanations.
+TEST(SecurityStateContentUtilsTest, GetSecurityStyleForNonCertErrors) {
+  content::SecurityStyleExplanations explanations;
+  security_state::SecurityInfo security_info;
+  security_info.cert_status = 0;
+  security_info.scheme_is_cryptographic = true;
+
+  security_info.is_non_cert_error_page = true;
+  GetSecurityStyle(security_info, &explanations);
+  EXPECT_EQ(l10n_util::GetStringUTF8(IDS_ERROR_PAGE_SUMMARY),
+            explanations.summary);
+}
+
+// Tests that malicious safe browsing data in SecurityInfo triggers the Safe
+// Browsing warning summary when |is_non_cert_error_page| is set to true.
+TEST(SecurityStateContentUtilsTest,
+     GetSecurityStyleForSafeBrowsingNonCertError) {
+  content::SecurityStyleExplanations explanations;
+  security_state::SecurityInfo security_info;
+  security_info.cert_status = 0;
+  security_info.scheme_is_cryptographic = true;
+  security_info.malicious_content_status =
+      security_state::MALICIOUS_CONTENT_STATUS_MALWARE;
+
+  security_info.is_non_cert_error_page = true;
+  GetSecurityStyle(security_info, &explanations);
+  EXPECT_EQ(l10n_util::GetStringUTF8(IDS_SAFEBROWSING_WARNING),
+            explanations.summary);
+}
+
 bool FindSecurityStyleExplanation(
     const std::vector<content::SecurityStyleExplanation>& explanations,
     const std::string& title,
diff --git a/components/security_state/core/security_state.cc b/components/security_state/core/security_state.cc
index f00515e..58a2645 100644
--- a/components/security_state/core/security_state.cc
+++ b/components/security_state/core/security_state.cc
@@ -90,14 +90,21 @@
   const bool is_cryptographic_with_certificate =
       (url.SchemeIsCryptographic() && visible_security_state.certificate);
 
-  // Set the security level to DANGEROUS for major certificate errors.
-  if (is_cryptographic_with_certificate &&
+  const bool is_major_cert_error =
       net::IsCertStatusError(visible_security_state.cert_status) &&
-      !net::IsCertStatusMinorError(visible_security_state.cert_status)) {
+      !net::IsCertStatusMinorError(visible_security_state.cert_status);
+
+  // Set the security level to DANGEROUS for major certificate errors.
+  if (is_cryptographic_with_certificate && is_major_cert_error) {
     security_info->security_level = DANGEROUS;
     return;
   }
 
+  // Set the field indicating when an error page is not a cert error.
+  if (visible_security_state.is_error_page && !is_major_cert_error) {
+    security_info->is_non_cert_error_page = true;
+  }
+
   // data: URLs don't define a secure context, and are a vector for spoofing.
   // Likewise, ftp: URLs are always non-secure, and are uncommon enough that
   // we can treat them as such without significant user impact.
@@ -285,7 +292,8 @@
       obsolete_ssl_status(net::OBSOLETE_SSL_NONE),
       pkp_bypassed(false),
       contained_mixed_form(false),
-      cert_missing_subject_alt_name(false) {}
+      cert_missing_subject_alt_name(false),
+      is_non_cert_error_page(false) {}
 
 SecurityInfo::~SecurityInfo() {}
 
diff --git a/components/security_state/core/security_state.h b/components/security_state/core/security_state.h
index cb59e4b3..ff2fcae 100644
--- a/components/security_state/core/security_state.h
+++ b/components/security_state/core/security_state.h
@@ -148,6 +148,9 @@
   // Contains information about input events that may impact the security
   // level of the page.
   InsecureInputEventData insecure_input_events;
+  // True if the page is an error page, for an error other than a certificate
+  // error.
+  bool is_non_cert_error_page;
 };
 
 // Contains the security state relevant to computing the SecurityInfo
diff --git a/components/security_state/core/security_state_unittest.cc b/components/security_state/core/security_state_unittest.cc
index 53dedf4..317b447c 100644
--- a/components/security_state/core/security_state_unittest.cc
+++ b/components/security_state/core/security_state_unittest.cc
@@ -573,6 +573,22 @@
   EXPECT_EQ(SecurityLevel::HTTP_SHOW_WARNING, security_info.security_level);
 }
 
+// Tests that |is_non_cert_error_page| is properly set.
+TEST(SecurityStateTest, NonCertErrorPage) {
+  TestSecurityStateHelper helper;
+  SecurityInfo security_info;
+  helper.SetUrl(GURL("http://nonexistent.test"));
+  helper.set_is_error_page(true);
+  helper.GetSecurityInfo(&security_info);
+  EXPECT_TRUE(security_info.is_non_cert_error_page);
+
+  // Should be false for cert errors.
+  helper.AddCertStatus(net::CERT_STATUS_DATE_INVALID);
+  SecurityInfo cert_error_security_info;
+  helper.GetSecurityInfo(&cert_error_security_info);
+  EXPECT_FALSE(cert_error_security_info.is_non_cert_error_page);
+}
+
 // Tests that the billing status is set, and it overrides valid HTTPS.
 TEST(SecurityStateTest, BillingOverridesValidHTTPS) {
   TestSecurityStateHelper helper;
diff --git a/components/security_state_strings.grdp b/components/security_state_strings.grdp
index ac2829b..97f86a7 100644
--- a/components/security_state_strings.grdp
+++ b/components/security_state_strings.grdp
@@ -1,6 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <grit-part>
   <!-- Strings describing Chrome security policy for DevTools security panel -->
+  <message name="IDS_ERROR_PAGE_SUMMARY" desc="Main summary for a non cert error page." translateable="false">
+    This is an error page.
+  </message>
   <message name="IDS_NON_CRYPTO_SECURE_SUMMARY" desc="Main summary for where the site has a non-cryptographic secure origin." translateable="false">
     This page has a non-HTTPS secure origin.
   </message>
diff --git a/components/sync/engine_impl/loopback_server/loopback_server.cc b/components/sync/engine_impl/loopback_server/loopback_server.cc
index 009bdb8..91b7933 100644
--- a/components/sync/engine_impl/loopback_server/loopback_server.cc
+++ b/components/sync/engine_impl/loopback_server/loopback_server.cc
@@ -10,15 +10,16 @@
 #include <utility>
 
 #include "base/files/file_util.h"
+#include "base/format_macros.h"
 #include "base/guid.h"
 #include "base/logging.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/rand_util.h"
 #include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
-#include "base/synchronization/lock.h"
 #include "components/sync/engine_impl/loopback_server/persistent_bookmark_entity.h"
 #include "components/sync/engine_impl/loopback_server/persistent_permanent_entity.h"
 #include "components/sync/engine_impl/loopback_server/persistent_tombstone_entity.h"
@@ -51,16 +52,96 @@
 static const char kSyncedBookmarksFolderServerTag[] = "synced_bookmarks";
 static const char kSyncedBookmarksFolderName[] = "Synced Bookmarks";
 
+int GetServerMigrationVersion(
+    const std::map<ModelType, int>& server_migration_versions,
+    ModelType type) {
+  auto server_it = server_migration_versions.find(type);
+  return server_it == server_migration_versions.end() ? 0 : server_it->second;
+}
+
+class ProgressMarkerToken {
+ public:
+  static ProgressMarkerToken FromEmpty(int migration_version) {
+    ProgressMarkerToken token;
+    token.migration_version_ = migration_version;
+    return token;
+  }
+
+  static ProgressMarkerToken FromString(const std::string& s) {
+    DCHECK(!s.empty());
+    const vector<base::StringPiece> splits = base::SplitStringPiece(
+        s, "/", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+    if (splits.size() != 2) {
+      ProgressMarkerToken token;
+      base::StringToInt64(s, &token.entity_version_);
+      return token;
+    }
+    ProgressMarkerToken token;
+    if (!base::StringToInt(splits[0], &token.migration_version_) ||
+        !base::StringToInt64(splits[1], &token.entity_version_)) {
+      return ProgressMarkerToken();
+    }
+    return token;
+  }
+
+  std::string ToString() const {
+    if (migration_version_ == 0) {
+      return base::NumberToString(entity_version_);
+    } else {
+      return base::StringPrintf("%d/%" PRId64, migration_version_,
+                                entity_version_);
+    }
+  }
+
+  int migration_version() const { return migration_version_; }
+  int64_t entity_version() const { return entity_version_; }
+
+  void UpdateWithEntity(int64_t other_entity_version) {
+    entity_version_ = std::max(entity_version_, other_entity_version);
+  }
+
+ private:
+  int migration_version_ = 0;
+  int64_t entity_version_ = 0;
+};
+
 // A filter used during GetUpdates calls to determine what information to
 // send back to the client; filtering out old entities and tracking versions to
 // use in response progress markers. Note that only the GetUpdatesMessage's
 // from_progress_marker is used to determine this; legacy fields are ignored.
 class UpdateSieve {
  public:
-  explicit UpdateSieve(const sync_pb::GetUpdatesMessage& message)
-      : UpdateSieve(MessageToVersionMap(message)) {}
+  UpdateSieve(const sync_pb::GetUpdatesMessage& message,
+              const std::map<ModelType, int>& server_migration_versions)
+      : UpdateSieve(MessageToVersionMap(message, server_migration_versions)) {}
   ~UpdateSieve() {}
 
+  // Verifies if MIGRATION_DONE should be exercised. It intentionally returns
+  // migrations in the order that they were triggered.  Doing it this way
+  // allows the client to queue up two migrations in a row, so the second one
+  // is received while responding to the first.
+  bool ShouldTriggerMigration(
+      const std::map<ModelType, int>& server_migration_versions,
+      std::vector<ModelType>* datatypes_to_migrate) const {
+    DCHECK(datatypes_to_migrate);
+    datatypes_to_migrate->clear();
+
+    for (const auto& request_version : request_version_map_) {
+      const ModelType type = request_version.first;
+      const int client_migration_version =
+          request_version.second.migration_version();
+
+      const int server_migration_version =
+          GetServerMigrationVersion(server_migration_versions, type);
+
+      if (client_migration_version < server_migration_version) {
+        datatypes_to_migrate->push_back(type);
+      }
+    }
+
+    return !datatypes_to_migrate->empty();
+  }
+
   // Sets the progress markers in |get_updates_response| based on the highest
   // version between request progress markers and response entities.
   void SetProgressMarkers(
@@ -70,7 +151,7 @@
           get_updates_response->add_new_progress_marker();
       new_marker->set_data_type_id(
           GetSpecificsFieldNumberFromModelType(kv.first));
-      new_marker->set_token(base::NumberToString(kv.second));
+      new_marker->set_token(kv.second.ToString());
     }
   }
 
@@ -82,7 +163,7 @@
     if (it == request_version_map_.end())
       return false;
     DCHECK_NE(0U, response_version_map_.count(type));
-    return it->second < entity.GetVersion();
+    return it->second.entity_version() < entity.GetVersion();
   }
 
   // Updates internal tracking of max versions to later be used to set response
@@ -90,33 +171,32 @@
   void UpdateProgressMarker(const LoopbackServerEntity& entity) {
     DCHECK(ClientWantsItem(entity));
     ModelType type = entity.GetModelType();
-    response_version_map_[type] =
-        std::max(response_version_map_[type], entity.GetVersion());
+    response_version_map_[type].UpdateWithEntity(entity.GetVersion());
   }
 
  private:
-  using ModelTypeToVersionMap = std::map<ModelType, int64_t>;
+  using ModelTypeToVersionMap = std::map<ModelType, ProgressMarkerToken>;
 
   static UpdateSieve::ModelTypeToVersionMap MessageToVersionMap(
-      const sync_pb::GetUpdatesMessage& get_updates_message) {
+      const sync_pb::GetUpdatesMessage& get_updates_message,
+      const std::map<ModelType, int>& server_migration_versions) {
     DCHECK_GT(get_updates_message.from_progress_marker_size(), 0)
         << "A GetUpdates request must have at least one progress marker.";
     ModelTypeToVersionMap request_version_map;
 
     for (int i = 0; i < get_updates_message.from_progress_marker_size(); i++) {
-      sync_pb::DataTypeProgressMarker marker =
+      const sync_pb::DataTypeProgressMarker& marker =
           get_updates_message.from_progress_marker(i);
 
-      int64_t version = 0;
-      // Let the version remain zero if there is no token or an empty token (the
-      // first request for this type).
-      if (marker.has_token() && !marker.token().empty()) {
-        bool parsed = base::StringToInt64(marker.token(), &version);
-        DCHECK(parsed) << "Unable to parse progress marker token.";
-      }
-
-      ModelType model_type =
+      const ModelType model_type =
           syncer::GetModelTypeFromSpecificsFieldNumber(marker.data_type_id());
+      const int server_migration_version =
+          GetServerMigrationVersion(server_migration_versions, model_type);
+      const ProgressMarkerToken version =
+          marker.token().empty()
+              ? ProgressMarkerToken::FromEmpty(server_migration_version)
+              : ProgressMarkerToken::FromString(marker.token());
+
       DCHECK(request_version_map.find(model_type) == request_version_map.end());
       request_version_map[model_type] = version;
     }
@@ -261,10 +341,12 @@
     response_proto.set_error_code(sync_pb::SyncEnums::NOT_MY_BIRTHDAY);
   } else {
     bool success = false;
+    std::vector<ModelType> datatypes_to_migrate;
     switch (message.message_contents()) {
       case sync_pb::ClientToServerMessage::GET_UPDATES:
         success = HandleGetUpdatesRequest(message.get_updates(),
-                                          response_proto.mutable_get_updates());
+                                          response_proto.mutable_get_updates(),
+                                          &datatypes_to_migrate);
         break;
       case sync_pb::ClientToServerMessage::COMMIT:
         success = HandleCommitRequest(message.commit(),
@@ -280,14 +362,22 @@
         return net::HTTP_BAD_REQUEST;
     }
 
-    if (!success) {
+    if (success) {
+      response_proto.set_error_code(sync_pb::SyncEnums::SUCCESS);
+    } else if (datatypes_to_migrate.empty()) {
       UMA_HISTOGRAM_ENUMERATION(
           "Sync.Local.RequestTypeOnError", message.message_contents(),
           sync_pb::ClientToServerMessage_Contents_Contents_MAX);
       return net::HTTP_INTERNAL_SERVER_ERROR;
+    } else {
+      DLOG(WARNING) << "Migration required for " << datatypes_to_migrate.size()
+                    << " datatypes";
+      for (ModelType type : datatypes_to_migrate) {
+        response_proto.add_migrated_data_type_id(
+            GetSpecificsFieldNumberFromModelType(type));
+      }
+      response_proto.set_error_code(sync_pb::SyncEnums::MIGRATION_DONE);
     }
-
-    response_proto.set_error_code(sync_pb::SyncEnums::SUCCESS);
   }
 
   response_proto.set_store_birthday(GetStoreBirthday());
@@ -304,10 +394,17 @@
 
 bool LoopbackServer::HandleGetUpdatesRequest(
     const sync_pb::GetUpdatesMessage& get_updates,
-    sync_pb::GetUpdatesResponse* response) {
+    sync_pb::GetUpdatesResponse* response,
+    std::vector<ModelType>* datatypes_to_migrate) {
   response->set_changes_remaining(0);
 
-  auto sieve = std::make_unique<UpdateSieve>(get_updates);
+  auto sieve = std::make_unique<UpdateSieve>(get_updates, migration_versions_);
+
+  if (sieve->ShouldTriggerMigration(migration_versions_,
+                                    datatypes_to_migrate)) {
+    DCHECK(!datatypes_to_migrate->empty());
+    return false;
+  }
 
   std::vector<const LoopbackServerEntity*> wanted_entities;
   for (const auto& id_and_entity : entities_) {
diff --git a/components/sync/engine_impl/loopback_server/loopback_server.h b/components/sync/engine_impl/loopback_server/loopback_server.h
index 9de929c..36ead60 100644
--- a/components/sync/engine_impl/loopback_server/loopback_server.h
+++ b/components/sync/engine_impl/loopback_server/loopback_server.h
@@ -67,6 +67,12 @@
     bag_of_chips_ = bag_of_chips;
   }
 
+  void TriggerMigrationForTesting(ModelTypeSet model_types) {
+    for (const ModelType type : model_types) {
+      ++migration_versions_[type];
+    }
+  }
+
  private:
   // Allow the FakeServer decorator to inspect the internals of this class.
   friend class fake_server::FakeServer;
@@ -83,7 +89,8 @@
 
   // Processes a GetUpdates call.
   bool HandleGetUpdatesRequest(const sync_pb::GetUpdatesMessage& get_updates,
-                               sync_pb::GetUpdatesResponse* response);
+                               sync_pb::GetUpdatesResponse* response,
+                               std::vector<ModelType>* datatypes_to_migrate);
 
   // Processes a Commit call.
   bool HandleCommitRequest(const sync_pb::CommitMessage& message,
@@ -211,6 +218,8 @@
 
   base::Optional<sync_pb::ChipBag> bag_of_chips_;
 
+  std::map<ModelType, int> migration_versions_;
+
   int max_get_updates_batch_size_ = 1000000;
 
   EntityMap entities_;
diff --git a/components/sync/test/fake_server/fake_server.cc b/components/sync/test/fake_server/fake_server.cc
index 1f85d012..9f59b2d 100644
--- a/components/sync/test/fake_server/fake_server.cc
+++ b/components/sync/test/fake_server/fake_server.cc
@@ -458,6 +458,11 @@
   loopback_server_->SetBagOfChipsForTesting(bag_of_chips);
 }
 
+void FakeServer::TriggerMigrationDoneError(syncer::ModelTypeSet types) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  loopback_server_->TriggerMigrationForTesting(types);
+}
+
 const std::set<std::string>& FakeServer::GetCommittedHistoryURLs() const {
   return committed_history_urls_;
 }
diff --git a/components/sync/test/fake_server/fake_server.h b/components/sync/test/fake_server/fake_server.h
index 80f813cf..e7eeb4c 100644
--- a/components/sync/test/fake_server/fake_server.h
+++ b/components/sync/test/fake_server/fake_server.h
@@ -176,6 +176,8 @@
   // Sets the bag of chips returned by the server.
   void SetBagOfChips(const sync_pb::ChipBag& bag_of_chips);
 
+  void TriggerMigrationDoneError(syncer::ModelTypeSet types);
+
   // Implement LoopbackServer::ObserverForTests:
   void OnCommit(const std::string& committer_id,
                 syncer::ModelTypeSet committed_model_types) override;
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.page_info_visible_browser_ui.Pixel_XL-25.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.page_info_visible_browser_ui.Pixel_XL-25.png.sha1
index 41d5720..845bac2 100644
--- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.page_info_visible_browser_ui.Pixel_XL-25.png.sha1
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.page_info_visible_browser_ui.Pixel_XL-25.png.sha1
@@ -1 +1 @@
-745db4f095c1ef7d49a17f27ffb990957dbe5a8f
\ No newline at end of file
+52541d2087d794f97ed191d74efd366c77012645
\ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.page_info_visible_browser_ui.Pixel_XL-26.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.page_info_visible_browser_ui.Pixel_XL-26.png.sha1
index 6dd682d..6f61104 100644
--- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.page_info_visible_browser_ui.Pixel_XL-26.png.sha1
+++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.page_info_visible_browser_ui.Pixel_XL-26.png.sha1
@@ -1 +1 @@
-693e3eb091ac55020acc6a70cab51e4fb9d089dc
\ No newline at end of file
+6c96578e1028dcd05b3fa204af5cf17a9e75fd26
\ No newline at end of file
diff --git a/components/viz/host/DEPS b/components/viz/host/DEPS
index 1a6b0e00..9a1738b3 100644
--- a/components/viz/host/DEPS
+++ b/components/viz/host/DEPS
@@ -13,6 +13,7 @@
   "+gpu/ipc/host",
   "+media/capture/mojom/video_capture_types.mojom.h",
   "+mojo/public/cpp",
+  "+services/service_manager/public",
   "+services/viz/privileged/interfaces",
   "+services/viz/public/interfaces",
   "+services/viz/public/interfaces/hit_test",
diff --git a/components/viz/host/gpu_host_impl.cc b/components/viz/host/gpu_host_impl.cc
index 4fd50ad9..a5021e43 100644
--- a/components/viz/host/gpu_host_impl.cc
+++ b/components/viz/host/gpu_host_impl.cc
@@ -331,6 +331,12 @@
   delegate_->BindInterface(interface_name, std::move(interface_pipe));
 }
 
+void GpuHostImpl::RunService(
+    const std::string& service_name,
+    mojo::PendingReceiver<service_manager::mojom::Service> receiver) {
+  delegate_->RunService(service_name, std::move(receiver));
+}
+
 mojom::GpuService* GpuHostImpl::gpu_service() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(gpu_service_ptr_.is_bound());
diff --git a/components/viz/host/gpu_host_impl.h b/components/viz/host/gpu_host_impl.h
index b5067b1..a2a7da2 100644
--- a/components/viz/host/gpu_host_impl.h
+++ b/components/viz/host/gpu_host_impl.h
@@ -24,7 +24,9 @@
 #include "gpu/command_buffer/common/activity_flags.h"
 #include "gpu/config/gpu_domain_guilt.h"
 #include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/system/message_pipe.h"
+#include "services/service_manager/public/mojom/service.mojom.h"
 #include "services/viz/privileged/interfaces/compositing/frame_sink_manager.mojom.h"
 #include "services/viz/privileged/interfaces/gl/gpu_host.mojom.h"
 #include "services/viz/privileged/interfaces/gl/gpu_service.mojom.h"
@@ -97,6 +99,9 @@
     virtual void BindInterface(
         const std::string& interface_name,
         mojo::ScopedMessagePipeHandle interface_pipe) = 0;
+    virtual void RunService(
+        const std::string& service_name,
+        mojo::PendingReceiver<service_manager::mojom::Service> receiver) = 0;
 #if defined(USE_OZONE)
     virtual void TerminateGpuProcess(const std::string& message) = 0;
 
@@ -185,6 +190,9 @@
 
   void BindInterface(const std::string& interface_name,
                      mojo::ScopedMessagePipeHandle interface_pipe);
+  void RunService(
+      const std::string& service_name,
+      mojo::PendingReceiver<service_manager::mojom::Service> receiver);
 
   mojom::GpuService* gpu_service();
 
diff --git a/content/browser/accessibility/accessibility_event_recorder.h b/content/browser/accessibility/accessibility_event_recorder.h
index e31c564..6e12f95 100644
--- a/content/browser/accessibility/accessibility_event_recorder.h
+++ b/content/browser/accessibility/accessibility_event_recorder.h
@@ -63,6 +63,9 @@
     callback_ = std::move(callback);
   }
 
+  // Called to ensure the event recorder has finished recording async events.
+  virtual void FlushAsyncEvents() {}
+
   // Access the vector of human-readable event logs, one string per event.
   const std::vector<std::string>& event_logs() { return event_logs_; }
 
diff --git a/content/browser/accessibility/accessibility_event_recorder_uia_win.cc b/content/browser/accessibility/accessibility_event_recorder_uia_win.cc
index efe13e61..aaf0b532 100644
--- a/content/browser/accessibility/accessibility_event_recorder_uia_win.cc
+++ b/content/browser/accessibility/accessibility_event_recorder_uia_win.cc
@@ -4,14 +4,19 @@
 
 #include "content/browser/accessibility/accessibility_event_recorder_uia_win.h"
 
-#include <string>
+#include <algorithm>
+#include <utility>
 
+#include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/win/scoped_bstr.h"
+#include "base/win/scoped_com_initializer.h"
 #include "base/win/scoped_variant.h"
+#include "content/browser/accessibility/accessibility_tree_formatter_utils_win.h"
 #include "content/browser/accessibility/browser_accessibility_com_win.h"
 #include "content/browser/accessibility/browser_accessibility_manager.h"
+#include "content/browser/accessibility/browser_accessibility_manager_win.h"
 #include "ui/base/win/atl_module.h"
 
 namespace content {
@@ -23,11 +28,23 @@
   return base::UTF16ToUTF8(str16);
 }
 
+std::string UiaIdentifierToStringPretty(int32_t id) {
+  auto str = base::UTF16ToUTF8(UiaIdentifierToString(id));
+  // Remove UIA_ prefix, and EventId/PropertyId suffixes
+  if (base::StartsWith(str, "UIA_", base::CompareCase::SENSITIVE))
+    str = str.substr(base::size("UIA_") - 1);
+  if (base::EndsWith(str, "EventId", base::CompareCase::SENSITIVE))
+    str = str.substr(0, str.size() - base::size("EventId") + 1);
+  if (base::EndsWith(str, "PropertyId", base::CompareCase::SENSITIVE))
+    str = str.substr(0, str.size() - base::size("PropertyId") + 1);
+  return str;
+}
+
 }  // namespace
 
 // static
-AccessibilityEventRecorderUia* AccessibilityEventRecorderUia::instance_ =
-    nullptr;
+volatile base::subtle::Atomic32 AccessibilityEventRecorderUia::instantiated_ =
+    0;
 
 // static
 std::unique_ptr<AccessibilityEventRecorder>
@@ -44,56 +61,191 @@
     base::ProcessId pid,
     const base::StringPiece& application_name_match_pattern)
     : AccessibilityEventRecorder(manager) {
-  CHECK(!instance_) << "There can be only one instance of"
-                    << " AccessibilityEventRecorder at a time.";
+  CHECK(!base::subtle::NoBarrier_AtomicExchange(&instantiated_, 1))
+      << "There can be only one instance at a time.";
+
+  // Find the root content window
+  HWND hwnd = manager->GetRoot()->GetTargetForNativeAccessibilityEvent();
+  CHECK(hwnd);
+
+  // Create the event thread, and pump messages via |initialization_loop| until
+  // initialization is complete.
+  base::RunLoop initialization_loop;
+  base::PlatformThread::Create(0, &thread_, &thread_handle_);
+  thread_.Init(this, hwnd, initialization_loop, shutdown_loop_);
+  initialization_loop.Run();
+}
+
+AccessibilityEventRecorderUia::~AccessibilityEventRecorderUia() {
+  base::subtle::NoBarrier_AtomicExchange(&instantiated_, 0);
+}
+
+void AccessibilityEventRecorderUia::FlushAsyncEvents() {
+  // Pump messages via |shutdown_loop_| until the thread is complete.
+  shutdown_loop_.Run();
+  base::PlatformThread::Join(thread_handle_);
+}
+
+AccessibilityEventRecorderUia::Thread::Thread() {}
+
+AccessibilityEventRecorderUia::Thread::~Thread() {}
+
+void AccessibilityEventRecorderUia::Thread::Init(
+    AccessibilityEventRecorderUia* owner,
+    HWND hwnd,
+    base::RunLoop& initialization,
+    base::RunLoop& shutdown) {
+  owner_ = owner;
+  hwnd_ = hwnd;
+  initialization_complete_ = initialization.QuitClosure();
+  shutdown_complete_ = shutdown.QuitClosure();
+}
+
+void AccessibilityEventRecorderUia::Thread::ThreadMain() {
+  // UIA calls must be made on an MTA thread to prevent random timeouts.
+  base::win::ScopedCOMInitializer com_init{
+      base::win::ScopedCOMInitializer::kMTA};
 
   // Create an instance of the CUIAutomation class.
   CoCreateInstance(CLSID_CUIAutomation, NULL, CLSCTX_INPROC_SERVER,
                    IID_IUIAutomation, &uia_);
   CHECK(uia_.Get());
 
-  uia_->CreateCacheRequest(&cache_request_);
-  CHECK(cache_request_.Get());
+  // Register the custom event to mark the end of the test.
+  Microsoft::WRL::ComPtr<IUIAutomationRegistrar> registrar;
+  CoCreateInstance(CLSID_CUIAutomationRegistrar, NULL, CLSCTX_INPROC_SERVER,
+                   IID_IUIAutomationRegistrar, &registrar);
+  CHECK(registrar.Get());
+  UIAutomationEventInfo custom_event = {kUiaTestCompleteSentinelGuid,
+                                        kUiaTestCompleteSentinel};
+  CHECK(
+      SUCCEEDED(registrar->RegisterEvent(&custom_event, &shutdown_sentinel_)));
 
-  // Find the root IUIAutomationElement for the content window
-  HWND hwnd = manager->GetRoot()->GetTargetForNativeAccessibilityEvent();
-  CHECK(hwnd);
-
-  Microsoft::WRL::ComPtr<IUIAutomationElement> root;
-  uia_->ElementFromHandle(hwnd, &root);
-  CHECK(root.Get());
+  // Find the IUIAutomationElement for the root content window
+  uia_->ElementFromHandle(hwnd_, &root_);
+  CHECK(root_.Get());
 
   // Create the event handler
   ui::win::CreateATLModuleIfNeeded();
   CHECK(
       SUCCEEDED(CComObject<EventHandler>::CreateInstance(&uia_event_handler_)));
-  uia_event_handler_->Init(this, root);
+  uia_event_handler_->AddRef();
+  uia_event_handler_->Init(this, root_);
+
+  // Subscribe to the shutdown sentinel event
+  uia_->AddAutomationEventHandler(shutdown_sentinel_, root_.Get(),
+                                  TreeScope::TreeScope_Subtree, nullptr,
+                                  uia_event_handler_.Get());
 
   // Subscribe to focus events
   uia_->AddFocusChangedEventHandler(nullptr, uia_event_handler_.Get());
 
-  instance_ = this;
-}
+  // Subscribe to all automation events
+  static const EVENTID kMinEvent = UIA_ToolTipOpenedEventId;
+  static const EVENTID kMaxEvent = UIA_NotificationEventId;
+  for (EVENTID event_id = kMinEvent; event_id <= kMaxEvent; ++event_id) {
+    uia_->AddAutomationEventHandler(event_id, root_.Get(),
+                                    TreeScope::TreeScope_Subtree, nullptr,
+                                    uia_event_handler_.Get());
+  }
 
-AccessibilityEventRecorderUia::~AccessibilityEventRecorderUia() {
-  uia_event_handler_->owner_ = nullptr;
+  // Signal that initialization is complete; this will wake the main thread to
+  // start executing the test.
+  std::move(initialization_complete_).Run();
+
+  // Wait for shutdown signal
+  shutdown_signal_.Wait();
+
+  // Due to a bug in Windows, events are raised exactly twice for any in-proc
+  // off-thread event listeners. (The bug has been acknowledged by the Windows
+  // team, but it's a lower priority since the scenario is rare outside of
+  // testing.) We filter out the duplicate events here, and forward the
+  // remaining events to our owner.
+  {
+    base::AutoLock lock{on_event_lock_};
+    CHECK_LE(event_logs_.size(), 2u);
+    if (event_logs_.size() == 1) {
+      // Only received events on a single thread... perhaps the bug was fixed?
+      // Forward all events.
+      for (auto&& event : event_logs_.begin()->second)
+        owner_->OnEvent(event);
+    } else if (event_logs_.size() == 2) {
+      // Events were raised on two threads, as expected.  Sort the lists and
+      // forward events, eliminating duplicates that occur in both threads.
+      auto&& events_thread1 = event_logs_.begin()->second;
+      auto&& events_thread2 = (++event_logs_.begin())->second;
+
+      std::sort(events_thread1.begin(), events_thread1.end());
+      std::sort(events_thread2.begin(), events_thread2.end());
+
+      auto it1 = events_thread1.begin();
+      auto it2 = events_thread2.begin();
+      while (it1 < events_thread1.end() && it2 < events_thread2.end()) {
+        if (*it1 == *it2) {
+          owner_->OnEvent(*it1);
+          it1++;
+          it2++;
+        } else if (*it1 < *it2) {
+          owner_->OnEvent(*it1);
+          it1++;
+        } else {
+          owner_->OnEvent(*it2);
+          it2++;
+        }
+      }
+      while (it1 < events_thread1.end())
+        owner_->OnEvent(*it1++);
+      while (it2 < events_thread2.end())
+        owner_->OnEvent(*it2++);
+    }
+  }
+
+  // Signal thread shutdown complete; this will wake the main thread to compile
+  // test results and compare against the expected results.
+  std::move(shutdown_complete_).Run();
+
+  // Cleanup
+  uia_event_handler_->CleanUp();
   uia_event_handler_.Reset();
-  instance_ = nullptr;
+  root_.Reset();
+  uia_.Reset();
 }
 
-AccessibilityEventRecorderUia::EventHandler::EventHandler() {}
+void AccessibilityEventRecorderUia::Thread::SendShutdownSignal() {
+  // We expect to see the shutdown sentinel exactly twice (due to the Windows
+  // bug detailed in |ThreadMain|), so don't actually shut down the thread until
+  // the second call.
+  if (shutdown_sentinel_received_)
+    shutdown_signal_.Signal();
+  else
+    shutdown_sentinel_received_ = true;
+}
 
-AccessibilityEventRecorderUia::EventHandler::~EventHandler() {}
+void AccessibilityEventRecorderUia::Thread::OnEvent(const std::string& event) {
+  // We need to synchronize event logging, since UIA event callbacks can be
+  // coming from multiple threads.
+  base::AutoLock lock{on_event_lock_};
+  event_logs_[base::PlatformThread::CurrentId()].push_back(event);
+}
 
-void AccessibilityEventRecorderUia::EventHandler::Init(
-    AccessibilityEventRecorderUia* owner,
+AccessibilityEventRecorderUia::Thread::EventHandler::EventHandler() {}
+
+AccessibilityEventRecorderUia::Thread::EventHandler::~EventHandler() {}
+
+void AccessibilityEventRecorderUia::Thread::EventHandler::Init(
+    AccessibilityEventRecorderUia::Thread* owner,
     Microsoft::WRL::ComPtr<IUIAutomationElement> root) {
   owner_ = owner;
   root_ = root;
 }
 
+void AccessibilityEventRecorderUia::Thread::EventHandler::CleanUp() {
+  owner_ = nullptr;
+  root_.Reset();
+}
+
 STDMETHODIMP
-AccessibilityEventRecorderUia::EventHandler::HandleFocusChangedEvent(
+AccessibilityEventRecorderUia::Thread::EventHandler::HandleFocusChangedEvent(
     IUIAutomationElement* sender) {
   if (!owner_)
     return S_OK;
@@ -115,14 +267,37 @@
     return S_OK;
   }
 
-  std::string log = base::StringPrintf("UIA_AutomationFocusChangedEventId %s",
+  std::string log = base::StringPrintf("AutomationFocusChanged %s",
                                        GetSenderInfo(sender).c_str());
   owner_->OnEvent(log);
 
   return S_OK;
 }
 
-std::string AccessibilityEventRecorderUia::EventHandler::GetSenderInfo(
+STDMETHODIMP
+AccessibilityEventRecorderUia::Thread::EventHandler::HandleAutomationEvent(
+    IUIAutomationElement* sender,
+    EVENTID event_id) {
+  if (owner_) {
+    if (event_id == owner_->shutdown_sentinel_) {
+      // This is a sentinel value that tells us the tests are finished.
+      owner_->SendShutdownSignal();
+    } else {
+      std::string event_str = UiaIdentifierToStringPretty(event_id);
+      if (event_str.empty()) {
+        VLOG(1) << "Ignoring UIA automation event " << event_id;
+        return S_OK;
+      }
+
+      std::string log = base::StringPrintf("%s %s", event_str.c_str(),
+                                           GetSenderInfo(sender).c_str());
+      owner_->OnEvent(log);
+    }
+  }
+  return S_OK;
+}
+
+std::string AccessibilityEventRecorderUia::Thread::EventHandler::GetSenderInfo(
     IUIAutomationElement* sender) {
   std::string sender_info = "";
 
diff --git a/content/browser/accessibility/accessibility_event_recorder_uia_win.h b/content/browser/accessibility/accessibility_event_recorder_uia_win.h
index e3aecc2..f3d7389c 100644
--- a/content/browser/accessibility/accessibility_event_recorder_uia_win.h
+++ b/content/browser/accessibility/accessibility_event_recorder_uia_win.h
@@ -9,7 +9,15 @@
 #include <stdint.h>
 #include <uiautomation.h>
 #include <wrl/client.h>
+#include <map>
+#include <string>
+#include <vector>
 
+#include "base/atomicops.h"
+#include "base/run_loop.h"
+#include "base/synchronization/lock.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/threading/platform_thread.h"
 #include "base/win/atl.h"
 #include "content/browser/accessibility/accessibility_event_recorder.h"
 
@@ -18,52 +26,99 @@
 class AccessibilityEventRecorderUia : public AccessibilityEventRecorder {
  public:
   AccessibilityEventRecorderUia(
-      BrowserAccessibilityManager* manager = nullptr,
-      base::ProcessId pid = 0,
-      const base::StringPiece& application_name_match_pattern =
-          base::StringPiece());
+      BrowserAccessibilityManager* manager,
+      base::ProcessId pid,
+      const base::StringPiece& application_name_match_pattern);
   ~AccessibilityEventRecorderUia() override;
 
   static std::unique_ptr<AccessibilityEventRecorder> CreateUia(
-      BrowserAccessibilityManager* manager = nullptr,
-      base::ProcessId pid = 0,
-      const base::StringPiece& application_name_match_pattern =
-          base::StringPiece());
+      BrowserAccessibilityManager* manager,
+      base::ProcessId pid,
+      const base::StringPiece& application_name_match_pattern);
+
+  // Called to ensure the event recorder has finished recording async events.
+  void FlushAsyncEvents() override;
 
  private:
-  Microsoft::WRL::ComPtr<IUIAutomation> uia_;
-  Microsoft::WRL::ComPtr<IUIAutomationCacheRequest> cache_request_;
-  static AccessibilityEventRecorderUia* instance_;
+  // Used to prevent creation of multiple instances simultaneously
+  static volatile base::subtle::Atomic32 instantiated_;
 
-  // An implementation of various UIA interface that forward event
-  // notifications to the owning event recorder.
-  class EventHandler : public CComObjectRootEx<CComMultiThreadModel>,
-                       public IUIAutomationFocusChangedEventHandler {
+  // All UIA calls need to be made on a secondary MTA thread to avoid sporadic
+  // test hangs / timeouts.
+  class Thread : public base::PlatformThread::Delegate {
    public:
-    explicit EventHandler();
-    virtual ~EventHandler();
+    Thread();
+    ~Thread() override;
 
     void Init(AccessibilityEventRecorderUia* owner,
-              Microsoft::WRL::ComPtr<IUIAutomationElement> root);
+              HWND hwnd,
+              base::RunLoop& initialization_loop,
+              base::RunLoop& shutdown_loop);
 
-    BEGIN_COM_MAP(EventHandler)
-    COM_INTERFACE_ENTRY(IUIAutomationFocusChangedEventHandler)
-    END_COM_MAP()
+    void SendShutdownSignal();
 
-    // IUIAutomationFocusChangedEventHandler interface.
-    STDMETHOD(HandleFocusChangedEvent)(IUIAutomationElement* sender) override;
-
-    // Points to the event recorder to receive notifications.
-    AccessibilityEventRecorderUia* owner_;
+    void ThreadMain() override;
 
    private:
-    std::string GetSenderInfo(IUIAutomationElement* sender);
+    AccessibilityEventRecorderUia* owner_ = nullptr;
+    HWND hwnd_ = NULL;
+    EVENTID shutdown_sentinel_ = 0;
 
+    Microsoft::WRL::ComPtr<IUIAutomation> uia_;
     Microsoft::WRL::ComPtr<IUIAutomationElement> root_;
 
-    DISALLOW_COPY_AND_ASSIGN(EventHandler);
+    // Thread synchronization members
+    base::OnceClosure initialization_complete_;
+    base::OnceClosure shutdown_complete_;
+    base::WaitableEvent shutdown_signal_;
+    bool shutdown_sentinel_received_ = false;
+
+    // Thread-specific wrapper for OnEvent to handle necessary locking
+    void OnEvent(const std::string& event);
+    base::Lock on_event_lock_;
+    std::map<base::PlatformThreadId, std::vector<std::string>> event_logs_;
+
+    // An implementation of various UIA interfaces that forward event
+    // notifications to the owning event recorder.
+    class EventHandler : public CComObjectRootEx<CComMultiThreadModel>,
+                         public IUIAutomationFocusChangedEventHandler,
+                         public IUIAutomationEventHandler {
+     public:
+      EventHandler();
+      virtual ~EventHandler();
+
+      void Init(AccessibilityEventRecorderUia::Thread* owner,
+                Microsoft::WRL::ComPtr<IUIAutomationElement> root);
+      void CleanUp();
+
+      BEGIN_COM_MAP(EventHandler)
+      COM_INTERFACE_ENTRY(IUIAutomationFocusChangedEventHandler)
+      COM_INTERFACE_ENTRY(IUIAutomationEventHandler)
+      END_COM_MAP()
+
+      // IUIAutomationFocusChangedEventHandler interface.
+      STDMETHOD(HandleFocusChangedEvent)(IUIAutomationElement* sender) override;
+
+      // IUIAutomationEventHandler interface.
+      STDMETHOD(HandleAutomationEvent)
+      (IUIAutomationElement* sender, EVENTID event_id) override;
+
+      // Points to the event recorder to receive notifications.
+      AccessibilityEventRecorderUia::Thread* owner_ = nullptr;
+
+     private:
+      std::string GetSenderInfo(IUIAutomationElement* sender);
+
+      Microsoft::WRL::ComPtr<IUIAutomationElement> root_;
+
+      DISALLOW_COPY_AND_ASSIGN(EventHandler);
+    };
+    Microsoft::WRL::ComPtr<CComObject<EventHandler>> uia_event_handler_;
   };
-  Microsoft::WRL::ComPtr<CComObject<EventHandler>> uia_event_handler_;
+
+  Thread thread_;
+  base::RunLoop shutdown_loop_;
+  base::PlatformThreadHandle thread_handle_;
 
   DISALLOW_COPY_AND_ASSIGN(AccessibilityEventRecorderUia);
 };
diff --git a/content/browser/accessibility/accessibility_tree_formatter_utils_win.cc b/content/browser/accessibility/accessibility_tree_formatter_utils_win.cc
index a3ad758a..037470f 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_utils_win.cc
+++ b/content/browser/accessibility/accessibility_tree_formatter_utils_win.cc
@@ -5,6 +5,7 @@
 #include "content/browser/accessibility/accessibility_tree_formatter_utils_win.h"
 
 #include <oleacc.h>
+#include <uiautomation.h>
 
 #include <map>
 #include <string>
@@ -294,4 +295,223 @@
   return base::JoinString(strings, base::ASCIIToUTF16(","));
 }
 
+CONTENT_EXPORT base::string16 UiaIdentifierToString(int32_t identifier) {
+  static const PlatformConstantToNameEntry id_table[] = {
+      // Events
+      QUOTE(UIA_ToolTipOpenedEventId),
+      QUOTE(UIA_ToolTipClosedEventId),
+      QUOTE(UIA_StructureChangedEventId),
+      QUOTE(UIA_MenuOpenedEventId),
+      QUOTE(UIA_AutomationPropertyChangedEventId),
+      QUOTE(UIA_AutomationFocusChangedEventId),
+      QUOTE(UIA_AsyncContentLoadedEventId),
+      QUOTE(UIA_MenuClosedEventId),
+      QUOTE(UIA_LayoutInvalidatedEventId),
+      QUOTE(UIA_Invoke_InvokedEventId),
+      QUOTE(UIA_SelectionItem_ElementAddedToSelectionEventId),
+      QUOTE(UIA_SelectionItem_ElementRemovedFromSelectionEventId),
+      QUOTE(UIA_SelectionItem_ElementSelectedEventId),
+      QUOTE(UIA_Selection_InvalidatedEventId),
+      QUOTE(UIA_Text_TextSelectionChangedEventId),
+      QUOTE(UIA_Text_TextChangedEventId),
+      QUOTE(UIA_Window_WindowOpenedEventId),
+      QUOTE(UIA_Window_WindowClosedEventId),
+      QUOTE(UIA_MenuModeStartEventId),
+      QUOTE(UIA_MenuModeEndEventId),
+      QUOTE(UIA_InputReachedTargetEventId),
+      QUOTE(UIA_InputReachedOtherElementEventId),
+      QUOTE(UIA_InputDiscardedEventId),
+      QUOTE(UIA_SystemAlertEventId),
+      QUOTE(UIA_LiveRegionChangedEventId),
+      QUOTE(UIA_HostedFragmentRootsInvalidatedEventId),
+      QUOTE(UIA_Drag_DragStartEventId),
+      QUOTE(UIA_Drag_DragCancelEventId),
+      QUOTE(UIA_Drag_DragCompleteEventId),
+      QUOTE(UIA_DropTarget_DragEnterEventId),
+      QUOTE(UIA_DropTarget_DragLeaveEventId),
+      QUOTE(UIA_DropTarget_DroppedEventId),
+      QUOTE(UIA_TextEdit_TextChangedEventId),
+      QUOTE(UIA_TextEdit_ConversionTargetChangedEventId),
+      QUOTE(UIA_ChangesEventId),
+      QUOTE(UIA_NotificationEventId),
+      // Properties
+      QUOTE(UIA_RuntimeIdPropertyId),
+      QUOTE(UIA_BoundingRectanglePropertyId),
+      QUOTE(UIA_ProcessIdPropertyId),
+      QUOTE(UIA_ControlTypePropertyId),
+      QUOTE(UIA_LocalizedControlTypePropertyId),
+      QUOTE(UIA_NamePropertyId),
+      QUOTE(UIA_AcceleratorKeyPropertyId),
+      QUOTE(UIA_AccessKeyPropertyId),
+      QUOTE(UIA_HasKeyboardFocusPropertyId),
+      QUOTE(UIA_IsKeyboardFocusablePropertyId),
+      QUOTE(UIA_IsEnabledPropertyId),
+      QUOTE(UIA_AutomationIdPropertyId),
+      QUOTE(UIA_ClassNamePropertyId),
+      QUOTE(UIA_HelpTextPropertyId),
+      QUOTE(UIA_ClickablePointPropertyId),
+      QUOTE(UIA_CulturePropertyId),
+      QUOTE(UIA_IsControlElementPropertyId),
+      QUOTE(UIA_IsContentElementPropertyId),
+      QUOTE(UIA_LabeledByPropertyId),
+      QUOTE(UIA_IsPasswordPropertyId),
+      QUOTE(UIA_NativeWindowHandlePropertyId),
+      QUOTE(UIA_ItemTypePropertyId),
+      QUOTE(UIA_IsOffscreenPropertyId),
+      QUOTE(UIA_OrientationPropertyId),
+      QUOTE(UIA_FrameworkIdPropertyId),
+      QUOTE(UIA_IsRequiredForFormPropertyId),
+      QUOTE(UIA_ItemStatusPropertyId),
+      QUOTE(UIA_IsDockPatternAvailablePropertyId),
+      QUOTE(UIA_IsExpandCollapsePatternAvailablePropertyId),
+      QUOTE(UIA_IsGridItemPatternAvailablePropertyId),
+      QUOTE(UIA_IsGridPatternAvailablePropertyId),
+      QUOTE(UIA_IsInvokePatternAvailablePropertyId),
+      QUOTE(UIA_IsMultipleViewPatternAvailablePropertyId),
+      QUOTE(UIA_IsRangeValuePatternAvailablePropertyId),
+      QUOTE(UIA_IsScrollPatternAvailablePropertyId),
+      QUOTE(UIA_IsScrollItemPatternAvailablePropertyId),
+      QUOTE(UIA_IsSelectionItemPatternAvailablePropertyId),
+      QUOTE(UIA_IsSelectionPatternAvailablePropertyId),
+      QUOTE(UIA_IsTablePatternAvailablePropertyId),
+      QUOTE(UIA_IsTableItemPatternAvailablePropertyId),
+      QUOTE(UIA_IsTextPatternAvailablePropertyId),
+      QUOTE(UIA_IsTogglePatternAvailablePropertyId),
+      QUOTE(UIA_IsTransformPatternAvailablePropertyId),
+      QUOTE(UIA_IsValuePatternAvailablePropertyId),
+      QUOTE(UIA_IsWindowPatternAvailablePropertyId),
+      QUOTE(UIA_ValueValuePropertyId),
+      QUOTE(UIA_ValueIsReadOnlyPropertyId),
+      QUOTE(UIA_RangeValueValuePropertyId),
+      QUOTE(UIA_RangeValueIsReadOnlyPropertyId),
+      QUOTE(UIA_RangeValueMinimumPropertyId),
+      QUOTE(UIA_RangeValueMaximumPropertyId),
+      QUOTE(UIA_RangeValueLargeChangePropertyId),
+      QUOTE(UIA_RangeValueSmallChangePropertyId),
+      QUOTE(UIA_ScrollHorizontalScrollPercentPropertyId),
+      QUOTE(UIA_ScrollHorizontalViewSizePropertyId),
+      QUOTE(UIA_ScrollVerticalScrollPercentPropertyId),
+      QUOTE(UIA_ScrollVerticalViewSizePropertyId),
+      QUOTE(UIA_ScrollHorizontallyScrollablePropertyId),
+      QUOTE(UIA_ScrollVerticallyScrollablePropertyId),
+      QUOTE(UIA_SelectionSelectionPropertyId),
+      QUOTE(UIA_SelectionCanSelectMultiplePropertyId),
+      QUOTE(UIA_SelectionIsSelectionRequiredPropertyId),
+      QUOTE(UIA_GridRowCountPropertyId),
+      QUOTE(UIA_GridColumnCountPropertyId),
+      QUOTE(UIA_GridItemRowPropertyId),
+      QUOTE(UIA_GridItemColumnPropertyId),
+      QUOTE(UIA_GridItemRowSpanPropertyId),
+      QUOTE(UIA_GridItemColumnSpanPropertyId),
+      QUOTE(UIA_GridItemContainingGridPropertyId),
+      QUOTE(UIA_DockDockPositionPropertyId),
+      QUOTE(UIA_ExpandCollapseExpandCollapseStatePropertyId),
+      QUOTE(UIA_MultipleViewCurrentViewPropertyId),
+      QUOTE(UIA_MultipleViewSupportedViewsPropertyId),
+      QUOTE(UIA_WindowCanMaximizePropertyId),
+      QUOTE(UIA_WindowCanMinimizePropertyId),
+      QUOTE(UIA_WindowWindowVisualStatePropertyId),
+      QUOTE(UIA_WindowWindowInteractionStatePropertyId),
+      QUOTE(UIA_WindowIsModalPropertyId),
+      QUOTE(UIA_WindowIsTopmostPropertyId),
+      QUOTE(UIA_SelectionItemIsSelectedPropertyId),
+      QUOTE(UIA_SelectionItemSelectionContainerPropertyId),
+      QUOTE(UIA_TableRowHeadersPropertyId),
+      QUOTE(UIA_TableColumnHeadersPropertyId),
+      QUOTE(UIA_TableRowOrColumnMajorPropertyId),
+      QUOTE(UIA_TableItemRowHeaderItemsPropertyId),
+      QUOTE(UIA_TableItemColumnHeaderItemsPropertyId),
+      QUOTE(UIA_ToggleToggleStatePropertyId),
+      QUOTE(UIA_TransformCanMovePropertyId),
+      QUOTE(UIA_TransformCanResizePropertyId),
+      QUOTE(UIA_TransformCanRotatePropertyId),
+      QUOTE(UIA_IsLegacyIAccessiblePatternAvailablePropertyId),
+      QUOTE(UIA_LegacyIAccessibleChildIdPropertyId),
+      QUOTE(UIA_LegacyIAccessibleNamePropertyId),
+      QUOTE(UIA_LegacyIAccessibleValuePropertyId),
+      QUOTE(UIA_LegacyIAccessibleDescriptionPropertyId),
+      QUOTE(UIA_LegacyIAccessibleRolePropertyId),
+      QUOTE(UIA_LegacyIAccessibleStatePropertyId),
+      QUOTE(UIA_LegacyIAccessibleHelpPropertyId),
+      QUOTE(UIA_LegacyIAccessibleKeyboardShortcutPropertyId),
+      QUOTE(UIA_LegacyIAccessibleSelectionPropertyId),
+      QUOTE(UIA_LegacyIAccessibleDefaultActionPropertyId),
+      QUOTE(UIA_AriaRolePropertyId),
+      QUOTE(UIA_AriaPropertiesPropertyId),
+      QUOTE(UIA_IsDataValidForFormPropertyId),
+      QUOTE(UIA_ControllerForPropertyId),
+      QUOTE(UIA_DescribedByPropertyId),
+      QUOTE(UIA_FlowsToPropertyId),
+      QUOTE(UIA_ProviderDescriptionPropertyId),
+      QUOTE(UIA_IsItemContainerPatternAvailablePropertyId),
+      QUOTE(UIA_IsVirtualizedItemPatternAvailablePropertyId),
+      QUOTE(UIA_IsSynchronizedInputPatternAvailablePropertyId),
+      QUOTE(UIA_OptimizeForVisualContentPropertyId),
+      QUOTE(UIA_IsObjectModelPatternAvailablePropertyId),
+      QUOTE(UIA_AnnotationAnnotationTypeIdPropertyId),
+      QUOTE(UIA_AnnotationAnnotationTypeNamePropertyId),
+      QUOTE(UIA_AnnotationAuthorPropertyId),
+      QUOTE(UIA_AnnotationDateTimePropertyId),
+      QUOTE(UIA_AnnotationTargetPropertyId),
+      QUOTE(UIA_IsAnnotationPatternAvailablePropertyId),
+      QUOTE(UIA_IsTextPattern2AvailablePropertyId),
+      QUOTE(UIA_StylesStyleIdPropertyId),
+      QUOTE(UIA_StylesStyleNamePropertyId),
+      QUOTE(UIA_StylesFillColorPropertyId),
+      QUOTE(UIA_StylesFillPatternStylePropertyId),
+      QUOTE(UIA_StylesShapePropertyId),
+      QUOTE(UIA_StylesFillPatternColorPropertyId),
+      QUOTE(UIA_StylesExtendedPropertiesPropertyId),
+      QUOTE(UIA_IsStylesPatternAvailablePropertyId),
+      QUOTE(UIA_IsSpreadsheetPatternAvailablePropertyId),
+      QUOTE(UIA_SpreadsheetItemFormulaPropertyId),
+      QUOTE(UIA_SpreadsheetItemAnnotationObjectsPropertyId),
+      QUOTE(UIA_SpreadsheetItemAnnotationTypesPropertyId),
+      QUOTE(UIA_IsSpreadsheetItemPatternAvailablePropertyId),
+      QUOTE(UIA_Transform2CanZoomPropertyId),
+      QUOTE(UIA_IsTransformPattern2AvailablePropertyId),
+      QUOTE(UIA_LiveSettingPropertyId),
+      QUOTE(UIA_IsTextChildPatternAvailablePropertyId),
+      QUOTE(UIA_IsDragPatternAvailablePropertyId),
+      QUOTE(UIA_DragIsGrabbedPropertyId),
+      QUOTE(UIA_DragDropEffectPropertyId),
+      QUOTE(UIA_DragDropEffectsPropertyId),
+      QUOTE(UIA_IsDropTargetPatternAvailablePropertyId),
+      QUOTE(UIA_DropTargetDropTargetEffectPropertyId),
+      QUOTE(UIA_DropTargetDropTargetEffectsPropertyId),
+      QUOTE(UIA_DragGrabbedItemsPropertyId),
+      QUOTE(UIA_Transform2ZoomLevelPropertyId),
+      QUOTE(UIA_Transform2ZoomMinimumPropertyId),
+      QUOTE(UIA_Transform2ZoomMaximumPropertyId),
+      QUOTE(UIA_FlowsFromPropertyId),
+      QUOTE(UIA_IsTextEditPatternAvailablePropertyId),
+      QUOTE(UIA_IsPeripheralPropertyId),
+      QUOTE(UIA_IsCustomNavigationPatternAvailablePropertyId),
+      QUOTE(UIA_PositionInSetPropertyId),
+      QUOTE(UIA_SizeOfSetPropertyId),
+      QUOTE(UIA_LevelPropertyId),
+      QUOTE(UIA_AnnotationTypesPropertyId),
+      QUOTE(UIA_AnnotationObjectsPropertyId),
+      QUOTE(UIA_LandmarkTypePropertyId),
+      QUOTE(UIA_LocalizedLandmarkTypePropertyId),
+      QUOTE(UIA_FullDescriptionPropertyId),
+      QUOTE(UIA_FillColorPropertyId),
+      QUOTE(UIA_OutlineColorPropertyId),
+      QUOTE(UIA_FillTypePropertyId),
+      QUOTE(UIA_VisualEffectsPropertyId),
+      QUOTE(UIA_OutlineThicknessPropertyId),
+      QUOTE(UIA_CenterPointPropertyId),
+      QUOTE(UIA_RotationPropertyId),
+      QUOTE(UIA_SizePropertyId),
+      QUOTE(UIA_IsSelectionPattern2AvailablePropertyId),
+      QUOTE(UIA_Selection2FirstSelectedItemPropertyId),
+      QUOTE(UIA_Selection2LastSelectedItemPropertyId),
+      QUOTE(UIA_Selection2CurrentSelectedItemPropertyId),
+      QUOTE(UIA_Selection2ItemCountPropertyId),
+      QUOTE(UIA_HeadingLevelPropertyId),
+  };
+
+  return GetNameForPlatformConstant(id_table, base::size(id_table), identifier);
+}
+
 }  // namespace content
diff --git a/content/browser/accessibility/accessibility_tree_formatter_utils_win.h b/content/browser/accessibility/accessibility_tree_formatter_utils_win.h
index 8312282f..736b3023 100644
--- a/content/browser/accessibility/accessibility_tree_formatter_utils_win.h
+++ b/content/browser/accessibility/accessibility_tree_formatter_utils_win.h
@@ -28,6 +28,8 @@
 // Handles both IAccessible/MSAA events and IAccessible2 events.
 CONTENT_EXPORT base::string16 AccessibilityEventToString(int32_t event_id);
 
+CONTENT_EXPORT base::string16 UiaIdentifierToString(int32_t identifier);
+
 }  // namespace content
 
 #endif  // CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_UTILS_WIN_H_
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc
index a82025b4..f1f4040 100644
--- a/content/browser/accessibility/browser_accessibility_manager.cc
+++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -658,6 +658,15 @@
   delegate_->AccessibilityPerformAction(action_data);
 }
 
+void BrowserAccessibilityManager::SignalEndOfTest() {
+  if (!delegate_)
+    return;
+
+  ui::AXActionData action_data;
+  action_data.action = ax::mojom::Action::kSignalEndOfTest;
+  delegate_->AccessibilityPerformAction(action_data);
+}
+
 void BrowserAccessibilityManager::ScrollToMakeVisible(
     const BrowserAccessibility& node,
     gfx::Rect subfocus) {
diff --git a/content/browser/accessibility/browser_accessibility_manager.h b/content/browser/accessibility/browser_accessibility_manager.h
index 0a2c167..7d1632f 100644
--- a/content/browser/accessibility/browser_accessibility_manager.h
+++ b/content/browser/accessibility/browser_accessibility_manager.h
@@ -230,6 +230,7 @@
   void SetSelection(const ui::AXActionData& action_data);
   void SetSelection(const BrowserAccessibilityRange& range);
   void ShowContextMenu(const BrowserAccessibility& node);
+  void SignalEndOfTest();
 
   // Retrieve the bounds of the parent View in screen coordinates.
   virtual gfx::Rect GetViewBounds();
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc
index 5bd9887..49c3e45 100644
--- a/content/browser/accessibility/browser_accessibility_manager_win.cc
+++ b/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -15,6 +15,7 @@
 #include "content/browser/accessibility/browser_accessibility_win.h"
 #include "content/browser/renderer_host/legacy_render_widget_host_win.h"
 #include "content/common/accessibility_messages.h"
+#include "content/public/common/content_switches.h"
 #include "ui/accessibility/accessibility_switches.h"
 #include "ui/accessibility/ax_role_properties.h"
 #include "ui/accessibility/platform/ax_fragment_root_win.h"
@@ -95,6 +96,21 @@
     BrowserAccessibility* node) {
   BrowserAccessibilityManager::FireBlinkEvent(event_type, node);
   switch (event_type) {
+    case ax::mojom::Event::kEndOfTest: {
+      // Event tests use kEndOfTest as a sentinel to mark the end of the test.
+      Microsoft::WRL::ComPtr<IUIAutomationRegistrar> registrar;
+      CoCreateInstance(CLSID_CUIAutomationRegistrar, NULL, CLSCTX_INPROC_SERVER,
+                       IID_IUIAutomationRegistrar, &registrar);
+      CHECK(registrar.Get());
+      UIAutomationEventInfo custom_event = {kUiaTestCompleteSentinelGuid,
+                                            kUiaTestCompleteSentinel};
+      EVENTID custom_event_id = 0;
+      CHECK(
+          SUCCEEDED(registrar->RegisterEvent(&custom_event, &custom_event_id)));
+
+      FireUiaAccessibilityEvent(custom_event_id, node);
+      break;
+    }
     case ax::mojom::Event::kLocationChanged:
       FireWinAccessibilityEvent(IA2_EVENT_VISIBLE_DATA_CHANGED, node);
       break;
@@ -133,6 +149,7 @@
       break;
     case ui::AXEventGenerator::Event::ALERT:
       FireWinAccessibilityEvent(EVENT_SYSTEM_ALERT, node);
+      FireUiaAccessibilityEvent(UIA_SystemAlertEventId, node);
       break;
     case ui::AXEventGenerator::Event::CHILDREN_CHANGED:
       FireWinAccessibilityEvent(EVENT_OBJECT_REORDER, node);
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.h b/content/browser/accessibility/browser_accessibility_manager_win.h
index a298243..95575e41 100644
--- a/content/browser/accessibility/browser_accessibility_manager_win.h
+++ b/content/browser/accessibility/browser_accessibility_manager_win.h
@@ -16,6 +16,14 @@
 namespace content {
 class BrowserAccessibilityWin;
 
+// {3761326A-34B2-465A-835D-7A3D8F4EFB92}
+static const GUID kUiaTestCompleteSentinelGuid = {
+    0x3761326a,
+    0x34b2,
+    0x465a,
+    {0x83, 0x5d, 0x7a, 0x3d, 0x8f, 0x4e, 0xfb, 0x92}};
+static const wchar_t kUiaTestCompleteSentinel[] = L"kUiaTestCompleteSentinel";
+
 // Manages a tree of BrowserAccessibilityWin objects.
 class CONTENT_EXPORT BrowserAccessibilityManagerWin
     : public BrowserAccessibilityManager {
diff --git a/content/browser/accessibility/dump_accessibility_browsertest_base.cc b/content/browser/accessibility/dump_accessibility_browsertest_base.cc
index 2591ff8..7aeaf82 100644
--- a/content/browser/accessibility/dump_accessibility_browsertest_base.cc
+++ b/content/browser/accessibility/dump_accessibility_browsertest_base.cc
@@ -98,6 +98,18 @@
   ASSERT_TRUE(embedded_test_server()->Start());
 }
 
+void DumpAccessibilityTestBase::SetUp() {
+  // TODO(dmazzoni): DumpAccessibilityTree expectations are based on the
+  // assumption that the accessibility labels feature is off. (There are
+  // also several tests that explicitly enable the feature.) It'd be better
+  // if DumpAccessibilityTree tests assumed that the feature is on by
+  // default instead.  http://crbug.com/940330
+  scoped_feature_list_.InitAndDisableFeature(
+      features::kExperimentalAccessibilityLabels);
+
+  ContentBrowserTest::SetUp();
+}
+
 base::string16
 DumpAccessibilityTestBase::DumpUnfilteredAccessibilityTreeAsString() {
   std::unique_ptr<AccessibilityTreeFormatter> formatter(formatter_factory_());
diff --git a/content/browser/accessibility/dump_accessibility_browsertest_base.h b/content/browser/accessibility/dump_accessibility_browsertest_base.h
index 864e4d2..135fc57 100644
--- a/content/browser/accessibility/dump_accessibility_browsertest_base.h
+++ b/content/browser/accessibility/dump_accessibility_browsertest_base.h
@@ -10,6 +10,7 @@
 
 #include "base/debug/leak_annotations.h"
 #include "base/strings/string16.h"
+#include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "content/browser/accessibility/accessibility_event_recorder.h"
 #include "content/browser/accessibility/accessibility_tree_formatter.h"
@@ -39,6 +40,7 @@
  protected:
   void SetUpCommandLine(base::CommandLine* command_line) override;
   void SetUpOnMainThread() override;
+  void SetUp() override;
 
   //
   // For subclasses to override:
@@ -120,6 +122,8 @@
   // Whether we should enable accessibility after navigating to the page,
   // otherwise we enable it first.
   bool enable_accessibility_after_navigating_;
+
+  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
 }  // namespace content
diff --git a/content/browser/accessibility/dump_accessibility_events_browsertest.cc b/content/browser/accessibility/dump_accessibility_events_browsertest.cc
index 32e9aa81..6e16a02 100644
--- a/content/browser/accessibility/dump_accessibility_events_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_events_browsertest.cc
@@ -133,13 +133,14 @@
 
   // More than one accessibility event could have been generated.
   // To make sure we've received all accessibility events, add a
-  // sentinel by calling AccessibilityHitTest and waiting for a HOVER
+  // sentinel by calling SignalEndOfTest and waiting for a kEndOfTest
   // event in response.
   waiter.reset(new AccessibilityNotificationWaiter(
-      shell()->web_contents(), ui::kAXModeComplete, ax::mojom::Event::kHover));
+      shell()->web_contents(), ui::kAXModeComplete,
+      ax::mojom::Event::kEndOfTest));
   BrowserAccessibilityManager* manager =
       web_contents->GetRootBrowserAccessibilityManager();
-  manager->HitTest(gfx::Point(0, 0));
+  manager->SignalEndOfTest();
   waiter->WaitForNotification();
 
   // Save a copy of the final accessibility tree (as a text dump); we'll
@@ -148,6 +149,7 @@
 
   // Dump the event logs, running them through any filters specified
   // in the HTML file.
+  event_recorder->FlushAsyncEvents();
   std::vector<std::string> event_logs = event_recorder->event_logs();
   std::vector<std::string> result;
   for (size_t i = 0; i < event_logs.size(); ++i) {
diff --git a/content/browser/frame_host/cross_process_frame_connector.cc b/content/browser/frame_host/cross_process_frame_connector.cc
index 3d6b0e52..ddffe8c11 100644
--- a/content/browser/frame_host/cross_process_frame_connector.cc
+++ b/content/browser/frame_host/cross_process_frame_connector.cc
@@ -365,13 +365,13 @@
 void CrossProcessFrameConnector::OnUpdateViewportIntersection(
     const gfx::Rect& viewport_intersection,
     const gfx::Rect& compositor_visible_rect,
-    bool occluded_or_obscured) {
+    blink::FrameOcclusionState occlusion_state) {
   viewport_intersection_rect_ = viewport_intersection;
   compositor_visible_rect_ = compositor_visible_rect;
-  occluded_or_obscured_ = occluded_or_obscured;
+  occlusion_state_ = occlusion_state;
   if (view_)
-    view_->UpdateViewportIntersection(
-        viewport_intersection, compositor_visible_rect, occluded_or_obscured);
+    view_->UpdateViewportIntersection(viewport_intersection,
+                                      compositor_visible_rect, occlusion_state);
 
   if (IsVisible()) {
     // Record metrics if a crashed subframe became visible as a result of this
diff --git a/content/browser/frame_host/cross_process_frame_connector.h b/content/browser/frame_host/cross_process_frame_connector.h
index 5b04cf9f..e1f4c6f 100644
--- a/content/browser/frame_host/cross_process_frame_connector.h
+++ b/content/browser/frame_host/cross_process_frame_connector.h
@@ -182,7 +182,7 @@
       const FrameVisualProperties& visual_properties);
   void OnUpdateViewportIntersection(const gfx::Rect& viewport_intersection,
                                     const gfx::Rect& compositor_visible_rect,
-                                    bool occluded_or_obscured);
+                                    blink::FrameOcclusionState occlusion_state);
   void OnVisibilityChanged(blink::mojom::FrameVisibility visibility);
   void OnSetIsInert(bool);
   void OnSetInheritedEffectiveTouchAction(cc::TouchAction);
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index 773d783..584a1aa5 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -1415,6 +1415,8 @@
                         OnUpdateUserActivationState)
     IPC_MESSAGE_HANDLER(FrameHostMsg_SetHasReceivedUserGestureBeforeNavigation,
                         OnSetHasReceivedUserGestureBeforeNavigation)
+    IPC_MESSAGE_HANDLER(FrameHostMsg_SetNeedsOcclusionTracking,
+                        OnSetNeedsOcclusionTracking);
     IPC_MESSAGE_HANDLER(FrameHostMsg_ScrollRectToVisibleInParentFrame,
                         OnScrollRectToVisibleInParentFrame)
     IPC_MESSAGE_HANDLER(FrameHostMsg_BubbleLogicalScrollInParentFrame,
@@ -3462,6 +3464,19 @@
   frame_tree_node_->OnSetHasReceivedUserGestureBeforeNavigation(value);
 }
 
+void RenderFrameHostImpl::OnSetNeedsOcclusionTracking(bool needs_tracking) {
+  RenderFrameProxyHost* proxy =
+      frame_tree_node()->render_manager()->GetProxyToParent();
+  if (!proxy) {
+    bad_message::ReceivedBadMessage(GetProcess(),
+                                    bad_message::RFH_NO_PROXY_TO_PARENT);
+    return;
+  }
+
+  proxy->Send(new FrameMsg_SetNeedsOcclusionTracking(proxy->GetRoutingID(),
+                                                     needs_tracking));
+}
+
 void RenderFrameHostImpl::OnScrollRectToVisibleInParentFrame(
     const gfx::Rect& rect_to_scroll,
     const blink::WebScrollIntoViewParams& params) {
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h
index 57f3c7e..df10f21 100644
--- a/content/browser/frame_host/render_frame_host_impl.h
+++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -1097,6 +1097,7 @@
                             const gfx::Rect& bounds_in_frame_widget);
   void OnUpdateUserActivationState(blink::UserActivationUpdateType update_type);
   void OnSetHasReceivedUserGestureBeforeNavigation(bool value);
+  void OnSetNeedsOcclusionTracking(bool needs_tracking);
   void OnScrollRectToVisibleInParentFrame(
       const gfx::Rect& rect_to_scroll,
       const blink::WebScrollIntoViewParams& params);
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index dd566a2..6a28827 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -624,6 +624,12 @@
                                               std::move(interface_pipe));
 }
 
+void GpuProcessHost::RunService(
+    const std::string& service_name,
+    mojo::PendingReceiver<service_manager::mojom::Service> receiver) {
+  process_->GetHost()->RunService(service_name, std::move(receiver));
+}
+
 #if defined(USE_OZONE)
 void GpuProcessHost::TerminateGpuProcess(const std::string& message) {
   // At the moment, this path is only used by Ozone/Wayland. Once others start
diff --git a/content/browser/gpu/gpu_process_host.h b/content/browser/gpu/gpu_process_host.h
index d9b87d3..1eba567 100644
--- a/content/browser/gpu/gpu_process_host.h
+++ b/content/browser/gpu/gpu_process_host.h
@@ -159,6 +159,9 @@
       override;
   void BindInterface(const std::string& interface_name,
                      mojo::ScopedMessagePipeHandle interface_pipe) override;
+  void RunService(
+      const std::string& service_name,
+      mojo::PendingReceiver<service_manager::mojom::Service> receiver) override;
 #if defined(USE_OZONE)
   void TerminateGpuProcess(const std::string& message) override;
   void SendGpuProcessMessage(IPC::Message* message) override;
diff --git a/content/browser/navigation_browsertest.cc b/content/browser/navigation_browsertest.cc
index cec873c..28ee776 100644
--- a/content/browser/navigation_browsertest.cc
+++ b/content/browser/navigation_browsertest.cc
@@ -705,7 +705,7 @@
   std::string script = base::StringPrintf(
       "var xhr = new XMLHttpRequest()\n"
       "xhr.open('GET', '%s', false);\n"
-      "xhr.send();\n"
+      "try { xhr.send(); } catch (e) {}\n"
       "window.domAutomationController.send(xhr.responseText);",
       file_url.spec().c_str());
   std::string result;
diff --git a/content/browser/portal/portal.cc b/content/browser/portal/portal.cc
index c2f18623..2fc24bd 100644
--- a/content/browser/portal/portal.cc
+++ b/content/browser/portal/portal.cc
@@ -81,6 +81,7 @@
   std::unique_ptr<WebContents> portal_contents = WebContents::Create(params);
   portal_contents_impl_ = static_cast<WebContentsImpl*>(portal_contents.get());
   portal_contents_impl_->set_portal(this);
+  portal_contents_impl_->SetDelegate(this);
 
   outer_contents_impl->AttachInnerWebContents(std::move(portal_contents),
                                               outer_node->current_frame_host());
@@ -92,8 +93,7 @@
   proxy_host->set_render_frame_proxy_created(true);
   portal_contents_impl_->ReattachToOuterWebContentsFrame();
 
-  outer_contents_impl->GetDelegate()->PortalWebContentsCreated(
-      portal_contents_impl_);
+  PortalWebContentsCreated(portal_contents_impl_);
 
   return proxy_host;
 }
@@ -132,6 +132,13 @@
   binding_->Close();  // Also deletes |this|.
 }
 
+void Portal::PortalWebContentsCreated(WebContents* portal_web_contents) {
+  WebContentsImpl* outer_contents = static_cast<WebContentsImpl*>(
+      WebContents::FromRenderFrameHost(owner_render_frame_host_));
+  DCHECK(outer_contents->GetDelegate());
+  outer_contents->GetDelegate()->PortalWebContentsCreated(portal_web_contents);
+}
+
 WebContentsImpl* Portal::GetPortalContents() {
   return portal_contents_impl_;
 }
diff --git a/content/browser/portal/portal.h b/content/browser/portal/portal.h
index c3bff09..34e8ae6b 100644
--- a/content/browser/portal/portal.h
+++ b/content/browser/portal/portal.h
@@ -9,6 +9,7 @@
 
 #include "content/common/content_export.h"
 #include "content/common/frame.mojom.h"
+#include "content/public/browser/web_contents_delegate.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "mojo/public/cpp/bindings/strong_binding.h"
 #include "third_party/blink/public/mojom/portal/portal.mojom.h"
@@ -27,7 +28,8 @@
 // The Portal is owned by its mojo binding, so it is kept alive as long as the
 // other end of the pipe (typically in the renderer) exists.
 class CONTENT_EXPORT Portal : public blink::mojom::Portal,
-                              public WebContentsObserver {
+                              public WebContentsObserver,
+                              public WebContentsDelegate {
  public:
   ~Portal() override;
 
@@ -55,6 +57,9 @@
   void RenderFrameDeleted(RenderFrameHost* render_frame_host) override;
   void WebContentsDestroyed() override;
 
+  // WebContentsDelegate overrides.
+  void PortalWebContentsCreated(WebContents* portal_web_contents) override;
+
   // Returns the token which uniquely identifies this Portal.
   const base::UnguessableToken& portal_token() const { return portal_token_; }
 
diff --git a/content/browser/renderer_host/frame_connector_delegate.h b/content/browser/renderer_host/frame_connector_delegate.h
index a7815b1..5f494de 100644
--- a/content/browser/renderer_host/frame_connector_delegate.h
+++ b/content/browser/renderer_host/frame_connector_delegate.h
@@ -14,6 +14,7 @@
 #include "content/common/content_export.h"
 #include "content/public/common/input_event_ack_state.h"
 #include "content/public/common/screen_info.h"
+#include "third_party/blink/public/common/frame/occlusion_state.h"
 #include "ui/gfx/geometry/rect.h"
 
 #if defined(USE_AURA)
@@ -187,7 +188,9 @@
 
   // Returns whether the current view may be occluded or distorted (e.g, with
   // CSS opacity or transform) in the parent view.
-  bool occluded_or_obscured() const { return occluded_or_obscured_; }
+  blink::FrameOcclusionState occlusion_state() const {
+    return occlusion_state_;
+  }
 
   // Returns the viz::LocalSurfaceIdAllocation propagated from the parent to be
   // used by this child frame.
@@ -269,10 +272,8 @@
   // This is here rather than in the implementation class so that
   // ViewportIntersection() can return a reference.
   gfx::Rect viewport_intersection_rect_;
-
   gfx::Rect compositor_visible_rect_;
-
-  bool occluded_or_obscured_ = false;
+  blink::FrameOcclusionState occlusion_state_ = blink::kUnknownOcclusionState;
 
   ScreenInfo screen_info_;
   gfx::Size local_frame_size_in_dip_;
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame.cc b/content/browser/renderer_host/render_widget_host_view_child_frame.cc
index 87b6d27..88681456 100644
--- a/content/browser/renderer_host/render_widget_host_view_child_frame.cc
+++ b/content/browser/renderer_host/render_widget_host_view_child_frame.cc
@@ -493,12 +493,12 @@
 void RenderWidgetHostViewChildFrame::UpdateViewportIntersection(
     const gfx::Rect& viewport_intersection,
     const gfx::Rect& compositor_visible_rect,
-    bool occluded_or_obscured) {
+    blink::FrameOcclusionState occlusion_state) {
   if (host()) {
     host()->SetIntersectsViewport(!viewport_intersection.IsEmpty());
     host()->Send(new WidgetMsg_SetViewportIntersection(
         host()->GetRoutingID(), viewport_intersection, compositor_visible_rect,
-        occluded_or_obscured));
+        occlusion_state));
   }
 }
 
@@ -822,7 +822,7 @@
   if (frame_connector_) {
     UpdateViewportIntersection(frame_connector_->viewport_intersection_rect(),
                                frame_connector_->compositor_visible_rect(),
-                               frame_connector_->occluded_or_obscured());
+                               frame_connector_->occlusion_state());
     SetIsInert();
     UpdateInheritedEffectiveTouchAction();
     UpdateRenderThrottlingStatus();
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame.h b/content/browser/renderer_host/render_widget_host_view_child_frame.h
index cf0e094..677115e 100644
--- a/content/browser/renderer_host/render_widget_host_view_child_frame.h
+++ b/content/browser/renderer_host/render_widget_host_view_child_frame.h
@@ -28,6 +28,7 @@
 #include "content/public/browser/touch_selection_controller_client_manager.h"
 #include "content/public/common/input_event_ack_state.h"
 #include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom.h"
+#include "third_party/blink/public/common/frame/occlusion_state.h"
 #include "third_party/blink/public/platform/web_intrinsic_sizing_info.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/native_widget_types.h"
@@ -223,7 +224,7 @@
 
   void UpdateViewportIntersection(const gfx::Rect& viewport_intersection,
                                   const gfx::Rect& compositor_visible_rect,
-                                  bool occluded_or_obscured);
+                                  blink::FrameOcclusionState occlusion_state);
 
   // TODO(sunxd): Rename SetIsInert to UpdateIsInert.
   void SetIsInert();
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc b/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc
index bdb8cf2..3ce79e42 100644
--- a/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <stdint.h>
 
+#include <tuple>
 #include <utility>
 
 #include "base/macros.h"
@@ -39,6 +40,7 @@
 #include "content/test/mock_widget_impl.h"
 #include "content/test/test_render_view_host.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/frame/occlusion_state.h"
 #include "ui/base/ui_base_features.h"
 #include "ui/compositor/compositor.h"
 
@@ -246,7 +248,7 @@
       process->sink().GetUniqueMessageMatching(
           WidgetMsg_SetViewportIntersection::ID);
   ASSERT_TRUE(intersection_update);
-  std::tuple<gfx::Rect, gfx::Rect, bool> sent_rects;
+  std::tuple<gfx::Rect, gfx::Rect, blink::FrameOcclusionState> sent_rects;
 
   WidgetMsg_SetViewportIntersection::Read(intersection_update, &sent_rects);
   EXPECT_EQ(intersection_rect, std::get<0>(sent_rects));
diff --git a/content/browser/service_manager/service_manager_context.cc b/content/browser/service_manager/service_manager_context.cc
index d0e0368..4b51556 100644
--- a/content/browser/service_manager/service_manager_context.cc
+++ b/content/browser/service_manager/service_manager_context.cc
@@ -181,15 +181,9 @@
     process_host = impl;
   }
 
-  service_manager::mojom::ServiceFactoryPtr service_factory;
-  BindInterface(process_host, mojo::MakeRequest(&service_factory));
-
-  // CreateService expects a non-null PIDReceiverPtr, but we don't actually
-  // expect the utility process to report anything on it. Send a dead-end proxy.
-  service_manager::mojom::PIDReceiverPtr dead_pid_receiver;
-  mojo::MakeRequest(&dead_pid_receiver);
-  service_factory->CreateService(std::move(request), service_name,
-                                 std::move(dead_pid_receiver));
+  process_host->RunService(
+      service_name, mojo::PendingReceiver<service_manager::mojom::Service>(
+                        request.PassMessagePipe()));
 }
 
 // Determine a sandbox type for a service and launch a process for it.
@@ -206,8 +200,7 @@
                      std::move(request), std::move(pid_receiver)));
 }
 
-// Request service_manager::mojom::ServiceFactory from GPU process host. Must be
-// called on IO thread.
+// Send a RunService request through the GpuProcessHost.
 void StartServiceInGpuProcess(
     const std::string& service_name,
     service_manager::mojom::ServiceRequest request,
@@ -218,14 +211,13 @@
     return;
   }
 
-  service_manager::mojom::ServiceFactoryPtr service_factory;
   // TODO(xhwang): It's possible that |process_host| is non-null, but the actual
   // process is dead. In that case, |request| will be dropped and application
   // load requests through ServiceFactory will also fail. Make sure we handle
   // these cases correctly.
-  BindInterfaceInGpuProcess(mojo::MakeRequest(&service_factory));
-  service_factory->CreateService(std::move(request), service_name,
-                                 std::move(pid_receiver));
+  process_host->gpu_host()->RunService(
+      service_name, mojo::PendingReceiver<service_manager::mojom::Service>(
+                        request.PassMessagePipe()));
 }
 
 class NullServiceProcessLauncherFactory
diff --git a/content/browser/service_worker/service_worker_data_pipe_reader.cc b/content/browser/service_worker/service_worker_data_pipe_reader.cc
index 7f6c0db..308a82b 100644
--- a/content/browser/service_worker/service_worker_data_pipe_reader.cc
+++ b/content/browser/service_worker/service_worker_data_pipe_reader.cc
@@ -7,17 +7,14 @@
 #include "base/bind.h"
 #include "base/trace_event/trace_event.h"
 #include "content/browser/service_worker/service_worker_url_request_job.h"
-#include "content/browser/service_worker/service_worker_version.h"
 #include "net/base/io_buffer.h"
 
 namespace content {
 
 ServiceWorkerDataPipeReader::ServiceWorkerDataPipeReader(
     ServiceWorkerURLRequestJob* owner,
-    scoped_refptr<ServiceWorkerVersion> streaming_version,
     blink::mojom::ServiceWorkerStreamHandlePtr stream_handle)
     : owner_(owner),
-      streaming_version_(streaming_version),
       stream_pending_buffer_size_(0),
       handle_watcher_(FROM_HERE,
                       mojo::SimpleWatcher::ArmingPolicy::MANUAL,
@@ -27,16 +24,11 @@
       producer_state_(State::kStreaming) {
   TRACE_EVENT_ASYNC_BEGIN1("ServiceWorker", "ServiceWorkerDataPipeReader", this,
                            "Url", owner->request()->url().spec());
-  streaming_version_->OnStreamResponseStarted();
   binding_.set_connection_error_handler(base::BindOnce(
       &ServiceWorkerDataPipeReader::OnAborted, base::Unretained(this)));
 }
 
 ServiceWorkerDataPipeReader::~ServiceWorkerDataPipeReader() {
-  DCHECK(streaming_version_);
-  streaming_version_->OnStreamResponseFinished();
-  streaming_version_ = nullptr;
-
   TRACE_EVENT_ASYNC_END0("ServiceWorker", "ServiceWorkerDataPipeReader", this);
 }
 
diff --git a/content/browser/service_worker/service_worker_data_pipe_reader.h b/content/browser/service_worker/service_worker_data_pipe_reader.h
index 081d362..c0272d2 100644
--- a/content/browser/service_worker/service_worker_data_pipe_reader.h
+++ b/content/browser/service_worker/service_worker_data_pipe_reader.h
@@ -19,7 +19,6 @@
 namespace content {
 
 class ServiceWorkerURLRequestJob;
-class ServiceWorkerVersion;
 
 // Reads a stream response for ServiceWorkerURLRequestJob passed through
 // Mojo's data pipe. Owned by ServiceWorkerURLRequestJob.
@@ -28,7 +27,6 @@
  public:
   ServiceWorkerDataPipeReader(
       ServiceWorkerURLRequestJob* owner,
-      scoped_refptr<ServiceWorkerVersion> streaming_version,
       blink::mojom::ServiceWorkerStreamHandlePtr stream_handle);
   ~ServiceWorkerDataPipeReader() override;
 
@@ -57,7 +55,6 @@
   State state();
 
   ServiceWorkerURLRequestJob* owner_;
-  scoped_refptr<ServiceWorkerVersion> streaming_version_;
   scoped_refptr<net::IOBuffer> stream_pending_buffer_;
   int stream_pending_buffer_size_;
   mojo::SimpleWatcher handle_watcher_;
diff --git a/content/browser/service_worker/service_worker_data_pipe_reader_unittest.cc b/content/browser/service_worker/service_worker_data_pipe_reader_unittest.cc
index f69386b66..580c48e 100644
--- a/content/browser/service_worker/service_worker_data_pipe_reader_unittest.cc
+++ b/content/browser/service_worker/service_worker_data_pipe_reader_unittest.cc
@@ -4,19 +4,17 @@
 
 #include "content/browser/service_worker/service_worker_data_pipe_reader.h"
 
+#include <utility>
 #include "base/run_loop.h"
 #include "content/browser/service_worker/embedded_worker_test_helper.h"
 #include "content/browser/service_worker/service_worker_context_core.h"
 #include "content/browser/service_worker/service_worker_context_wrapper.h"
-#include "content/browser/service_worker/service_worker_registration.h"
 #include "content/browser/service_worker/service_worker_url_request_job.h"
-#include "content/browser/service_worker/service_worker_version.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "net/base/io_buffer.h"
 #include "services/network/public/cpp/resource_request_body.h"
 #include "services/network/public/mojom/request_context_frame_type.mojom.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
 
 namespace content {
 
@@ -81,20 +79,6 @@
     helper_ = std::make_unique<EmbeddedWorkerTestHelper>(base::FilePath());
     mock_url_request_job_ =
         std::make_unique<MockServiceWorkerURLRequestJob>(this);
-    blink::mojom::ServiceWorkerRegistrationOptions options;
-    options.scope = GURL("https://example.com/");
-    registration_ = new ServiceWorkerRegistration(
-        options, 1L, helper_->context()->AsWeakPtr());
-    version_ = new ServiceWorkerVersion(
-        registration_.get(), GURL("https://example.com/service_worker.js"),
-        blink::mojom::ScriptType::kClassic, 1L,
-        helper_->context()->AsWeakPtr());
-    std::vector<ServiceWorkerDatabase::ResourceRecord> records;
-    records.push_back(
-        ServiceWorkerDatabase::ResourceRecord(10, version_->script_url(), 100));
-    version_->script_cache_map()->SetResources(records);
-    version_->set_fetch_handler_existence(
-        ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
   }
 
   std::unique_ptr<ServiceWorkerDataPipeReader> CreateTargetDataPipeReader(
@@ -105,7 +89,7 @@
     stream_handle->stream = std::move(data_pipe->consumer_handle);
     stream_handle->callback_request = mojo::MakeRequest(stream_callback);
     return std::make_unique<ServiceWorkerDataPipeReader>(
-        mock_url_request_job_.get(), version_, std::move(stream_handle));
+        mock_url_request_job_.get(), std::move(stream_handle));
   }
 
   // Implements ServiceWorkerURLRequestJob::Delegate.
@@ -133,8 +117,6 @@
 
   std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
   std::unique_ptr<MockServiceWorkerURLRequestJob> mock_url_request_job_;
-  scoped_refptr<ServiceWorkerRegistration> registration_;
-  scoped_refptr<ServiceWorkerVersion> version_;
 };
 
 class ServiceWorkerDataPipeReaderTestP
diff --git a/content/browser/service_worker/service_worker_navigation_loader.cc b/content/browser/service_worker/service_worker_navigation_loader.cc
index a505f5d34..6b4d11d 100644
--- a/content/browser/service_worker/service_worker_navigation_loader.cc
+++ b/content/browser/service_worker/service_worker_navigation_loader.cc
@@ -63,16 +63,12 @@
  public:
   StreamWaiter(
       ServiceWorkerNavigationLoader* owner,
-      scoped_refptr<ServiceWorkerVersion> streaming_version,
       blink::mojom::ServiceWorkerStreamCallbackRequest callback_request)
       : owner_(owner),
-        streaming_version_(streaming_version),
         binding_(this, std::move(callback_request)) {
-    streaming_version_->OnStreamResponseStarted();
     binding_.set_connection_error_handler(
         base::BindOnce(&StreamWaiter::OnAborted, base::Unretained(this)));
   }
-  ~StreamWaiter() override { streaming_version_->OnStreamResponseFinished(); }
 
   // Implements mojom::ServiceWorkerStreamCallback.
   void OnCompleted() override {
@@ -86,7 +82,6 @@
 
  private:
   ServiceWorkerNavigationLoader* owner_;
-  scoped_refptr<ServiceWorkerVersion> streaming_version_;
   mojo::Binding<blink::mojom::ServiceWorkerStreamCallback> binding_;
 
   DISALLOW_COPY_AND_ASSIGN(StreamWaiter);
@@ -463,7 +458,7 @@
                            TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
                            "result", "stream response");
     stream_waiter_ = std::make_unique<StreamWaiter>(
-        this, std::move(version), std::move(body_as_stream->callback_request));
+        this, std::move(body_as_stream->callback_request));
     CommitResponseBody(std::move(body_as_stream->stream));
     // StreamWaiter will call CommitCompleted() when done.
     return;
diff --git a/content/browser/service_worker/service_worker_navigation_loader_unittest.cc b/content/browser/service_worker/service_worker_navigation_loader_unittest.cc
index 04ce241..0747983f 100644
--- a/content/browser/service_worker/service_worker_navigation_loader_unittest.cc
+++ b/content/browser/service_worker/service_worker_navigation_loader_unittest.cc
@@ -791,10 +791,8 @@
   ASSERT_EQ(MOJO_RESULT_OK, mojo_result);
   EXPECT_EQ(sizeof(kResponseBody) - 1, written_bytes);
   EXPECT_TRUE(data_pipe.producer_handle.is_valid());
-  EXPECT_TRUE(HasWorkInBrowser(version_.get()));
   loader_ptr_.reset();
   base::RunLoop().RunUntilIdle();
-  EXPECT_FALSE(HasWorkInBrowser(version_.get()));
 
   // Although ServiceWorkerNavigationLoader resets its URLLoaderClient pointer
   // on connection error, the URLLoaderClient still exists. In this test, it is
diff --git a/content/browser/service_worker/service_worker_url_request_job.cc b/content/browser/service_worker/service_worker_url_request_job.cc
index 31f10bda..395bea7 100644
--- a/content/browser/service_worker/service_worker_url_request_job.cc
+++ b/content/browser/service_worker/service_worker_url_request_job.cc
@@ -601,8 +601,8 @@
   if (!body_as_stream.is_null()) {
     SetResponseBodyType(STREAM);
     SetResponse(std::move(response));
-    data_pipe_reader_.reset(new ServiceWorkerDataPipeReader(
-        this, version, std::move(body_as_stream)));
+    data_pipe_reader_.reset(
+        new ServiceWorkerDataPipeReader(this, std::move(body_as_stream)));
     data_pipe_reader_->Start();
     return;
   }
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
index c6d61cc8..e723d0e9 100644
--- a/content/browser/service_worker/service_worker_version.cc
+++ b/content/browser/service_worker/service_worker_version.cc
@@ -59,9 +59,6 @@
 // Timeout for a request to be handled.
 constexpr base::TimeDelta kRequestTimeout = base::TimeDelta::FromMinutes(5);
 
-// Time to wait until stopping an idle worker.
-constexpr base::TimeDelta kIdleWorkerTimeout = base::TimeDelta::FromSeconds(30);
-
 // Default delay for scheduled update.
 constexpr base::TimeDelta kUpdateDelay = base::TimeDelta::FromSeconds(1);
 
@@ -643,7 +640,6 @@
       request->event_type, tick_clock_->NowTicks() - request->start_time_ticks,
       was_handled);
 
-  RestartTick(&idle_time_);
   TRACE_EVENT_ASYNC_END1("ServiceWorker", "ServiceWorkerVersion::Request",
                          request, "Handled", was_handled);
   request_timeouts_.erase(request->timeout_iter);
@@ -707,11 +703,7 @@
   DCHECK(!base::ContainsKey(controllee_map_, uuid));
 
   controllee_map_[uuid] = provider_host;
-
   embedded_worker_->UpdateForegroundPriority();
-
-  // Keep the worker alive a bit longer right after a new controllee is added.
-  RestartTick(&idle_time_);
   ClearTick(&no_controllees_time_);
 
   ServiceWorkerRegistration* registration =
@@ -746,20 +738,6 @@
                                 weak_factory_.GetWeakPtr(), client_uuid));
 }
 
-void ServiceWorkerVersion::OnStreamResponseStarted() {
-  CHECK_LT(inflight_stream_response_count_, std::numeric_limits<int>::max());
-  inflight_stream_response_count_++;
-}
-
-void ServiceWorkerVersion::OnStreamResponseFinished() {
-  DCHECK_GT(inflight_stream_response_count_, 0);
-  inflight_stream_response_count_--;
-  if (!blink::ServiceWorkerUtils::IsServicificationEnabled() &&
-      !HasWorkInBrowser()) {
-    OnNoWorkInBrowser();
-  }
-}
-
 void ServiceWorkerVersion::AddObserver(Observer* observer) {
   observers_.AddObserver(observer);
 }
@@ -980,7 +958,6 @@
 void ServiceWorkerVersion::OnStarted(
     blink::mojom::ServiceWorkerStartStatus start_status) {
   DCHECK_EQ(EmbeddedWorkerStatus::RUNNING, running_status());
-  RestartTick(&idle_time_);
 
   // TODO(falken): This maps kAbruptCompletion to kErrorScriptEvaluated, which
   // most start callbacks will consider to be a failure. But the worker thread
@@ -1438,8 +1415,7 @@
 }
 
 bool ServiceWorkerVersion::HasWorkInBrowser() const {
-  return !inflight_requests_.IsEmpty() || inflight_stream_response_count_ > 0 ||
-         !start_callbacks_.empty();
+  return !inflight_requests_.IsEmpty() || !start_callbacks_.empty();
 }
 
 void ServiceWorkerVersion::OnSimpleEventFinished(
@@ -1688,9 +1664,6 @@
     skip_recording_startup_time_ = false;
   }
 
-  // The worker is starting up and not yet idle.
-  ClearTick(&idle_time_);
-
   // Ping will be activated in OnScriptEvaluationStart.
   ping_controller_.Deactivate();
 
@@ -1700,7 +1673,6 @@
 
 void ServiceWorkerVersion::StopTimeoutTimer() {
   timeout_timer_.Stop();
-  ClearTick(&idle_time_);
 
   // Trigger update if worker is stale.
   if (!in_dtor_ && !stale_time_.is_null()) {
@@ -1802,16 +1774,6 @@
   if (running_status() == EmbeddedWorkerStatus::STOPPING)
     return;
 
-  // The worker has been idle for longer than a certain period.
-  // S13nServiceWorker: The idle timer is implemented on the renderer, so we can
-  // skip this check.
-  if (!blink::ServiceWorkerUtils::IsServicificationEnabled() &&
-      GetTickDuration(idle_time_) > kIdleWorkerTimeout) {
-    if (HasNoWork())
-      embedded_worker_->StopIfNotAttachedToDevTools();
-    return;
-  }
-
   // Check ping status.
   ping_controller_.CheckPingStatus();
 }
@@ -2076,13 +2038,6 @@
 
 void ServiceWorkerVersion::OnNoWorkInBrowser() {
   DCHECK(!HasWorkInBrowser());
-  if (!blink::ServiceWorkerUtils::IsServicificationEnabled()) {
-    for (auto& observer : observers_)
-      observer.OnNoWork(this);
-    return;
-  }
-
-  DCHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
   if (worker_is_idle_on_renderer_) {
     for (auto& observer : observers_)
       observer.OnNoWork(this);
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h
index cd292a7..a9961fa 100644
--- a/content/browser/service_worker/service_worker_version.h
+++ b/content/browser/service_worker/service_worker_version.h
@@ -383,16 +383,6 @@
 
   base::WeakPtr<ServiceWorkerContextCore> context() const { return context_; }
 
-  // Called when the browser process starts/finishes reading a fetch event
-  // response via Mojo data pipe from the service worker.
-  // Non-S13nServiceWorker: We try to not stop the service worker while there is
-  // an ongoing response.
-  // S13nServiceWorker: Renderer's idle timer recognizes stream responses, so we
-  // rely on it instead of keeping track of stream responses in the browser
-  // process.
-  void OnStreamResponseStarted();
-  void OnStreamResponseFinished();
-
   // Adds and removes Observers.
   void AddObserver(Observer* observer);
   void RemoveObserver(Observer* observer);
@@ -914,8 +904,6 @@
 
   // Starts running in StartWorker and continues until the worker is stopped.
   base::RepeatingTimer timeout_timer_;
-  // Holds the time the worker last started being considered idle.
-  base::TimeTicks idle_time_;
   // Holds the time that the outstanding StartWorker() request started.
   base::TimeTicks start_time_;
   // Holds the time the worker entered STOPPING status. This is also used as a
diff --git a/content/browser/service_worker/service_worker_version_unittest.cc b/content/browser/service_worker/service_worker_version_unittest.cc
index e2537e9..a64b808b 100644
--- a/content/browser/service_worker/service_worker_version_unittest.cc
+++ b/content/browser/service_worker/service_worker_version_unittest.cc
@@ -483,60 +483,6 @@
   EXPECT_FALSE(host->controller());
 }
 
-TEST_F(ServiceWorkerVersionTest, IdleTimeout) {
-  // Used to reliably test when the idle time gets reset regardless of clock
-  // granularity.
-  const base::TimeDelta kOneSecond = base::TimeDelta::FromSeconds(1);
-
-  // Verify the timer is not running when version initializes its status.
-  version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
-  EXPECT_FALSE(version_->timeout_timer_.IsRunning());
-
-  // Verify the timer is running after the worker is started.
-  StartWorker(version_.get(), ServiceWorkerMetrics::EventType::UNKNOWN);
-  EXPECT_TRUE(version_->timeout_timer_.IsRunning());
-  EXPECT_FALSE(version_->idle_time_.is_null());
-
-  // The idle time should be reset if the worker is restarted without
-  // controllee.
-  bool has_stopped = false;
-  version_->idle_time_ -= kOneSecond;
-  base::TimeTicks idle_time = version_->idle_time_;
-  version_->StopWorker(base::BindOnce(&VerifyCalled, &has_stopped));
-  base::RunLoop().RunUntilIdle();
-  EXPECT_TRUE(has_stopped);
-  StartWorker(version_.get(), ServiceWorkerMetrics::EventType::UNKNOWN);
-  EXPECT_TRUE(version_->timeout_timer_.IsRunning());
-  EXPECT_LT(idle_time, version_->idle_time_);
-
-  // Adding a controllee resets the idle time.
-  version_->idle_time_ -= kOneSecond;
-  idle_time = version_->idle_time_;
-  ServiceWorkerRemoteProviderEndpoint remote_endpoint;
-  base::WeakPtr<ServiceWorkerProviderHost> host = CreateProviderHostForWindow(
-      33 /* dummy render process id */, true /* is_parent_frame_secure */,
-      helper_->context()->AsWeakPtr(), &remote_endpoint);
-  version_->AddControllee(host.get());
-  EXPECT_TRUE(version_->timeout_timer_.IsRunning());
-  EXPECT_LT(idle_time, version_->idle_time_);
-
-  // Completing an event resets the idle time.
-  version_->idle_time_ -= kOneSecond;
-  idle_time = version_->idle_time_;
-  SimulateDispatchEvent(ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME);
-  EXPECT_LT(idle_time, version_->idle_time_);
-
-  // Starting and finishing a request resets the idle time.
-  version_->idle_time_ -= kOneSecond;
-  idle_time = version_->idle_time_;
-  base::Optional<blink::ServiceWorkerStatusCode> status;
-  int request_id =
-      version_->StartRequest(ServiceWorkerMetrics::EventType::SYNC,
-                             CreateReceiverOnCurrentThread(&status));
-  EXPECT_TRUE(version_->FinishRequest(request_id, true /* was_handled */));
-  EXPECT_LT(idle_time, version_->idle_time_);
-}
-
 TEST_F(ServiceWorkerVersionTest, SetDevToolsAttached) {
   base::Optional<blink::ServiceWorkerStatusCode> status;
   version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
diff --git a/content/browser/utility_process_host.cc b/content/browser/utility_process_host.cc
index 3d74373..40a2eee 100644
--- a/content/browser/utility_process_host.cc
+++ b/content/browser/utility_process_host.cc
@@ -262,6 +262,12 @@
                                               std::move(interface_pipe));
 }
 
+void UtilityProcessHost::RunService(
+    const std::string& service_name,
+    mojo::PendingReceiver<service_manager::mojom::Service> receiver) {
+  process_->GetHost()->RunService(service_name, std::move(receiver));
+}
+
 void UtilityProcessHost::SetMetricsName(const std::string& metrics_name) {
   metrics_name_ = metrics_name;
 }
diff --git a/content/browser/utility_process_host.h b/content/browser/utility_process_host.h
index 39edbdf..358230ba 100644
--- a/content/browser/utility_process_host.h
+++ b/content/browser/utility_process_host.h
@@ -18,8 +18,10 @@
 #include "content/common/content_export.h"
 #include "content/public/browser/browser_child_process_host_delegate.h"
 #include "ipc/ipc_sender.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/system/message_pipe.h"
 #include "services/service_manager/public/cpp/identity.h"
+#include "services/service_manager/public/mojom/service.mojom.h"
 #include "services/service_manager/sandbox/sandbox_type.h"
 
 namespace base {
@@ -86,6 +88,12 @@
   void BindInterface(const std::string& interface_name,
                      mojo::ScopedMessagePipeHandle interface_pipe);
 
+  // Instructs the utility process to run an instance of the named service,
+  // bound to |receiver|.
+  void RunService(
+      const std::string& service_name,
+      mojo::PendingReceiver<service_manager::mojom::Service> receiver);
+
   // Sets the name of the process to appear in the task manager.
   void SetName(const base::string16& name);
 
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 06988f3..38fc0c8 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -4301,13 +4301,7 @@
   // SSLInfo is not needed on subframe navigations since the main-frame
   // certificate is the only one that can be inspected (using the info
   // bubble) without refreshing the page with DevTools open.
-  // We don't call DidStartResourceResponse on net errors, since that results on
-  // existing cert exceptions being revoked, which leads to weird behavior with
-  // committed interstitials or while offline. We only need the error check for
-  // the main frame case because unlike this method, SubresourceResponseStarted
-  // does not get called on network errors.
-  if (navigation_handle->IsInMainFrame() &&
-      navigation_handle->GetNetErrorCode() == net::OK) {
+  if (navigation_handle->IsInMainFrame()) {
     controller_.ssl_manager()->DidStartResourceResponse(
         navigation_handle->GetURL(),
         navigation_handle->GetSSLInfo().has_value()
diff --git a/content/browser/web_contents/web_contents_view.h b/content/browser/web_contents/web_contents_view.h
index 2960f29..bfb918a 100644
--- a/content/browser/web_contents/web_contents_view.h
+++ b/content/browser/web_contents/web_contents_view.h
@@ -19,7 +19,6 @@
 class RenderWidgetHost;
 class RenderWidgetHostViewBase;
 struct DropData;
-struct ScreenInfo;
 
 // The WebContentsView is an interface that is implemented by the platform-
 // dependent web contents views. The WebContents uses this interface to talk to
@@ -40,9 +39,6 @@
   // dialog boxes.
   virtual gfx::NativeWindow GetTopLevelNativeWindow() const = 0;
 
-  // The following static method is implemented by each platform.
-  static void GetDefaultScreenInfo(ScreenInfo* results);
-
   // Computes the rectangle for the native widget that contains the contents of
   // the tab in the screen coordinate system.
   virtual void GetContainerBounds(gfx::Rect* out) const = 0;
diff --git a/content/child/BUILD.gn b/content/child/BUILD.gn
index f454ddf..8a51f69e8 100644
--- a/content/child/BUILD.gn
+++ b/content/child/BUILD.gn
@@ -65,8 +65,6 @@
     "runtime_features.h",
     "scoped_child_process_reference.cc",
     "scoped_child_process_reference.h",
-    "service_factory.cc",
-    "service_factory.h",
     "thread_safe_sender.cc",
     "thread_safe_sender.h",
     "webthemeengine_impl_android.cc",
diff --git a/content/child/child_thread_impl.cc b/content/child/child_thread_impl.cc
index 8f5e6f16..c99ec67 100644
--- a/content/child/child_thread_impl.cc
+++ b/content/child/child_thread_impl.cc
@@ -694,6 +694,12 @@
 }
 #endif  //  IPC_MESSAGE_LOG_ENABLED
 
+void ChildThreadImpl::RunService(
+    const std::string& service_name,
+    mojo::PendingReceiver<service_manager::mojom::Service> receiver) {
+  DLOG(ERROR) << "Ignoring unhandled request to run service: " << service_name;
+}
+
 void ChildThreadImpl::OnChildControlRequest(
     mojom::ChildControlRequest request) {
   child_control_bindings_.AddBinding(this, std::move(request));
diff --git a/content/child/child_thread_impl.h b/content/child/child_thread_impl.h
index 9f917bc..a10be95 100644
--- a/content/child/child_thread_impl.h
+++ b/content/child/child_thread_impl.h
@@ -145,6 +145,10 @@
 #if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
   void SetIPCLoggingEnabled(bool enable) override;
 #endif
+  void RunService(
+      const std::string& service_name,
+      mojo::PendingReceiver<service_manager::mojom::Service> receiver) override;
+
   void OnChildControlRequest(mojom::ChildControlRequest);
 
   virtual bool OnControlMessageReceived(const IPC::Message& msg);
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index 12f1bca6..401eddd 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -307,7 +307,7 @@
   if (base::FeatureList::IsEnabled(features::kGenericSensorExtraClasses))
     WebRuntimeFeatures::EnableGenericSensorExtraClasses(true);
 
-  if (base::FeatureList::IsEnabled(network::features::kOutOfBlinkCors))
+  if (network::features::ShouldEnableOutOfBlinkCors())
     WebRuntimeFeatures::EnableOutOfBlinkCors(true);
 
   WebRuntimeFeatures::EnableMediaCastOverlayButton(
@@ -408,10 +408,6 @@
   WebRuntimeFeatures::EnableWasmCodeCache(
       base::FeatureList::IsEnabled(blink::features::kWasmCodeCache));
 
-  // Make imagesrcset on link rel=preload work with SignedHTTPExchange flag too.
-  if (base::FeatureList::IsEnabled(features::kSignedHTTPExchange))
-    WebRuntimeFeatures::EnablePreloadImageSrcSetEnabled(true);
-
   if (base::FeatureList::IsEnabled(
           features::kExperimentalProductivityFeatures)) {
     WebRuntimeFeatures::EnableExperimentalProductivityFeatures(true);
diff --git a/content/child/service_factory.cc b/content/child/service_factory.cc
deleted file mode 100644
index 52f6385..0000000
--- a/content/child/service_factory.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/child/service_factory.h"
-
-#include <utility>
-
-#include "base/bind.h"
-#include "content/public/common/content_client.h"
-
-namespace content {
-
-ServiceFactory::ServiceFactory() = default;
-
-ServiceFactory::~ServiceFactory() = default;
-
-bool ServiceFactory::HandleServiceRequest(
-    const std::string& name,
-    service_manager::mojom::ServiceRequest request) {
-  return false;
-}
-
-void ServiceFactory::CreateService(
-    service_manager::mojom::ServiceRequest request,
-    const std::string& name,
-    service_manager::mojom::PIDReceiverPtr pid_receiver) {
-  if (HandleServiceRequest(name, std::move(request)))
-    return;
-
-  // DCHECK in developer builds to make these errors easier to identify.
-  // Otherwise they result only in cryptic browser error messages.
-  NOTREACHED() << "Unable to start service \"" << name << "\". Did you "
-               << "forget to register the service in the utility process's"
-               << "ServiceFactory?";
-  OnLoadFailed();
-}
-
-}  // namespace content
diff --git a/content/child/service_factory.h b/content/child/service_factory.h
deleted file mode 100644
index 9c63ab8..0000000
--- a/content/child/service_factory.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_CHILD_SERVICE_FACTORY_H_
-#define CONTENT_CHILD_SERVICE_FACTORY_H_
-
-#include <map>
-#include <memory>
-
-#include "base/macros.h"
-#include "services/service_manager/public/mojom/service.mojom.h"
-#include "services/service_manager/public/mojom/service_factory.mojom.h"
-
-namespace content {
-
-// Base class for child-process specific implementations of
-// service_manager::mojom::ServiceFactory.
-class ServiceFactory : public service_manager::mojom::ServiceFactory {
- public:
-  ServiceFactory();
-  ~ServiceFactory() override;
-
-  virtual bool HandleServiceRequest(
-      const std::string& name,
-      service_manager::mojom::ServiceRequest request);
-
-  // service_manager::mojom::ServiceFactory:
-  void CreateService(
-      service_manager::mojom::ServiceRequest request,
-      const std::string& name,
-      service_manager::mojom::PIDReceiverPtr pid_receiver) override;
-
- private:
-  // Called if CreateService fails to find a registered service.
-  virtual void OnLoadFailed() {}
-
-  DISALLOW_COPY_AND_ASSIGN(ServiceFactory);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_CHILD_SERVICE_FACTORY_H_
diff --git a/content/common/child_control.mojom b/content/common/child_control.mojom
index 733c85c..c840289ab 100644
--- a/content/common/child_control.mojom
+++ b/content/common/child_control.mojom
@@ -4,11 +4,19 @@
 
 module content.mojom;
 
+import "services/service_manager/public/mojom/service.mojom";
+
 interface ChildControl {
-  // Tell the child process that it's safe to shutdown.
+  // Tells the child process that it's safe to shutdown.
   ProcessShutdown();
 
-  // Tell the child process to begin or end IPC message logging.
+  // Tells the child process to begin or end IPC message logging.
   [EnableIf=ipc_logging]
   SetIPCLoggingEnabled(bool on);
+
+  // Tells the child process to run an instance of a service named
+  // |service_name|, binding it to |receiver|. This is used by the browser to
+  // support launching of packaged services within Utility or GPU processes.
+  RunService(string service_name,
+             pending_receiver<service_manager.mojom.Service> receiver);
 };
diff --git a/content/common/child_process_host_impl.cc b/content/common/child_process_host_impl.cc
index 27b8c5a..761d1453 100644
--- a/content/common/child_process_host_impl.cc
+++ b/content/common/child_process_host_impl.cc
@@ -101,6 +101,12 @@
   return delegate_->BindInterface(interface_name, std::move(interface_pipe));
 }
 
+void ChildProcessHostImpl::RunService(
+    const std::string& service_name,
+    mojo::PendingReceiver<service_manager::mojom::Service> receiver) {
+  child_control_->RunService(service_name, std::move(receiver));
+}
+
 void ChildProcessHostImpl::ForceShutdown() {
   child_control_->ProcessShutdown();
 }
diff --git a/content/common/child_process_host_impl.h b/content/common/child_process_host_impl.h
index 99644ea..7ed3a4ce 100644
--- a/content/common/child_process_host_impl.h
+++ b/content/common/child_process_host_impl.h
@@ -70,6 +70,9 @@
   void AddFilter(IPC::MessageFilter* filter) override;
   void BindInterface(const std::string& interface_name,
                      mojo::ScopedMessagePipeHandle interface_pipe) override;
+  void RunService(
+      const std::string& service_name,
+      mojo::PendingReceiver<service_manager::mojom::Service> receiver) override;
 
   base::Process& peer_process() { return peer_process_; }
 
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h
index 831e7c4..0ea49d9 100644
--- a/content/common/frame_messages.h
+++ b/content/common/frame_messages.h
@@ -56,6 +56,7 @@
 #include "third_party/blink/public/common/feature_policy/feature_policy.h"
 #include "third_party/blink/public/common/frame/frame_owner_element_type.h"
 #include "third_party/blink/public/common/frame/frame_policy.h"
+#include "third_party/blink/public/common/frame/occlusion_state.h"
 #include "third_party/blink/public/common/frame/user_activation_update_type.h"
 #include "third_party/blink/public/common/messaging/message_port_channel.h"
 #include "third_party/blink/public/common/messaging/transferable_message.h"
@@ -156,6 +157,9 @@
                           blink::mojom::FeaturePolicyDisposition::kMaxValue)
 IPC_ENUM_TRAITS_MAX_VALUE(blink::mojom::FrameVisibility,
                           blink::mojom::FrameVisibility::kMaxValue)
+IPC_ENUM_TRAITS_MIN_MAX_VALUE(blink::FrameOcclusionState,
+                              blink::kUnknownOcclusionState,
+                              blink::kMaxOcclusionState)
 
 IPC_STRUCT_TRAITS_BEGIN(blink::WebFloatSize)
   IPC_STRUCT_TRAITS_MEMBER(width)
@@ -1035,6 +1039,11 @@
 // (e.g. during Android voice search).
 IPC_MESSAGE_ROUTED0(FrameMsg_NotifyUserActivation)
 
+// Notifies a parent frame that the child frame requires information about
+// whether it is occluded or has visual effects applied.
+IPC_MESSAGE_ROUTED1(FrameMsg_SetNeedsOcclusionTracking,
+                    bool /* needs_tracking */)
+
 // Tells the frame to update the user activation state in appropriate part of
 // the frame tree (ancestors for activation notification and all nodes for
 // consumption).
@@ -1389,7 +1398,13 @@
 IPC_MESSAGE_ROUTED3(FrameHostMsg_UpdateViewportIntersection,
                     gfx::Rect /* viewport_intersection */,
                     gfx::Rect /* compositor_visible_rect */,
-                    bool /* occluded or obscured */)
+                    blink::FrameOcclusionState /* occlusion_state */)
+
+// Indicates that a child frame requires its parent frame to send it information
+// about whether it is occluded or has visual effects applied, in order to
+// service IntersectionObserver's that track visibility.
+IPC_MESSAGE_ROUTED1(FrameHostMsg_SetNeedsOcclusionTracking,
+                    bool /* needs_tracking */)
 
 // Informs the child that the frame has changed visibility.
 IPC_MESSAGE_ROUTED1(FrameHostMsg_VisibilityChanged,
diff --git a/content/common/widget_messages.h b/content/common/widget_messages.h
index 208aea8..da13f24 100644
--- a/content/common/widget_messages.h
+++ b/content/common/widget_messages.h
@@ -15,6 +15,7 @@
 #include "content/common/visual_properties.h"
 #include "content/public/common/common_param_traits.h"
 #include "ipc/ipc_message_macros.h"
+#include "third_party/blink/public/common/frame/occlusion_state.h"
 #include "third_party/blink/public/common/screen_orientation/web_screen_orientation_type.h"
 #include "third_party/blink/public/platform/web_float_point.h"
 #include "third_party/blink/public/platform/web_float_rect.h"
@@ -187,11 +188,11 @@
 IPC_MESSAGE_ROUTED1(WidgetMsg_ForceRedraw, int /* snapshot_id */)
 
 // Sets the viewport intersection and compositor raster area on the widget for
-// an out-of-process iframe.
+// an out-of-process iframe. Also see FrameMsg_UpdateViewportIntersection.
 IPC_MESSAGE_ROUTED3(WidgetMsg_SetViewportIntersection,
                     gfx::Rect /* viewport_intersection */,
                     gfx::Rect /* compositor_visible_rect */,
-                    bool /* occluded or obscured */)
+                    blink::FrameOcclusionState /* occlusion_state */)
 
 // Sent to an OOPIF widget when the browser receives a FrameHostMsg_SetIsInert
 // from the target widget's embedding renderer changing its inertness. When a
diff --git a/content/gpu/gpu_child_thread.cc b/content/gpu/gpu_child_thread.cc
index 5d8413f..55499d9d 100644
--- a/content/gpu/gpu_child_thread.cc
+++ b/content/gpu/gpu_child_thread.cc
@@ -239,10 +239,6 @@
       &GpuChildThread::CreateVizMainService, base::Unretained(this)));
 
   auto registry = std::make_unique<service_manager::BinderRegistry>();
-  registry->AddInterface(
-      base::BindRepeating(&GpuChildThread::BindServiceFactoryRequest,
-                          weak_factory_.GetWeakPtr()),
-      base::ThreadTaskRunnerHandle::Get());
   if (GetContentClient()->gpu())  // nullptr in tests.
     GetContentClient()->gpu()->InitializeRegistry(registry.get());
 
@@ -281,6 +277,18 @@
   return ChildThreadImpl::Send(msg);
 }
 
+void GpuChildThread::RunService(
+    const std::string& service_name,
+    mojo::PendingReceiver<service_manager::mojom::Service> receiver) {
+  if (!service_factory_) {
+    pending_service_requests_.emplace_back(service_name, std::move(receiver));
+    return;
+  }
+
+  DVLOG(1) << "GPU: Handling RunService request for " << service_name;
+  service_factory_->RunService(service_name, std::move(receiver));
+}
+
 void GpuChildThread::OnAssociatedInterfaceRequest(
     const std::string& name,
     mojo::ScopedInterfaceEndpointHandle handle) {
@@ -317,6 +325,10 @@
 
   DCHECK(release_pending_requests_closure_);
   std::move(release_pending_requests_closure_).Run();
+
+  for (auto& request : pending_service_requests_)
+    RunService(request.service_name, std::move(request.receiver));
+  pending_service_requests_.clear();
 }
 
 void GpuChildThread::PostCompositorThreadCreated(
@@ -330,14 +342,6 @@
   quit_closure_.Run();
 }
 
-void GpuChildThread::BindServiceFactoryRequest(
-    service_manager::mojom::ServiceFactoryRequest request) {
-  DVLOG(1) << "GPU: Binding service_manager::mojom::ServiceFactoryRequest";
-  DCHECK(service_factory_);
-  service_factory_bindings_.AddBinding(service_factory_.get(),
-                                       std::move(request));
-}
-
 void GpuChildThread::OnMemoryPressure(
     base::MemoryPressureListener::MemoryPressureLevel level) {
   if (level != base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL)
@@ -401,4 +405,14 @@
 }
 #endif
 
+GpuChildThread::PendingServiceRequest::PendingServiceRequest(
+    const std::string& service_name,
+    mojo::PendingReceiver<service_manager::mojom::Service> receiver)
+    : service_name(service_name), receiver(std::move(receiver)) {}
+
+GpuChildThread::PendingServiceRequest::PendingServiceRequest(
+    PendingServiceRequest&&) = default;
+
+GpuChildThread::PendingServiceRequest::~PendingServiceRequest() = default;
+
 }  // namespace content
diff --git a/content/gpu/gpu_child_thread.h b/content/gpu/gpu_child_thread.h
index f9264ba..3b40d5a5 100644
--- a/content/gpu/gpu_child_thread.h
+++ b/content/gpu/gpu_child_thread.h
@@ -10,6 +10,7 @@
 #include <memory>
 #include <queue>
 #include <string>
+#include <vector>
 
 #include "base/callback.h"
 #include "base/command_line.h"
@@ -31,9 +32,7 @@
 #include "gpu/ipc/service/x_util.h"
 #include "media/base/android_overlay_mojo_factory.h"
 #include "mojo/public/cpp/bindings/associated_binding_set.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
 #include "services/service_manager/public/cpp/service_context_ref.h"
-#include "services/service_manager/public/mojom/service_factory.mojom.h"
 #include "services/viz/privileged/interfaces/viz_main.mojom.h"
 #include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h"
 #include "ui/gfx/native_widget_types.h"
@@ -68,8 +67,11 @@
 
   bool in_process_gpu() const;
 
-  // ChildThreadImpl:.
+  // ChildThreadImpl:
   bool Send(IPC::Message* msg) override;
+  void RunService(
+      const std::string& service_name,
+      mojo::PendingReceiver<service_manager::mojom::Service> receiver) override;
 
   // IPC::Listener implementation via ChildThreadImpl:
   void OnAssociatedInterfaceRequest(
@@ -86,9 +88,6 @@
   void OnMemoryPressure(
       base::MemoryPressureListener::MemoryPressureLevel level);
 
-  void BindServiceFactoryRequest(
-      service_manager::mojom::ServiceFactoryRequest request);
-
   // Returns a closure which calls into the VizMainImpl to perform shutdown
   // before quitting the main message loop. Must be called on the main thread.
   static base::RepeatingClosure MakeQuitSafelyClosure();
@@ -107,10 +106,6 @@
   // ServiceFactory for service_manager::Service hosting.
   std::unique_ptr<GpuServiceFactory> service_factory_;
 
-  // Bindings to the service_manager::mojom::ServiceFactory impl.
-  mojo::BindingSet<service_manager::mojom::ServiceFactory>
-      service_factory_bindings_;
-
   blink::AssociatedInterfaceRegistry associated_interfaces_;
 
   // Holds a closure that releases pending interface requests on the IO thread.
@@ -121,6 +116,20 @@
 
   std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
 
+  // Retains pending GPU-process service startup requests (i.e. RunService
+  // invocations from the browser) until the process is fully initialized.
+  struct PendingServiceRequest {
+    PendingServiceRequest(
+        const std::string& service_name,
+        mojo::PendingReceiver<service_manager::mojom::Service> receiver);
+    PendingServiceRequest(PendingServiceRequest&&);
+    ~PendingServiceRequest();
+
+    std::string service_name;
+    mojo::PendingReceiver<service_manager::mojom::Service> receiver;
+  };
+  std::vector<PendingServiceRequest> pending_service_requests_;
+
   base::WeakPtrFactory<GpuChildThread> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(GpuChildThread);
diff --git a/content/gpu/gpu_service_factory.cc b/content/gpu/gpu_service_factory.cc
index 56d9a6b3..71ae3de 100644
--- a/content/gpu/gpu_service_factory.cc
+++ b/content/gpu/gpu_service_factory.cc
@@ -41,9 +41,10 @@
 
 GpuServiceFactory::~GpuServiceFactory() {}
 
-bool GpuServiceFactory::HandleServiceRequest(
+void GpuServiceFactory::RunService(
     const std::string& service_name,
-    service_manager::mojom::ServiceRequest request) {
+    mojo::PendingReceiver<service_manager::mojom::Service> receiver) {
+  auto request = service_manager::mojom::ServiceRequest(std::move(receiver));
 #if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
   if (service_name == media::mojom::kMediaServiceName) {
     media::CdmProxyFactoryCB cdm_proxy_factory_cb;
@@ -80,7 +81,7 @@
                              std::move(factory).Run());
                        },
                        std::move(factory)));
-    return true;
+    return;
   }
 #endif  // BUILDFLAG(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
 
@@ -88,10 +89,8 @@
     service_manager::Service::RunAsyncUntilTermination(
         std::make_unique<shape_detection::ShapeDetectionService>(
             std::move(request)));
-    return true;
+    return;
   }
-
-  return true;
 }
 
 }  // namespace content
diff --git a/content/gpu/gpu_service_factory.h b/content/gpu/gpu_service_factory.h
index 0c88974..cb4314b 100644
--- a/content/gpu/gpu_service_factory.h
+++ b/content/gpu/gpu_service_factory.h
@@ -9,12 +9,12 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "base/single_thread_task_runner.h"
-#include "content/child/service_factory.h"
 #include "gpu/config/gpu_driver_bug_workarounds.h"
 #include "gpu/config/gpu_feature_info.h"
 #include "gpu/config/gpu_preferences.h"
 #include "media/base/android_overlay_mojo_factory.h"
 #include "media/mojo/buildflags.h"
+#include "services/service_manager/public/mojom/service.mojom.h"
 
 namespace media {
 class MediaGpuChannelManager;
@@ -22,8 +22,8 @@
 
 namespace content {
 
-// Customization of ServiceFactory for the GPU process.
-class GpuServiceFactory : public ServiceFactory {
+// Helper for handling incoming RunService requests on GpuChildThread.
+class GpuServiceFactory {
  public:
   GpuServiceFactory(
       const gpu::GpuPreferences& gpu_preferences,
@@ -31,12 +31,11 @@
       const gpu::GpuFeatureInfo& gpu_feature_info,
       base::WeakPtr<media::MediaGpuChannelManager> media_gpu_channel_manager,
       media::AndroidOverlayMojoFactoryCB android_overlay_factory_cb);
-  ~GpuServiceFactory() override;
+  ~GpuServiceFactory();
 
-  // ServiceFactory overrides:
-  bool HandleServiceRequest(
+  void RunService(
       const std::string& service_name,
-      service_manager::mojom::ServiceRequest request) override;
+      mojo::PendingReceiver<service_manager::mojom::Service> receiver);
 
  private:
 #if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h
index 2fe0a25a..27cbadf 100644
--- a/content/public/browser/web_contents.h
+++ b/content/public/browser/web_contents.h
@@ -361,7 +361,9 @@
   virtual RenderWidgetHostView* GetFullscreenRenderWidgetHostView() = 0;
 
   // Returns the theme color for the underlying content as set by the
-  // theme-color meta tag.
+  // theme-color meta tag, returns SK_ColorTRANSPARENT if none.
+  // TODO(crbug.com/872121): Make this return a base::Optional instead of
+  // relying on a sentinel value.
   virtual SkColor GetThemeColor() = 0;
 
   // Returns the committed WebUI if one exists, otherwise the pending one.
diff --git a/content/public/common/child_process_host.h b/content/public/common/child_process_host.h
index 9fbfb0bb..8f26d3b 100644
--- a/content/public/common/child_process_host.h
+++ b/content/public/common/child_process_host.h
@@ -6,13 +6,17 @@
 #define CONTENT_PUBLIC_COMMON_CHILD_PROCESS_HOST_H_
 
 #include <stdint.h>
+
 #include <memory>
+#include <string>
 
 #include "base/files/scoped_file.h"
 #include "build/build_config.h"
 #include "content/common/content_export.h"
 #include "content/public/common/bind_interface_helpers.h"
 #include "ipc/ipc_channel_proxy.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "services/service_manager/public/mojom/service.mojom.h"
 
 namespace base {
 class FilePath;
@@ -86,6 +90,11 @@
   // Bind an interface exposed by the child process.
   virtual void BindInterface(const std::string& interface_name,
                              mojo::ScopedMessagePipeHandle interface_pipe) = 0;
+
+  // Instructs the child process to run an instance of the named service.
+  virtual void RunService(
+      const std::string& service_name,
+      mojo::PendingReceiver<service_manager::mojom::Service> receiver) = 0;
 };
 
 }  // namespace content
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index a2196ab..c83c2a3 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -144,9 +144,10 @@
 const base::Feature kDesktopCaptureChangeSource{
     "DesktopCaptureChangeSource", base::FEATURE_ENABLED_BY_DEFAULT};
 
-// Enables additional image label features that haven't launched yet.
+// When a screen reader is detected, allow users the option of letting
+// Google provide descriptions for unlabeled images.
 const base::Feature kExperimentalAccessibilityLabels{
-    "ExperimentalAccessibilityLabels", base::FEATURE_DISABLED_BY_DEFAULT};
+    "ExperimentalAccessibilityLabels", base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Throttle tasks in Blink background timer queues based on CPU budgets
 // for the background tab. Bug: https://crbug.com/639852.
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index 7d2d0cb..8363d5d 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -254,8 +254,6 @@
     "media/stream/apply_constraints_processor.h",
     "media/stream/audio_service_audio_processor_proxy.cc",
     "media/stream/audio_service_audio_processor_proxy.h",
-    "media/stream/external_media_stream_audio_source.cc",
-    "media/stream/external_media_stream_audio_source.h",
     "media/stream/local_media_stream_audio_source.cc",
     "media/stream/local_media_stream_audio_source.h",
     "media/stream/local_video_capturer_source.cc",
@@ -303,8 +301,6 @@
     "media/web_media_element_source_utils.h",
     "media/webrtc/audio_codec_factory.cc",
     "media/webrtc/audio_codec_factory.h",
-    "media/webrtc/fake_rtc_rtp_transceiver.cc",
-    "media/webrtc/fake_rtc_rtp_transceiver.h",
     "media/webrtc/media_stream_remote_video_source.cc",
     "media/webrtc/media_stream_remote_video_source.h",
     "media/webrtc/media_stream_track_metrics.cc",
diff --git a/content/renderer/accessibility/ax_image_annotator.cc b/content/renderer/accessibility/ax_image_annotator.cc
index c4ac434..af503de 100644
--- a/content/renderer/accessibility/ax_image_annotator.cc
+++ b/content/renderer/accessibility/ax_image_annotator.cc
@@ -158,11 +158,35 @@
     blink::WebAXObject image = blink::WebAXObject::FromWebDocumentByID(
         render_accessibility_->GetMainDocument(), key_value.first);
     if (!image.IsDetached())
-      render_accessibility_->MarkWebAXObjectDirty(image, false /* subtree */);
+      MarkDirty(image);
   }
   image_annotations_.clear();
 }
 
+void AXImageAnnotator::MarkDirty(const blink::WebAXObject& image) const {
+  render_accessibility_->MarkWebAXObjectDirty(image, false /* subtree */);
+
+  // Check two unignored parents. If either of them is a link or root web area,
+  // mark it dirty too, because we want a link or document containing exactly
+  // a single image and nothing more to get annotated directly, too.
+  //
+  // TODO(dmazzoni): Expose ParentObjectUnignored in WebAXObject to
+  // make this simpler.
+  blink::WebAXObject parent = image.ParentObject();
+  for (int ancestor_count = 0; !parent.IsDetached() && ancestor_count < 2;
+       parent = parent.ParentObject()) {
+    if (!parent.AccessibilityIsIgnored()) {
+      ++ancestor_count;
+      if (parent.Role() == ax::mojom::Role::kLink ||
+          parent.Role() == ax::mojom::Role::kRootWebArea) {
+        render_accessibility_->MarkWebAXObjectDirty(parent,
+                                                    false /* subtree */);
+        return;
+      }
+    }
+  }
+}
+
 AXImageAnnotator::ImageInfo::ImageInfo(const blink::WebAXObject& image)
     : image_processor_(
           base::BindRepeating(&AXImageAnnotator::GetImageData, image)),
@@ -241,7 +265,7 @@
             .set_status(ax::mojom::ImageAnnotationStatus::kAnnotationAdult);
         break;
     }
-    render_accessibility_->MarkWebAXObjectDirty(image, false /* subtree */);
+    MarkDirty(image);
     return;
   }
 
@@ -249,7 +273,7 @@
     DLOG(WARNING) << "No image annotation results.";
     image_annotations_.at(image.AxID())
         .set_status(ax::mojom::ImageAnnotationStatus::kAnnotationEmpty);
-    render_accessibility_->MarkWebAXObjectDirty(image, false /* subtree */);
+    MarkDirty(image);
     return;
   }
 
@@ -286,7 +310,7 @@
   if (contextualized_strings.empty()) {
     image_annotations_.at(image.AxID())
         .set_status(ax::mojom::ImageAnnotationStatus::kAnnotationEmpty);
-    render_accessibility_->MarkWebAXObjectDirty(image, false /* subtree */);
+    MarkDirty(image);
     return;
   }
 
@@ -298,7 +322,7 @@
   std::string contextualized_string =
       base::JoinString(contextualized_strings, ". ");
   image_annotations_.at(image.AxID()).set_annotation(contextualized_string);
-  render_accessibility_->MarkWebAXObjectDirty(image, false /* subtree */);
+  MarkDirty(image);
 
   VLOG(1) << "Annotating image on page " << GetDocumentUrl() << " - "
           << contextualized_string;
diff --git a/content/renderer/accessibility/ax_image_annotator.h b/content/renderer/accessibility/ax_image_annotator.h
index 0b8ae0b..0b7c01a 100644
--- a/content/renderer/accessibility/ax_image_annotator.h
+++ b/content/renderer/accessibility/ax_image_annotator.h
@@ -98,6 +98,11 @@
   // Removes the automatic image annotations from all images.
   void MarkAllImagesDirty();
 
+  // Marks a node in the accessibility tree dirty when an image annotation
+  // changes. Also marks dirty a link or document that immediately contains
+  // an image.
+  void MarkDirty(const blink::WebAXObject& image) const;
+
   // Gets called when an image gets annotated by the image annotation service.
   void OnImageAnnotated(const blink::WebAXObject& image,
                         image_annotation::mojom::AnnotateImageResultPtr result);
diff --git a/content/renderer/accessibility/blink_ax_tree_source.cc b/content/renderer/accessibility/blink_ax_tree_source.cc
index 784c728..623b95e 100644
--- a/content/renderer/accessibility/blink_ax_tree_source.cc
+++ b/content/renderer/accessibility/blink_ax_tree_source.cc
@@ -172,6 +172,51 @@
   return parent.Equals(ancestor);
 }
 
+// Helper function that searches in the subtree of |obj| to a max
+// depth of |max_depth| for an image.
+//
+// Returns true on success, or false if it finds more than one image,
+// or any node with a name, or anything deeper than |max_depth|.
+bool SearchForExactlyOneInnerImage(WebAXObject obj,
+                                   WebAXObject* inner_image,
+                                   int max_depth) {
+  DCHECK(inner_image);
+
+  // If it's the first image, set |inner_image|. If we already
+  // found an image, fail.
+  if (obj.Role() == ax::mojom::Role::kImage) {
+    if (!inner_image->IsDetached())
+      return false;
+    *inner_image = obj;
+  }
+
+  // Fail if we recursed to |max_depth| and there's more of a subtree.
+  if (max_depth == 0 && obj.ChildCount())
+    return false;
+
+  // If we found something else with a name, fail.
+  blink::WebString web_name = obj.GetName();
+  if (!base::ContainsOnlyChars(web_name.Utf8(), base::kWhitespaceASCII))
+    return false;
+
+  // Recurse.
+  for (unsigned int i = 0; i < obj.ChildCount(); i++) {
+    if (!SearchForExactlyOneInnerImage(obj.ChildAt(i), inner_image,
+                                       max_depth - 1))
+      return false;
+  }
+
+  return !inner_image->IsDetached();
+}
+
+// Return true if the subtree of |obj|, to a max depth of 2, contains
+// exactly one image. Return that image in |inner_image|.
+bool FindExactlyOneInnerImageInMaxDepthTwo(WebAXObject obj,
+                                           WebAXObject* inner_image) {
+  DCHECK(inner_image);
+  return SearchForExactlyOneInnerImage(obj, inner_image, /* max_depth = */ 2);
+}
+
 std::string GetEquivalentAriaRoleString(const ax::mojom::Role role) {
   switch (role) {
     case ax::mojom::Role::kArticle:
@@ -887,6 +932,16 @@
 
     if (dst->role == ax::mojom::Role::kImage)
       AddImageAnnotations(src, dst);
+
+    // If a link or web area isn't otherwise labeled and contains
+    // exactly one image (searching only to a max depth of 2),
+    // annotate the link/web area with the image's annotation, too.
+    if (dst->role == ax::mojom::Role::kLink ||
+        dst->role == ax::mojom::Role::kRootWebArea) {
+      WebAXObject inner_image;
+      if (FindExactlyOneInnerImageInMaxDepthTwo(src, &inner_image))
+        AddImageAnnotations(inner_image, dst);
+    }
   }
 
   // The majority of the rest of this code computes attributes needed for
@@ -1051,8 +1106,21 @@
   //
   // In the future, we may annotate some images that have a name
   // if we think we can add additional useful information.
-  if (dst->GetNameFrom() == ax::mojom::NameFrom::kAttributeExplicitlyEmpty ||
-      dst->HasStringAttribute(ax::mojom::StringAttribute::kName)) {
+  ax::mojom::NameFrom name_from;
+  blink::WebVector<WebAXObject> name_objects;
+  blink::WebString web_name = src.GetName(name_from, name_objects);
+  if (name_from == ax::mojom::NameFrom::kAttributeExplicitlyEmpty ||
+      !web_name.IsEmpty()) {
+    dst->SetImageAnnotationStatus(
+        ax::mojom::ImageAnnotationStatus::kIneligibleForAnnotation);
+    return;
+  }
+
+  // |dst| may be a document or link containing an image. Skip annotating
+  // it if it already has text other than whitespace.
+  if (!base::ContainsOnlyChars(
+          dst->GetStringAttribute(ax::mojom::StringAttribute::kName),
+          base::kWhitespaceASCII)) {
     dst->SetImageAnnotationStatus(
         ax::mojom::ImageAnnotationStatus::kIneligibleForAnnotation);
     return;
diff --git a/content/renderer/accessibility/render_accessibility_impl.cc b/content/renderer/accessibility/render_accessibility_impl.cc
index 741fc65..5b0cd7c 100644
--- a/content/renderer/accessibility/render_accessibility_impl.cc
+++ b/content/renderer/accessibility/render_accessibility_impl.cc
@@ -722,6 +722,9 @@
         MarkAllAXObjectsDirty(ax::mojom::Role::kImage);
       }
       break;
+    case ax::mojom::Action::kSignalEndOfTest:
+      HandleAXEvent(root, ax::mojom::Event::kEndOfTest);
+      break;
   }
 }
 
diff --git a/content/renderer/accessibility/render_accessibility_impl_browsertest.cc b/content/renderer/accessibility/render_accessibility_impl_browsertest.cc
index c20a951..22eac1f 100644
--- a/content/renderer/accessibility/render_accessibility_impl_browsertest.cc
+++ b/content/renderer/accessibility/render_accessibility_impl_browsertest.cc
@@ -397,6 +397,7 @@
 TEST_F(AXImageAnnotatorTest, OnImageAdded) {
   LoadHTMLAndRefreshAccessibilityTree(R"HTML(
       <body>
+        <p>Test document</p>
         <img id="A" src="test1.jpg"
             style="width: 200px; height: 150px;">
         <img id="B" src="test2.jpg"
@@ -409,7 +410,6 @@
   // check test expectations.
   scoped_task_environment_.RunUntilIdle();
 
-  ASSERT_EQ(4, CountAccessibilityNodesSentToBrowser());
   EXPECT_THAT(mock_annotator().image_ids_, ElementsAre("test1.jpg"));
   ASSERT_EQ(1u, mock_annotator().image_processors_.size());
   EXPECT_TRUE(mock_annotator().image_processors_[0].is_bound());
@@ -441,6 +441,7 @@
 TEST_F(AXImageAnnotatorTest, OnImageUpdated) {
   LoadHTMLAndRefreshAccessibilityTree(R"HTML(
       <body>
+        <p>Test document</p>
         <img id="A" src="test1.jpg"
             style="width: 200px; height: 150px;">
       </body>
@@ -451,7 +452,6 @@
   // check test expectations.
   scoped_task_environment_.RunUntilIdle();
 
-  ASSERT_EQ(3, CountAccessibilityNodesSentToBrowser());
   EXPECT_THAT(mock_annotator().image_ids_, ElementsAre("test1.jpg"));
   ASSERT_EQ(1u, mock_annotator().image_processors_.size());
   EXPECT_TRUE(mock_annotator().image_processors_[0].is_bound());
diff --git a/content/renderer/loader/web_url_loader_impl.cc b/content/renderer/loader/web_url_loader_impl.cc
index dd5c24a..c417f29d 100644
--- a/content/renderer/loader/web_url_loader_impl.cc
+++ b/content/renderer/loader/web_url_loader_impl.cc
@@ -1219,7 +1219,7 @@
     int request_id) {
   response->SetCurrentRequestUrl(url);
   response->SetResponseTime(info.response_time);
-  response->SetMIMEType(WebString::FromUTF8(info.mime_type));
+  response->SetMimeType(WebString::FromUTF8(info.mime_type));
   response->SetTextEncodingName(WebString::FromUTF8(info.charset));
   response->SetExpectedContentLength(info.content_length);
   response->SetHasMajorCertificateErrors(
diff --git a/content/renderer/media/stream/external_media_stream_audio_source.cc b/content/renderer/media/stream/external_media_stream_audio_source.cc
deleted file mode 100644
index 6248c27..0000000
--- a/content/renderer/media/stream/external_media_stream_audio_source.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/media/stream/external_media_stream_audio_source.h"
-
-namespace content {
-
-ExternalMediaStreamAudioSource::ExternalMediaStreamAudioSource(
-    scoped_refptr<media::AudioCapturerSource> source,
-    int sample_rate,
-    media::ChannelLayout channel_layout,
-    int frames_per_buffer,
-    bool is_remote,
-    scoped_refptr<base::SingleThreadTaskRunner> task_runner)
-    : blink::MediaStreamAudioSource(task_runner, !is_remote),
-      source_(std::move(source)),
-      was_started_(false) {
-  DVLOG(1)
-      << "ExternalMediaStreamAudioSource::ExternalMediaStreamAudioSource()";
-  DCHECK(source_.get());
-  MediaStreamAudioSource::SetFormat(media::AudioParameters(
-      media::AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout,
-      sample_rate,
-      frames_per_buffer));
-}
-
-ExternalMediaStreamAudioSource::~ExternalMediaStreamAudioSource() {
-  DVLOG(1)
-      << "ExternalMediaStreamAudioSource::~ExternalMediaStreamAudioSource()";
-  EnsureSourceIsStopped();
-}
-
-bool ExternalMediaStreamAudioSource::EnsureSourceIsStarted() {
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  if (was_started_)
-    return true;
-  VLOG(1) << "Starting externally-provided "
-          << (is_local_source() ? "local" : "remote")
-          << " source with audio parameters={"
-          << GetAudioParameters().AsHumanReadableString() << "}.";
-  source_->Initialize(GetAudioParameters(), this);
-  source_->Start();
-  was_started_ = true;
-  return true;
-}
-
-void ExternalMediaStreamAudioSource::EnsureSourceIsStopped() {
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  if (!source_)
-    return;
-  if (was_started_)
-    source_->Stop();
-  source_ = nullptr;
-  VLOG(1) << "Stopped externally-provided "
-          << (is_local_source() ? "local" : "remote")
-          << " source with audio parameters={"
-          << GetAudioParameters().AsHumanReadableString() << "}.";
-}
-
-void ExternalMediaStreamAudioSource::Capture(const media::AudioBus* audio_bus,
-                                             int audio_delay_milliseconds,
-                                             double volume,
-                                             bool key_pressed) {
-  DCHECK(audio_bus);
-  // TODO(miu): Plumbing is needed to determine the actual capture timestamp
-  // of the audio, instead of just snapshotting TimeTicks::Now(), for proper
-  // audio/video sync. https://crbug.com/335335
-  blink::MediaStreamAudioSource::DeliverDataToTracks(
-      *audio_bus, base::TimeTicks::Now() - base::TimeDelta::FromMilliseconds(
-                                               audio_delay_milliseconds));
-}
-
-void ExternalMediaStreamAudioSource::OnCaptureError(const std::string& why) {
-  StopSourceOnError(why);
-}
-
-void ExternalMediaStreamAudioSource::OnCaptureMuted(bool is_muted) {
-  SetMutedState(is_muted);
-}
-
-}  // namespace content
diff --git a/content/renderer/media/stream/external_media_stream_audio_source.h b/content/renderer/media/stream/external_media_stream_audio_source.h
deleted file mode 100644
index df71c08..0000000
--- a/content/renderer/media/stream/external_media_stream_audio_source.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_MEDIA_STREAM_EXTERNAL_MEDIA_STREAM_AUDIO_SOURCE_H_
-#define CONTENT_RENDERER_MEDIA_STREAM_EXTERNAL_MEDIA_STREAM_AUDIO_SOURCE_H_
-
-#include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h"
-
-#include "content/common/content_export.h"
-#include "media/base/audio_capturer_source.h"
-
-namespace content {
-
-// Represents an externally-provided local or remote source of audio data. This
-// allows users of the public content::MediaStreamApi to provide a
-// media::AudioCapturerSource to be used as the source of audio data in the
-// MediaStream framework. Audio data is transported directly to the tracks
-// (i.e., there is no audio processing).
-class CONTENT_EXPORT ExternalMediaStreamAudioSource final
-    : public blink::MediaStreamAudioSource,
-      public media::AudioCapturerSource::CaptureCallback {
- public:
-  ExternalMediaStreamAudioSource(
-      scoped_refptr<media::AudioCapturerSource> source,
-      int sample_rate,
-      media::ChannelLayout channel_layout,
-      int frames_per_buffer,
-      bool is_remote,
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner);
-
-  ~ExternalMediaStreamAudioSource() final;
-
- private:
-  // blink::MediaStreamAudioSource implementation.
-  bool EnsureSourceIsStarted() final;
-  void EnsureSourceIsStopped() final;
-
-  // media::AudioCapturerSource::CaptureCallback implementation.
-  void Capture(const media::AudioBus* audio_bus,
-               int audio_delay_milliseconds,
-               double volume,
-               bool key_pressed) final;
-  void OnCaptureError(const std::string& message) final;
-  void OnCaptureMuted(bool is_muted) final;
-
-  // The external source provided to the constructor.
-  scoped_refptr<media::AudioCapturerSource> source_;
-
-  // In debug builds, check that all methods that could cause object graph
-  // or data flow changes are being called on the main thread.
-  THREAD_CHECKER(thread_checker_);
-
-  // True once the source has been started successfully.
-  bool was_started_;
-
-  DISALLOW_COPY_AND_ASSIGN(ExternalMediaStreamAudioSource);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_RENDERER_MEDIA_STREAM_EXTERNAL_MEDIA_STREAM_AUDIO_SOURCE_H_
diff --git a/content/renderer/media/stream/local_media_stream_audio_source.cc b/content/renderer/media/stream/local_media_stream_audio_source.cc
index 8e6fdd9..27325eafb 100644
--- a/content/renderer/media/stream/local_media_stream_audio_source.cc
+++ b/content/renderer/media/stream/local_media_stream_audio_source.cc
@@ -4,6 +4,8 @@
 
 #include "content/renderer/media/stream/local_media_stream_audio_source.h"
 
+#include <utility>
+
 #include "content/renderer/media/audio/audio_device_factory.h"
 #include "content/renderer/media/webrtc_logging.h"
 #include "content/renderer/render_frame_impl.h"
@@ -16,7 +18,7 @@
     bool disable_local_echo,
     const ConstraintsCallback& started_callback,
     scoped_refptr<base::SingleThreadTaskRunner> task_runner)
-    : blink::MediaStreamAudioSource(task_runner,
+    : blink::MediaStreamAudioSource(std::move(task_runner),
                                     true /* is_local_source */,
                                     disable_local_echo),
       consumer_render_frame_id_(consumer_render_frame_id),
diff --git a/content/renderer/media/stream/processed_local_audio_source.cc b/content/renderer/media/stream/processed_local_audio_source.cc
index 33cfd58..c663e36a 100644
--- a/content/renderer/media/stream/processed_local_audio_source.cc
+++ b/content/renderer/media/stream/processed_local_audio_source.cc
@@ -95,7 +95,7 @@
     const ConstraintsCallback& started_callback,
     PeerConnectionDependencyFactory* factory,
     scoped_refptr<base::SingleThreadTaskRunner> task_runner)
-    : blink::MediaStreamAudioSource(task_runner,
+    : blink::MediaStreamAudioSource(std::move(task_runner),
                                     true /* is_local_source */,
                                     disable_local_echo),
       consumer_render_frame_id_(consumer_render_frame_id),
diff --git a/content/renderer/media/stream/webaudio_media_stream_source.cc b/content/renderer/media/stream/webaudio_media_stream_source.cc
index 7c9c825..1f1b6dd 100644
--- a/content/renderer/media/stream/webaudio_media_stream_source.cc
+++ b/content/renderer/media/stream/webaudio_media_stream_source.cc
@@ -4,6 +4,8 @@
 
 #include "content/renderer/media/stream/webaudio_media_stream_source.h"
 
+#include <utility>
+
 #include "base/bind.h"
 #include "base/bind_helpers.h"
 #include "base/logging.h"
@@ -13,7 +15,8 @@
 WebAudioMediaStreamSource::WebAudioMediaStreamSource(
     blink::WebMediaStreamSource* blink_source,
     scoped_refptr<base::SingleThreadTaskRunner> task_runner)
-    : blink::MediaStreamAudioSource(task_runner, false /* is_remote */),
+    : blink::MediaStreamAudioSource(std::move(task_runner),
+                                    false /* is_remote */),
       is_registered_consumer_(false),
       fifo_(base::Bind(&WebAudioMediaStreamSource::DeliverRebufferedAudio,
                        base::Unretained(this))),
diff --git a/content/renderer/media/stream/webaudio_media_stream_source.h b/content/renderer/media/stream/webaudio_media_stream_source.h
index 8d7955b..99ab9b4 100644
--- a/content/renderer/media/stream/webaudio_media_stream_source.h
+++ b/content/renderer/media/stream/webaudio_media_stream_source.h
@@ -25,7 +25,7 @@
     : public blink::MediaStreamAudioSource,
       public blink::WebAudioDestinationConsumer {
  public:
-  explicit WebAudioMediaStreamSource(
+  WebAudioMediaStreamSource(
       blink::WebMediaStreamSource* blink_source,
       scoped_refptr<base::SingleThreadTaskRunner> task_runner);
 
diff --git a/content/renderer/media/webrtc/fake_rtc_rtp_transceiver.cc b/content/renderer/media/webrtc/fake_rtc_rtp_transceiver.cc
index 6c1a2f4..a5d04bd 100644
--- a/content/renderer/media/webrtc/fake_rtc_rtp_transceiver.cc
+++ b/content/renderer/media/webrtc/fake_rtc_rtp_transceiver.cc
@@ -17,7 +17,7 @@
                         blink::WebString::FromUTF8("audio_track"), false);
   std::unique_ptr<blink::MediaStreamAudioSource> audio_source_ptr =
       std::make_unique<blink::MediaStreamAudioSource>(
-          task_runner, true /* is_local_source */);
+          std::move(task_runner), true /* is_local_source */);
   blink::MediaStreamAudioSource* audio_source = audio_source_ptr.get();
   // Takes ownership of |audio_source_ptr|.
   web_source.SetPlatformSource(std::move(audio_source_ptr));
diff --git a/content/renderer/media/webrtc/fake_rtc_rtp_transceiver.h b/content/renderer/media/webrtc/fake_rtc_rtp_transceiver.h
index d59ec65..cda182e 100644
--- a/content/renderer/media/webrtc/fake_rtc_rtp_transceiver.h
+++ b/content/renderer/media/webrtc/fake_rtc_rtp_transceiver.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "content/common/content_export.h"
 #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h"
 #include "third_party/blink/public/platform/web_media_constraints.h"
 #include "third_party/blink/public/platform/web_media_stream_source.h"
@@ -22,9 +21,11 @@
 
 // TODO(https://crbug.com/868868): Similar methods to this exist in many content
 // unittests. Move to a separate file and reuse it in all of them.
-blink::WebMediaStreamTrack CreateWebMediaStreamTrack(const std::string& id);
+blink::WebMediaStreamTrack CreateWebMediaStreamTrack(
+    const std::string& id,
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner);
 
-class CONTENT_EXPORT FakeRTCRtpSender : public blink::WebRTCRtpSender {
+class FakeRTCRtpSender : public blink::WebRTCRtpSender {
  public:
   FakeRTCRtpSender(base::Optional<std::string> track_id,
                    std::vector<std::string> stream_ids,
@@ -56,7 +57,7 @@
   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
 };
 
-class CONTENT_EXPORT FakeRTCRtpReceiver : public blink::WebRTCRtpReceiver {
+class FakeRTCRtpReceiver : public blink::WebRTCRtpReceiver {
  public:
   FakeRTCRtpReceiver(const std::string& track_id,
                      std::vector<std::string> stream_ids,
@@ -82,8 +83,7 @@
   std::vector<std::string> stream_ids_;
 };
 
-class CONTENT_EXPORT FakeRTCRtpTransceiver
-    : public blink::WebRTCRtpTransceiver {
+class FakeRTCRtpTransceiver : public blink::WebRTCRtpTransceiver {
  public:
   FakeRTCRtpTransceiver(
       base::Optional<std::string> mid,
diff --git a/content/renderer/media/webrtc/peer_connection_remote_audio_source.cc b/content/renderer/media/webrtc/peer_connection_remote_audio_source.cc
index 5ee6a65..b15c915 100644
--- a/content/renderer/media/webrtc/peer_connection_remote_audio_source.cc
+++ b/content/renderer/media/webrtc/peer_connection_remote_audio_source.cc
@@ -62,7 +62,8 @@
 PeerConnectionRemoteAudioSource::PeerConnectionRemoteAudioSource(
     scoped_refptr<webrtc::AudioTrackInterface> track_interface,
     scoped_refptr<base::SingleThreadTaskRunner> task_runner)
-    : blink::MediaStreamAudioSource(task_runner, false /* is_local_source */),
+    : blink::MediaStreamAudioSource(std::move(task_runner),
+                                    false /* is_local_source */),
       track_interface_(std::move(track_interface)),
       is_sink_of_peer_connection_(false) {
   DCHECK(track_interface_);
diff --git a/content/renderer/media/webrtc/peer_connection_remote_audio_source.h b/content/renderer/media/webrtc/peer_connection_remote_audio_source.h
index cc35e94..69d5e3f 100644
--- a/content/renderer/media/webrtc/peer_connection_remote_audio_source.h
+++ b/content/renderer/media/webrtc/peer_connection_remote_audio_source.h
@@ -58,7 +58,7 @@
     : public blink::MediaStreamAudioSource,
       protected webrtc::AudioTrackSinkInterface {
  public:
-  explicit PeerConnectionRemoteAudioSource(
+  PeerConnectionRemoteAudioSource(
       scoped_refptr<webrtc::AudioTrackInterface> track_interface,
       scoped_refptr<base::SingleThreadTaskRunner> task_runner);
   ~PeerConnectionRemoteAudioSource() final;
diff --git a/content/renderer/media_capture_from_element/html_audio_element_capturer_source.cc b/content/renderer/media_capture_from_element/html_audio_element_capturer_source.cc
index 2e8c7b17..8d42c93 100644
--- a/content/renderer/media_capture_from_element/html_audio_element_capturer_source.cc
+++ b/content/renderer/media_capture_from_element/html_audio_element_capturer_source.cc
@@ -4,6 +4,8 @@
 
 #include "content/renderer/media_capture_from_element/html_audio_element_capturer_source.h"
 
+#include <utility>
+
 #include "base/bind.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "media/base/audio_parameters.h"
@@ -23,13 +25,14 @@
   return new HtmlAudioElementCapturerSource(
       static_cast<media::WebAudioSourceProviderImpl*>(
           player->GetAudioSourceProvider()),
-      task_runner);
+      std::move(task_runner));
 }
 
 HtmlAudioElementCapturerSource::HtmlAudioElementCapturerSource(
     media::WebAudioSourceProviderImpl* audio_source,
     scoped_refptr<base::SingleThreadTaskRunner> task_runner)
-    : blink::MediaStreamAudioSource(task_runner, true /* is_local_source */),
+    : blink::MediaStreamAudioSource(std::move(task_runner),
+                                    true /* is_local_source */),
       audio_source_(audio_source),
       is_started_(false),
       last_sample_rate_(0),
diff --git a/content/renderer/media_capture_from_element/html_audio_element_capturer_source.h b/content/renderer/media_capture_from_element/html_audio_element_capturer_source.h
index e34fc38a..62f56b7 100644
--- a/content/renderer/media_capture_from_element/html_audio_element_capturer_source.h
+++ b/content/renderer/media_capture_from_element/html_audio_element_capturer_source.h
@@ -33,7 +33,7 @@
       blink::WebMediaPlayer* player,
       scoped_refptr<base::SingleThreadTaskRunner> task_runner);
 
-  explicit HtmlAudioElementCapturerSource(
+  HtmlAudioElementCapturerSource(
       media::WebAudioSourceProviderImpl* audio_source,
       scoped_refptr<base::SingleThreadTaskRunner> task_runner);
   ~HtmlAudioElementCapturerSource() override;
diff --git a/content/renderer/media_stream_utils.cc b/content/renderer/media_stream_utils.cc
index f0f8af8..fac0a0d 100644
--- a/content/renderer/media_stream_utils.cc
+++ b/content/renderer/media_stream_utils.cc
@@ -11,7 +11,6 @@
 #include "base/guid.h"
 #include "base/rand_util.h"
 #include "base/strings/utf_string_conversions.h"
-#include "content/renderer/media/stream/external_media_stream_audio_source.h"
 #include "content/renderer/media/stream/media_stream_video_capturer_source.h"
 #include "media/base/audio_capturer_source.h"
 #include "media/capture/video_capturer_source.h"
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index cd2729c..f014139 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -4419,6 +4419,10 @@
   GetLocalRootRenderWidget()->SetMouseCapture(capture);
 }
 
+void RenderFrameImpl::SetNeedsOcclusionTracking(bool needs_tracking) {
+  Send(new FrameHostMsg_SetNeedsOcclusionTracking(routing_id_, needs_tracking));
+}
+
 bool RenderFrameImpl::ShouldReportDetailedMessageForSource(
     const blink::WebString& source) {
   return GetContentClient()->renderer()->ShouldReportDetailedMessageForSource(
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index ba83f18..3115482 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -714,6 +714,7 @@
   void UpdateUserActivationState(
       blink::UserActivationUpdateType update_type) override;
   void SetHasReceivedUserGestureBeforeNavigation(bool value) override;
+  void SetNeedsOcclusionTracking(bool needs_tracking) override;
   void SetMouseCapture(bool capture) override;
   bool ShouldReportDetailedMessageForSource(
       const blink::WebString& source) override;
diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc
index 353e5da..02458b3 100644
--- a/content/renderer/render_frame_proxy.cc
+++ b/content/renderer/render_frame_proxy.cc
@@ -223,7 +223,8 @@
       // TODO(samans): Investigate if it is safe to delay creation of this
       // object until a FrameSinkId is provided.
       parent_local_surface_id_allocator_(
-          std::make_unique<viz::ParentLocalSurfaceIdAllocator>()) {
+          std::make_unique<viz::ParentLocalSurfaceIdAllocator>()),
+      last_occlusion_state_(blink::kUnknownOcclusionState) {
   std::pair<RoutingIDProxyMap::iterator, bool> result =
       g_routing_id_proxy_map.Get().insert(std::make_pair(routing_id_, this));
   CHECK(result.second) << "Inserting a duplicate item.";
@@ -429,6 +430,8 @@
     IPC_MESSAGE_HANDLER(FrameMsg_ForwardResourceTimingToParent,
                         OnForwardResourceTimingToParent)
     IPC_MESSAGE_HANDLER(FrameMsg_DispatchLoad, OnDispatchLoad)
+    IPC_MESSAGE_HANDLER(FrameMsg_SetNeedsOcclusionTracking,
+                        OnSetNeedsOcclusionTracking)
     IPC_MESSAGE_HANDLER(FrameMsg_Collapse, OnCollapse)
     IPC_MESSAGE_HANDLER(FrameMsg_DidUpdateName, OnDidUpdateName)
     IPC_MESSAGE_HANDLER(FrameMsg_AddContentSecurityPolicies,
@@ -540,6 +543,10 @@
   web_frame_->DispatchLoadEventForFrameOwner();
 }
 
+void RenderFrameProxy::OnSetNeedsOcclusionTracking(bool needs_tracking) {
+  web_frame_->SetNeedsOcclusionTracking(needs_tracking);
+}
+
 void RenderFrameProxy::OnCollapse(bool collapsed) {
   web_frame_->Collapse(collapsed);
 }
@@ -740,7 +747,7 @@
   gfx::Rect new_compositor_visible_rect = web_frame_->GetCompositingRect();
   if (new_compositor_visible_rect != last_compositor_visible_rect_)
     UpdateRemoteViewportIntersection(last_intersection_rect_,
-                                     last_occluded_or_obscured_);
+                                     last_occlusion_state_);
 }
 
 void RenderFrameProxy::OnSetHasReceivedUserGestureBeforeNavigation(bool value) {
@@ -876,13 +883,13 @@
 
 void RenderFrameProxy::UpdateRemoteViewportIntersection(
     const blink::WebRect& viewport_intersection,
-    bool occluded_or_obscured) {
+    blink::FrameOcclusionState occlusion_state) {
   last_intersection_rect_ = viewport_intersection;
   last_compositor_visible_rect_ = web_frame_->GetCompositingRect();
-  last_occluded_or_obscured_ = occluded_or_obscured;
+  last_occlusion_state_ = occlusion_state;
   Send(new FrameHostMsg_UpdateViewportIntersection(
       routing_id_, gfx::Rect(viewport_intersection),
-      last_compositor_visible_rect_, last_occluded_or_obscured_));
+      last_compositor_visible_rect_, last_occlusion_state_));
 }
 
 void RenderFrameProxy::VisibilityChanged(
diff --git a/content/renderer/render_frame_proxy.h b/content/renderer/render_frame_proxy.h
index c0c455d..14106cf 100644
--- a/content/renderer/render_frame_proxy.h
+++ b/content/renderer/render_frame_proxy.h
@@ -208,7 +208,7 @@
                          const blink::WebRect& screen_space_rect) override;
   void UpdateRemoteViewportIntersection(
       const blink::WebRect& viewport_intersection,
-      bool occluded_or_obscured) override;
+      blink::FrameOcclusionState occlusion_state) override;
   void VisibilityChanged(blink::mojom::FrameVisibility visibility) override;
   void SetIsInert(bool) override;
   void SetInheritedEffectiveTouchAction(cc::TouchAction) override;
@@ -253,6 +253,7 @@
   void OnForwardResourceTimingToParent(
       const ResourceTimingInfo& resource_timing);
   void OnDispatchLoad();
+  void OnSetNeedsOcclusionTracking(bool);
   void OnCollapse(bool collapsed);
   void OnDidUpdateName(const std::string& name, const std::string& unique_name);
   void OnAddContentSecurityPolicies(
@@ -334,7 +335,7 @@
 
   gfx::Rect last_intersection_rect_;
   gfx::Rect last_compositor_visible_rect_;
-  bool last_occluded_or_obscured_ = false;
+  blink::FrameOcclusionState last_occlusion_state_;
 
 #if defined(USE_AURA)
   std::unique_ptr<MusEmbeddedFrame> mus_embedded_frame_;
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 0d760d6..3fa6942 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -2086,12 +2086,8 @@
 std::unique_ptr<blink::WebMediaStreamCenter>
 RenderThreadImpl::CreateMediaStreamCenter() {
   DCHECK(main_thread_runner()->BelongsToCurrentThread());
-  std::unique_ptr<blink::WebMediaStreamCenter> media_stream_center;
-  if (!media_stream_center) {
-    media_stream_center =
-        std::make_unique<MediaStreamCenter>(main_thread_runner());
-  }
-  return media_stream_center;
+  // TODO(hajimehoshi): Pass a per-frame task runner if possible.
+  return std::make_unique<MediaStreamCenter>(main_thread_runner());
 }
 
 PeerConnectionDependencyFactory*
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index bab1a37..7f6d8f8e 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -2258,11 +2258,11 @@
 void RenderWidget::OnSetViewportIntersection(
     const gfx::Rect& viewport_intersection,
     const gfx::Rect& compositor_visible_rect,
-    bool occluded_or_obscured) {
+    blink::FrameOcclusionState occlusion_state) {
   if (auto* frame_widget = GetFrameWidget()) {
     compositor_visible_rect_ = compositor_visible_rect;
     frame_widget->SetRemoteViewportIntersection(viewport_intersection,
-                                                occluded_or_obscured);
+                                                occlusion_state);
     layer_tree_view_->SetViewportVisibleRect(ViewportVisibleRect());
   }
 }
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h
index a7dcbd2a..e5f551c 100644
--- a/content/renderer/render_widget.h
+++ b/content/renderer/render_widget.h
@@ -51,6 +51,7 @@
 #include "mojo/public/cpp/bindings/binding.h"
 #include "ppapi/buildflags/buildflags.h"
 #include "services/network/public/mojom/referrer_policy.mojom.h"
+#include "third_party/blink/public/common/frame/occlusion_state.h"
 #include "third_party/blink/public/common/manifest/web_display_mode.h"
 #include "third_party/blink/public/platform/web_input_event.h"
 #include "third_party/blink/public/platform/web_rect.h"
@@ -713,7 +714,7 @@
                            const gfx::Rect& window_screen_rect);
   void OnSetViewportIntersection(const gfx::Rect& viewport_intersection,
                                  const gfx::Rect& compositor_visible_rect,
-                                 bool occluded_or_obscured);
+                                 blink::FrameOcclusionState occlusion_state);
   void OnSetIsInert(bool);
   void OnSetInheritedEffectiveTouchAction(cc::TouchAction touch_action);
   void OnUpdateRenderThrottlingStatus(bool is_throttled,
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc
index 94928c18..c7f4798 100644
--- a/content/renderer/renderer_blink_platform_impl.cc
+++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -773,7 +773,7 @@
   AddVideoTrackToMediaStream(
       HtmlVideoElementCapturerSource::CreateFromWebMediaPlayerImpl(
           web_media_player, content::RenderThread::Get()->GetIOTaskRunner(),
-          task_runner),
+          std::move(task_runner)),
       false,  // is_remote
       web_media_stream);
 }
@@ -796,7 +796,7 @@
 
   blink::MediaStreamAudioSource* const media_stream_source =
       HtmlAudioElementCapturerSource::CreateFromWebMediaPlayerImpl(
-          web_media_player, task_runner);
+          web_media_player, std::move(task_runner));
 
   // Takes ownership of |media_stream_source|.
   web_media_stream_source.SetPlatformSource(
diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc
index 0e48435..e7758714 100644
--- a/content/renderer/service_worker/service_worker_context_client.cc
+++ b/content/renderer/service_worker/service_worker_context_client.cc
@@ -57,7 +57,6 @@
 #include "third_party/blink/public/mojom/blob/blob_registry.mojom.h"
 #include "third_party/blink/public/mojom/service_worker/service_worker.mojom.h"
 #include "third_party/blink/public/mojom/service_worker/service_worker_client.mojom.h"
-#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
 #include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
 #include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
 #include "third_party/blink/public/platform/interface_provider.h"
@@ -186,18 +185,17 @@
   return true;
 }
 
-// Creates a callback which takes an |event_id|, which calls the given event's
-// callback with ABORTED status and removes it from |map|.
+// Creates a callback which takes an |event_id| and |status|, which calls the
+// given event's callback with the given status and removes it from |map|.
 template <typename MapType, typename... Args>
-base::OnceCallback<void(int /* event_id */)> CreateAbortCallback(MapType* map,
-                                                                 Args... args) {
+ServiceWorkerTimeoutTimer::AbortCallback CreateAbortCallback(MapType* map,
+                                                             Args... args) {
   return base::BindOnce(
-      [](MapType* map, Args... args, int event_id) {
+      [](MapType* map, Args... args, int event_id,
+         blink::mojom::ServiceWorkerEventStatus status) {
         auto iter = map->find(event_id);
         CHECK(iter != map->end());
-        std::move(iter->second)
-            .Run(blink::mojom::ServiceWorkerEventStatus::ABORTED,
-                 std::forward<Args>(args)...);
+        std::move(iter->second).Run(status, std::forward<Args>(args)...);
         map->erase(iter);
       },
       map, std::forward<Args>(args)...);
@@ -1630,7 +1628,6 @@
 
 void ServiceWorkerContextClient::SetIdleTimerDelayToZero() {
   CHECK(worker_task_runner_->RunsTasksInCurrentSequence());
-  CHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
   CHECK(context_);
   CHECK(context_->timeout_timer);
   context_->timeout_timer->SetIdleTimerDelayToZero();
@@ -1661,7 +1658,6 @@
 void ServiceWorkerContextClient::OnRequestedTermination(
     bool will_be_terminated) {
   CHECK(worker_task_runner_->RunsTasksInCurrentSequence());
-  CHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
   CHECK(context_);
   CHECK(context_->timeout_timer);
   RecordDebugLog(will_be_terminated ? "OnRequestedTermination/Y"
diff --git a/content/renderer/service_worker/service_worker_subresource_loader.cc b/content/renderer/service_worker/service_worker_subresource_loader.cc
index 915c239..4d85038 100644
--- a/content/renderer/service_worker/service_worker_subresource_loader.cc
+++ b/content/renderer/service_worker/service_worker_subresource_loader.cc
@@ -299,6 +299,7 @@
       // promise, and handle this request.
       break;
     case blink::mojom::ServiceWorkerEventStatus::ABORTED:
+    case blink::mojom::ServiceWorkerEventStatus::TIMEOUT:
       // Fetch event dispatch did not complete, possibly due to timeout of
       // respondWith() or waitUntil(). Return network error.
 
diff --git a/content/renderer/service_worker/service_worker_timeout_timer.cc b/content/renderer/service_worker/service_worker_timeout_timer.cc
index 33a8833..20b9292 100644
--- a/content/renderer/service_worker/service_worker_timeout_timer.cc
+++ b/content/renderer/service_worker/service_worker_timeout_timer.cc
@@ -9,8 +9,6 @@
 #include "base/stl_util.h"
 #include "base/time/default_tick_clock.h"
 #include "base/time/time.h"
-#include "services/network/public/cpp/features.h"
-#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
 
 namespace content {
 
@@ -36,7 +34,6 @@
     base::WeakPtr<ServiceWorkerTimeoutTimer> timer)
     : timer_(std::move(timer)) {
   CHECK(timer_);
-  CHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
   timer_->num_of_stay_awake_tokens_++;
 }
 
@@ -69,7 +66,8 @@
   in_dtor_ = true;
   // Abort all callbacks.
   for (auto& event : inflight_events_)
-    std::move(event.abort_callback).Run();
+    std::move(event.abort_callback)
+        .Run(blink::mojom::ServiceWorkerEventStatus::ABORTED);
 }
 
 void ServiceWorkerTimeoutTimer::Start() {
@@ -83,13 +81,12 @@
                                    base::Unretained(this)));
 }
 
-int ServiceWorkerTimeoutTimer::StartEvent(
-    base::OnceCallback<void(int /* event_id */)> abort_callback) {
+int ServiceWorkerTimeoutTimer::StartEvent(AbortCallback abort_callback) {
   return StartEventWithCustomTimeout(std::move(abort_callback), kEventTimeout);
 }
 
 int ServiceWorkerTimeoutTimer::StartEventWithCustomTimeout(
-    base::OnceCallback<void(int /* event_id */)> abort_callback,
+    AbortCallback abort_callback,
     base::TimeDelta timeout) {
   if (did_idle_timeout()) {
     CHECK(!running_pending_tasks_);
@@ -133,40 +130,34 @@
 
 std::unique_ptr<ServiceWorkerTimeoutTimer::StayAwakeToken>
 ServiceWorkerTimeoutTimer::CreateStayAwakeToken() {
-  if (!blink::ServiceWorkerUtils::IsServicificationEnabled())
-    return nullptr;
   return std::make_unique<ServiceWorkerTimeoutTimer::StayAwakeToken>(
       weak_factory_.GetWeakPtr());
 }
 
 void ServiceWorkerTimeoutTimer::PushPendingTask(
     base::OnceClosure pending_task) {
-  CHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
   CHECK(did_idle_timeout());
   pending_tasks_.emplace(std::move(pending_task));
 }
 
 void ServiceWorkerTimeoutTimer::SetIdleTimerDelayToZero() {
-  CHECK(blink::ServiceWorkerUtils::IsServicificationEnabled());
   zero_idle_timer_delay_ = true;
   if (!HasInflightEvent())
     MaybeTriggerIdleTimer();
 }
 
 void ServiceWorkerTimeoutTimer::UpdateStatus() {
-  if (!blink::ServiceWorkerUtils::IsServicificationEnabled())
-    return;
-
   base::TimeTicks now = tick_clock_->NowTicks();
 
   // Abort all events exceeding |kEventTimeout|.
   auto iter = inflight_events_.begin();
   while (iter != inflight_events_.end() && iter->expiration_time <= now) {
     int event_id = iter->id;
-    base::OnceClosure callback = std::move(iter->abort_callback);
+    base::OnceCallback<void(blink::mojom::ServiceWorkerEventStatus)> callback =
+        std::move(iter->abort_callback);
     iter = inflight_events_.erase(iter);
     id_event_map_.erase(event_id);
-    std::move(callback).Run();
+    std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::TIMEOUT);
     // Shut down the worker as soon as possible since the worker may have gone
     // into bad state.
     zero_idle_timer_delay_ = true;
@@ -209,7 +200,8 @@
 ServiceWorkerTimeoutTimer::EventInfo::EventInfo(
     int id,
     base::TimeTicks expiration_time,
-    base::OnceClosure abort_callback)
+    base::OnceCallback<void(blink::mojom::ServiceWorkerEventStatus)>
+        abort_callback)
     : id(id),
       expiration_time(expiration_time),
       abort_callback(std::move(abort_callback)) {}
diff --git a/content/renderer/service_worker/service_worker_timeout_timer.h b/content/renderer/service_worker/service_worker_timeout_timer.h
index 86e1072e..c6ccb31 100644
--- a/content/renderer/service_worker/service_worker_timeout_timer.h
+++ b/content/renderer/service_worker/service_worker_timeout_timer.h
@@ -14,6 +14,7 @@
 #include "base/time/time.h"
 #include "base/timer/timer.h"
 #include "content/common/content_export.h"
+#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
 
 namespace base {
 
@@ -26,12 +27,11 @@
 // ServiceWorkerTimeoutTimer manages two types of timeouts: the long standing
 // event timeout and the idle timeout.
 //
-// S13nServiceWorker:
 // 1) Event timeout: when an event starts, StartEvent() records the expiration
 // time of the event (kEventTimeout). If EndEvent() has not been called within
-// the timeout time, |abort_callback| passed to StartEvent() is called. Also,
-// |zero_idle_timer_delay_| is set to true to shut down the worker as soon as
-// possible since the worker may have gone into bad state.
+// the timeout time, |abort_callback| passed to StartEvent() is called with
+// status TIMEOUT. Also, |zero_idle_timer_delay_| is set to true to shut down
+// the worker as soon as possible since the worker may have gone into bad state.
 // 2) Idle timeout: when a certain time has passed (kIdleDelay) since all of
 // events have ended, ServiceWorkerTimeoutTimer calls the |idle_callback|.
 // |idle_callback| will be continuously called at a certain interval
@@ -39,10 +39,7 @@
 //
 // The lifetime of ServiceWorkerTimeoutTimer is the same with the worker
 // thread. If ServiceWorkerTimeoutTimer is destructed while there are inflight
-// events, all |abort_callback|s will be immediately called.
-//
-// Non-S13nServiceWorker:
-// Does nothing except calls the abort callbacks upon destruction.
+// events, all |abort_callback|s will be immediately called with status ABORTED.
 class CONTENT_EXPORT ServiceWorkerTimeoutTimer {
  public:
   // A token to keep the timeout timer from going into the idle state if any of
@@ -56,6 +53,10 @@
     base::WeakPtr<ServiceWorkerTimeoutTimer> timer_;
   };
 
+  using AbortCallback =
+      base::OnceCallback<void(int /* event_id */,
+                              blink::mojom::ServiceWorkerEventStatus)>;
+
   explicit ServiceWorkerTimeoutTimer(base::RepeatingClosure idle_callback);
   // For testing.
   ServiceWorkerTimeoutTimer(base::RepeatingClosure idle_callback,
@@ -71,12 +72,11 @@
   // If there are pending tasks queued by PushPendingTask(), they will
   // run in order synchronouslly in StartEvent().
   // See the class comment to know when |abort_callback| runs.
-  int StartEvent(base::OnceCallback<void(int /* event_id */)> abort_callback);
+  int StartEvent(AbortCallback abort_callback);
   // This is basically the same as StartEvent, but you can customize the
   // timeout time until |abort_callback| runs by |timeout|.
-  int StartEventWithCustomTimeout(
-      base::OnceCallback<void(int /* event_id */)> abort_callback,
-      base::TimeDelta timeout);
+  int StartEventWithCustomTimeout(AbortCallback abort_callback,
+                                  base::TimeDelta timeout);
 
   void EndEvent(int event_id);
 
@@ -133,14 +133,16 @@
   struct EventInfo {
     EventInfo(int id,
               base::TimeTicks expiration_time,
-              base::OnceClosure abort_callback);
+              base::OnceCallback<void(blink::mojom::ServiceWorkerEventStatus)>
+                  abort_callback);
     ~EventInfo();
     // Compares |expiration_time|, or |id| if |expiration_time| is the same.
     bool operator<(const EventInfo& other) const;
 
     const int id;
     const base::TimeTicks expiration_time;
-    mutable base::OnceClosure abort_callback;
+    mutable base::OnceCallback<void(blink::mojom::ServiceWorkerEventStatus)>
+        abort_callback;
   };
 
   // For long standing event timeouts. Ordered by expiration time.
diff --git a/content/renderer/service_worker/service_worker_timeout_timer_unittest.cc b/content/renderer/service_worker/service_worker_timeout_timer_unittest.cc
index 86c69341..253903cd 100644
--- a/content/renderer/service_worker/service_worker_timeout_timer_unittest.cc
+++ b/content/renderer/service_worker/service_worker_timeout_timer_unittest.cc
@@ -10,12 +10,11 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "base/message_loop/message_loop.h"
-#include "base/test/scoped_feature_list.h"
+#include "base/optional.h"
 #include "base/test/test_mock_time_task_runner.h"
 #include "base/time/tick_clock.h"
-#include "services/network/public/cpp/features.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
+#include "third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom.h"
 
 namespace content {
 
@@ -25,23 +24,25 @@
  public:
   MockEvent() : weak_factory_(this) {}
 
-  base::OnceCallback<void(int)> CreateAbortCallback() {
-    EXPECT_FALSE(has_aborted_);
+  ServiceWorkerTimeoutTimer::AbortCallback CreateAbortCallback() {
     return base::BindOnce(&MockEvent::Abort, weak_factory_.GetWeakPtr());
   }
 
   int event_id() const { return event_id_; }
   void set_event_id(int event_id) { event_id_ = event_id; }
-  bool has_aborted() const { return has_aborted_; }
-
- private:
-  void Abort(int event_id) {
-    EXPECT_EQ(event_id_, event_id);
-    has_aborted_ = true;
+  const base::Optional<blink::mojom::ServiceWorkerEventStatus>& status() const {
+    return status_;
   }
 
-  bool has_aborted_ = false;
+ private:
+  void Abort(int event_id, blink::mojom::ServiceWorkerEventStatus status) {
+    EXPECT_EQ(event_id_, event_id);
+    EXPECT_FALSE(status_.has_value());
+    status_ = status;
+  }
+
   int event_id_ = 0;
+  base::Optional<blink::mojom::ServiceWorkerEventStatus> status_;
   base::WeakPtrFactory<MockEvent> weak_factory_;
 };
 
@@ -62,12 +63,12 @@
         const int event_id = timer->StartEvent(event.CreateAbortCallback());
         event.set_event_id(event_id);
         EXPECT_FALSE(timer->did_idle_timeout());
-        EXPECT_FALSE(event.has_aborted());
+        EXPECT_FALSE(event.status().has_value());
 
         out_tags->emplace_back(std::move(tag));
 
         timer->EndEvent(event_id);
-        EXPECT_FALSE(event.has_aborted());
+        EXPECT_FALSE(event.status().has_value());
       },
       timer, std::move(tag), out_tags);
 }
@@ -84,30 +85,19 @@
     message_loop_.SetTaskRunner(task_runner_);
   }
 
-  void EnableServicification() {
-    feature_list_.InitWithFeatures({network::features::kNetworkService}, {});
-    ASSERT_TRUE(blink::ServiceWorkerUtils::IsServicificationEnabled());
-  }
-
   base::TestMockTimeTaskRunner* task_runner() { return task_runner_.get(); }
 
  private:
   base::MessageLoop message_loop_;
   scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
-  base::test::ScopedFeatureList feature_list_;
 };
 
 TEST_F(ServiceWorkerTimeoutTimerTest, IdleTimer) {
-  EnableServicification();
-
   const base::TimeDelta kIdleInterval =
       ServiceWorkerTimeoutTimer::kIdleDelay +
       ServiceWorkerTimeoutTimer::kUpdateInterval +
       base::TimeDelta::FromSeconds(1);
 
-  base::RepeatingCallback<void(int)> do_nothing_callback =
-      base::BindRepeating([](int) {});
-
   bool is_idle = false;
   ServiceWorkerTimeoutTimer timer(CreateReceiverWithCalledFlag(&is_idle),
                                   task_runner()->GetMockTickClock());
@@ -121,12 +111,12 @@
   EXPECT_TRUE(is_idle);
 
   is_idle = false;
-  int event_id_1 = timer.StartEvent(do_nothing_callback);
+  int event_id_1 = timer.StartEvent(base::DoNothing());
   task_runner()->FastForwardBy(kIdleInterval);
   // Nothing happens since there is an inflight event.
   EXPECT_FALSE(is_idle);
 
-  int event_id_2 = timer.StartEvent(do_nothing_callback);
+  int event_id_2 = timer.StartEvent(base::DoNothing());
   task_runner()->FastForwardBy(kIdleInterval);
   // Nothing happens since there are two inflight events.
   EXPECT_FALSE(is_idle);
@@ -142,7 +132,7 @@
   EXPECT_TRUE(is_idle);
 
   is_idle = false;
-  int event_id_3 = timer.StartEvent(do_nothing_callback);
+  int event_id_3 = timer.StartEvent(base::DoNothing());
   task_runner()->FastForwardBy(kIdleInterval);
   // Nothing happens since there is an inflight event.
   EXPECT_FALSE(is_idle);
@@ -162,8 +152,6 @@
 }
 
 TEST_F(ServiceWorkerTimeoutTimerTest, InflightEventBeforeStart) {
-  EnableServicification();
-
   const base::TimeDelta kIdleInterval =
       ServiceWorkerTimeoutTimer::kIdleDelay +
       ServiceWorkerTimeoutTimer::kUpdateInterval +
@@ -180,13 +168,11 @@
 }
 
 TEST_F(ServiceWorkerTimeoutTimerTest, EventTimer) {
-  EnableServicification();
-
   ServiceWorkerTimeoutTimer timer(base::DoNothing(),
                                   task_runner()->GetMockTickClock());
   timer.Start();
-  MockEvent event1, event2;
 
+  MockEvent event1, event2;
   int event_id1 = timer.StartEvent(event1.CreateAbortCallback());
   int event_id2 = timer.StartEvent(event2.CreateAbortCallback());
   event1.set_event_id(event_id1);
@@ -194,19 +180,19 @@
   task_runner()->FastForwardBy(ServiceWorkerTimeoutTimer::kUpdateInterval +
                                base::TimeDelta::FromSeconds(1));
 
-  EXPECT_FALSE(event1.has_aborted());
-  EXPECT_FALSE(event2.has_aborted());
+  EXPECT_FALSE(event1.status().has_value());
+  EXPECT_FALSE(event2.status().has_value());
   timer.EndEvent(event1.event_id());
   task_runner()->FastForwardBy(ServiceWorkerTimeoutTimer::kEventTimeout +
                                base::TimeDelta::FromSeconds(1));
 
-  EXPECT_FALSE(event1.has_aborted());
-  EXPECT_TRUE(event2.has_aborted());
+  EXPECT_FALSE(event1.status().has_value());
+  EXPECT_TRUE(event2.status().has_value());
+  EXPECT_EQ(blink::mojom::ServiceWorkerEventStatus::TIMEOUT,
+            event2.status().value());
 }
 
 TEST_F(ServiceWorkerTimeoutTimerTest, CustomTimeouts) {
-  EnableServicification();
-
   ServiceWorkerTimeoutTimer timer(base::DoNothing(),
                                   task_runner()->GetMockTickClock());
   timer.Start();
@@ -223,18 +209,20 @@
   task_runner()->FastForwardBy(ServiceWorkerTimeoutTimer::kUpdateInterval +
                                base::TimeDelta::FromSeconds(1));
 
-  EXPECT_TRUE(event1.has_aborted());
-  EXPECT_FALSE(event2.has_aborted());
+  EXPECT_TRUE(event1.status().has_value());
+  EXPECT_FALSE(event2.status().has_value());
+  EXPECT_EQ(blink::mojom::ServiceWorkerEventStatus::TIMEOUT,
+            event1.status().value());
   task_runner()->FastForwardBy(ServiceWorkerTimeoutTimer::kUpdateInterval +
                                base::TimeDelta::FromSeconds(1));
 
-  EXPECT_TRUE(event1.has_aborted());
-  EXPECT_TRUE(event2.has_aborted());
+  EXPECT_TRUE(event1.status().has_value());
+  EXPECT_TRUE(event2.status().has_value());
+  EXPECT_EQ(blink::mojom::ServiceWorkerEventStatus::TIMEOUT,
+            event2.status().value());
 }
 
 TEST_F(ServiceWorkerTimeoutTimerTest, BecomeIdleAfterAbort) {
-  EnableServicification();
-
   bool is_idle = false;
   ServiceWorkerTimeoutTimer timer(CreateReceiverWithCalledFlag(&is_idle),
                                   task_runner()->GetMockTickClock());
@@ -249,13 +237,11 @@
 
   // |event| should have been aborted, and at the same time, the idle timeout
   // should also be fired since there has been an aborted event.
-  EXPECT_TRUE(event.has_aborted());
+  EXPECT_TRUE(event.status().has_value());
   EXPECT_TRUE(is_idle);
 }
 
 TEST_F(ServiceWorkerTimeoutTimerTest, AbortAllOnDestruction) {
-  EnableServicification();
-
   MockEvent event1, event2;
   {
     ServiceWorkerTimeoutTimer timer(base::DoNothing(),
@@ -269,16 +255,19 @@
     task_runner()->FastForwardBy(ServiceWorkerTimeoutTimer::kUpdateInterval +
                                  base::TimeDelta::FromSeconds(1));
 
-    EXPECT_FALSE(event1.has_aborted());
-    EXPECT_FALSE(event2.has_aborted());
+    EXPECT_FALSE(event1.status().has_value());
+    EXPECT_FALSE(event2.status().has_value());
   }
 
-  EXPECT_TRUE(event1.has_aborted());
-  EXPECT_TRUE(event2.has_aborted());
+  EXPECT_TRUE(event1.status().has_value());
+  EXPECT_EQ(blink::mojom::ServiceWorkerEventStatus::ABORTED,
+            event1.status().value());
+  EXPECT_TRUE(event2.status().has_value());
+  EXPECT_EQ(blink::mojom::ServiceWorkerEventStatus::ABORTED,
+            event2.status().value());
 }
 
 TEST_F(ServiceWorkerTimeoutTimerTest, PushPendingTask) {
-  EnableServicification();
   ServiceWorkerTimeoutTimer timer(base::DoNothing(),
                                   task_runner()->GetMockTickClock());
   timer.Start();
@@ -301,7 +290,6 @@
 // Test that pending tasks are run when StartEvent() is called while there the
 // idle timer delay is zero. Regression test for https://crbug.com/878608.
 TEST_F(ServiceWorkerTimeoutTimerTest, RunPendingTasksWithZeroIdleTimerDelay) {
-  EnableServicification();
   ServiceWorkerTimeoutTimer timer(base::DoNothing(),
                                   task_runner()->GetMockTickClock());
   timer.Start();
@@ -325,7 +313,6 @@
 }
 
 TEST_F(ServiceWorkerTimeoutTimerTest, SetIdleTimerDelayToZero) {
-  EnableServicification();
   {
     bool is_idle = false;
     ServiceWorkerTimeoutTimer timer(CreateReceiverWithCalledFlag(&is_idle),
@@ -343,7 +330,7 @@
     ServiceWorkerTimeoutTimer timer(CreateReceiverWithCalledFlag(&is_idle),
                                     task_runner()->GetMockTickClock());
     timer.Start();
-    int event_id = timer.StartEvent(base::BindOnce([](int) {}));
+    int event_id = timer.StartEvent(base::DoNothing());
     timer.SetIdleTimerDelayToZero();
     // Nothing happens since there is an inflight event.
     EXPECT_FALSE(is_idle);
@@ -358,8 +345,8 @@
     ServiceWorkerTimeoutTimer timer(CreateReceiverWithCalledFlag(&is_idle),
                                     task_runner()->GetMockTickClock());
     timer.Start();
-    int event_id_1 = timer.StartEvent(base::BindOnce([](int) {}));
-    int event_id_2 = timer.StartEvent(base::BindOnce([](int) {}));
+    int event_id_1 = timer.StartEvent(base::DoNothing());
+    int event_id_2 = timer.StartEvent(base::DoNothing());
     timer.SetIdleTimerDelayToZero();
     // Nothing happens since there are two inflight events.
     EXPECT_FALSE(is_idle);
@@ -395,39 +382,4 @@
   }
 }
 
-TEST_F(ServiceWorkerTimeoutTimerTest, NonS13nServiceWorker) {
-  if (blink::ServiceWorkerUtils::IsServicificationEnabled())
-    return;
-
-  MockEvent event;
-  {
-    bool is_idle = false;
-    ServiceWorkerTimeoutTimer timer(
-        base::BindRepeating([](bool* out_is_idle) { *out_is_idle = true; },
-                            &is_idle),
-        task_runner()->GetMockTickClock());
-    timer.Start();
-
-    int event_id = timer.StartEvent(event.CreateAbortCallback());
-    event.set_event_id(event_id);
-    task_runner()->FastForwardBy(ServiceWorkerTimeoutTimer::kEventTimeout +
-                                 ServiceWorkerTimeoutTimer::kUpdateInterval +
-                                 base::TimeDelta::FromSeconds(1));
-
-    // Timed out events  should *NOT* be aborted in non-S13nServiceWorker.
-    EXPECT_FALSE(event.has_aborted());
-    EXPECT_FALSE(is_idle);
-
-    task_runner()->FastForwardBy(ServiceWorkerTimeoutTimer::kIdleDelay +
-                                 ServiceWorkerTimeoutTimer::kUpdateInterval +
-                                 base::TimeDelta::FromSeconds(1));
-
-    // |idle_callback| should *NOT* be fired in non-S13nServiceWorker.
-    EXPECT_FALSE(is_idle);
-  }
-
-  // Events should be aborted when the timer is destructed.
-  EXPECT_TRUE(event.has_aborted());
-}
-
 }  // namespace content
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 523d1cb..8e04544 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -1813,6 +1813,8 @@
     "../renderer/media/stream/webmediaplayer_ms_unittest.cc",
     "../renderer/media/video_capture_impl_manager_unittest.cc",
     "../renderer/media/video_capture_impl_unittest.cc",
+    "../renderer/media/webrtc/fake_rtc_rtp_transceiver.cc",
+    "../renderer/media/webrtc/fake_rtc_rtp_transceiver.h",
     "../renderer/media/webrtc/media_stream_remote_video_source_unittest.cc",
     "../renderer/media/webrtc/media_stream_track_metrics_unittest.cc",
     "../renderer/media/webrtc/media_stream_video_webrtc_sink_unittest.cc",
diff --git a/content/test/data/accessibility/event/add-alert-expected-mac.txt b/content/test/data/accessibility/event/add-alert-expected-mac.txt
index d40a375..a6b1a8ad4 100644
--- a/content/test/data/accessibility/event/add-alert-expected-mac.txt
+++ b/content/test/data/accessibility/event/add-alert-expected-mac.txt
@@ -1,2 +1,6 @@
-AXLiveRegionChanged on AXGroup
-AXLiveRegionCreated on AXGroup
+AXLiveRegionChanged on AXGroup AXDescription="a"
+AXLiveRegionChanged on AXGroup AXDescription="b"
+AXLiveRegionChanged on AXGroup AXDescription="c"
+AXLiveRegionCreated on AXGroup AXDescription="a"
+AXLiveRegionCreated on AXGroup AXDescription="b"
+AXLiveRegionCreated on AXGroup AXDescription="c"
diff --git a/content/test/data/accessibility/event/add-alert-expected-win-uia.txt b/content/test/data/accessibility/event/add-alert-expected-win-uia.txt
new file mode 100644
index 0000000..40b1c89
--- /dev/null
+++ b/content/test/data/accessibility/event/add-alert-expected-win-uia.txt
@@ -0,0 +1,3 @@
+SystemAlert on role=alert, name=a
+SystemAlert on role=alert, name=b
+SystemAlert on role=alert, name=c
diff --git a/content/test/data/accessibility/event/add-alert-expected-win.txt b/content/test/data/accessibility/event/add-alert-expected-win.txt
index 8f349d6..89922a167 100644
--- a/content/test/data/accessibility/event/add-alert-expected-win.txt
+++ b/content/test/data/accessibility/event/add-alert-expected-win.txt
@@ -1 +1,3 @@
-EVENT_SYSTEM_ALERT on <div#a> role=ROLE_SYSTEM_ALERT
+EVENT_SYSTEM_ALERT on <div#a> role=ROLE_SYSTEM_ALERT name="a"
+EVENT_SYSTEM_ALERT on <div#b> role=ROLE_SYSTEM_ALERT name="b"
+EVENT_SYSTEM_ALERT on <div#c> role=ROLE_SYSTEM_ALERT name="c"
diff --git a/content/test/data/accessibility/event/add-alert.html b/content/test/data/accessibility/event/add-alert.html
index 8de948d..8293d3d49 100644
--- a/content/test/data/accessibility/event/add-alert.html
+++ b/content/test/data/accessibility/event/add-alert.html
@@ -1,15 +1,21 @@
 <!--
 @WIN-DENY:*
 @WIN-ALLOW:EVENT_SYSTEM_ALERT*
+@WIN-ALLOW:SystemAlert*
 -->
 <!DOCTYPE html>
 <html>
 <body>
-<div id="a" role="alert" style="display:none">This is an alert</div>
+<div id="a" aria-label="a" role="alert" style="display:none">This is an alert</div>
+<div id="b" aria-label="b" role="alertdialog" aria-live="polite" style="display:none">This is an alert dialog</div>
+<div id="c" aria-label="c" role="alert" aria-hidden="true">This is an alert</div>
+<div id="d" aria-label="d" role="alert" aria-hidden="true">This alert shouldn't fire an event</div>
 <script>
   function go() {
     document.getElementById('a').style.display = "block";
-  }
+    document.getElementById('b').style.display = "block";
+    document.getElementById('c').setAttribute('aria-hidden', 'false');
+}
 </script>
 </body>
 </html>
diff --git a/content/test/data/accessibility/event/aria-combo-box-collapse-expected-win-uia.txt b/content/test/data/accessibility/event/aria-combo-box-collapse-expected-win-uia.txt
index 7500f78..50c9f72 100644
--- a/content/test/data/accessibility/event/aria-combo-box-collapse-expected-win-uia.txt
+++ b/content/test/data/accessibility/event/aria-combo-box-collapse-expected-win-uia.txt
@@ -1 +1 @@
-UIA_AutomationFocusChangedEventId on role=combobox
+AutomationFocusChanged on role=combobox
diff --git a/content/test/data/accessibility/event/aria-combo-box-delay-add-list-expected-win-uia.txt b/content/test/data/accessibility/event/aria-combo-box-delay-add-list-expected-win-uia.txt
index a67bf9cc3..f0904f5 100644
--- a/content/test/data/accessibility/event/aria-combo-box-delay-add-list-expected-win-uia.txt
+++ b/content/test/data/accessibility/event/aria-combo-box-delay-add-list-expected-win-uia.txt
@@ -1 +1 @@
-UIA_AutomationFocusChangedEventId on role=option, name=Apple
+AutomationFocusChanged on role=option, name=Apple
diff --git a/content/test/data/accessibility/event/aria-combo-box-expand-expected-win-uia.txt b/content/test/data/accessibility/event/aria-combo-box-expand-expected-win-uia.txt
index a67bf9cc3..f0904f5 100644
--- a/content/test/data/accessibility/event/aria-combo-box-expand-expected-win-uia.txt
+++ b/content/test/data/accessibility/event/aria-combo-box-expand-expected-win-uia.txt
@@ -1 +1 @@
-UIA_AutomationFocusChangedEventId on role=option, name=Apple
+AutomationFocusChanged on role=option, name=Apple
diff --git a/content/test/data/accessibility/event/aria-combo-box-focus-expected-win-uia.txt b/content/test/data/accessibility/event/aria-combo-box-focus-expected-win-uia.txt
index a67bf9cc3..f0904f5 100644
--- a/content/test/data/accessibility/event/aria-combo-box-focus-expected-win-uia.txt
+++ b/content/test/data/accessibility/event/aria-combo-box-focus-expected-win-uia.txt
@@ -1 +1 @@
-UIA_AutomationFocusChangedEventId on role=option, name=Apple
+AutomationFocusChanged on role=option, name=Apple
diff --git a/content/test/data/accessibility/event/aria-combo-box-next-expected-win-uia.txt b/content/test/data/accessibility/event/aria-combo-box-next-expected-win-uia.txt
index 843f163..2acc20c1 100644
--- a/content/test/data/accessibility/event/aria-combo-box-next-expected-win-uia.txt
+++ b/content/test/data/accessibility/event/aria-combo-box-next-expected-win-uia.txt
@@ -1 +1 @@
-UIA_AutomationFocusChangedEventId on role=option, name=Banana
+AutomationFocusChanged on role=option, name=Banana
diff --git a/content/test/data/accessibility/event/listbox-focus-expected-win-uia.txt b/content/test/data/accessibility/event/listbox-focus-expected-win-uia.txt
index 3789cbf..dab3963 100644
--- a/content/test/data/accessibility/event/listbox-focus-expected-win-uia.txt
+++ b/content/test/data/accessibility/event/listbox-focus-expected-win-uia.txt
@@ -1 +1 @@
-UIA_AutomationFocusChangedEventId on role=listbox
+AutomationFocusChanged on role=listbox
diff --git a/content/test/data/accessibility/event/listbox-next-expected-win-uia.txt b/content/test/data/accessibility/event/listbox-next-expected-win-uia.txt
index 6d7e8a2..8ca35af7 100644
--- a/content/test/data/accessibility/event/listbox-next-expected-win-uia.txt
+++ b/content/test/data/accessibility/event/listbox-next-expected-win-uia.txt
@@ -1 +1 @@
-UIA_AutomationFocusChangedEventId on role=option, name=Orange
+AutomationFocusChanged on role=option, name=Orange
diff --git a/content/test/data/accessibility/event/menulist-focus-expected-win-uia.txt b/content/test/data/accessibility/event/menulist-focus-expected-win-uia.txt
index 7500f78..50c9f72 100644
--- a/content/test/data/accessibility/event/menulist-focus-expected-win-uia.txt
+++ b/content/test/data/accessibility/event/menulist-focus-expected-win-uia.txt
@@ -1 +1 @@
-UIA_AutomationFocusChangedEventId on role=combobox
+AutomationFocusChanged on role=combobox
diff --git a/content/test/data/accessibility/event/report-validity-invalid-field-expected-win-uia.txt b/content/test/data/accessibility/event/report-validity-invalid-field-expected-win-uia.txt
index f8d851a..1a42ba0 100644
--- a/content/test/data/accessibility/event/report-validity-invalid-field-expected-win-uia.txt
+++ b/content/test/data/accessibility/event/report-validity-invalid-field-expected-win-uia.txt
@@ -1 +1 @@
-UIA_AutomationFocusChangedEventId on role=textbox, name=Pet name:
+AutomationFocusChanged on role=textbox, name=Pet name:
diff --git a/content/test/data/accessibility/event/report-validity-invalid-field.html b/content/test/data/accessibility/event/report-validity-invalid-field.html
index 9d0aeec..8bb3f3e 100644
--- a/content/test/data/accessibility/event/report-validity-invalid-field.html
+++ b/content/test/data/accessibility/event/report-validity-invalid-field.html
@@ -3,7 +3,7 @@
 @WIN-ALLOW:EVENT_OBJECT_FOCUS*
 @WIN-ALLOW:EVENT_SYSTEM_ALERT*
 @WIN-ALLOW:EVENT_OBJECT_LIVE*
-@WIN-ALLOW:UIA_AutomationFocusChangedEventId*
+@WIN-ALLOW:AutomationFocusChanged*
 @MAC-DENY:*
 @MAC-ALLOW:AXFocusedUIElementChanged*
 @MAC-ALLOW:AXFocusedUIElementChanged*
diff --git a/content/test/data/accessibility/event/tbody-focus-expected-win-uia.txt b/content/test/data/accessibility/event/tbody-focus-expected-win-uia.txt
index aa3ec43..76912dc 100644
--- a/content/test/data/accessibility/event/tbody-focus-expected-win-uia.txt
+++ b/content/test/data/accessibility/event/tbody-focus-expected-win-uia.txt
@@ -1 +1 @@
-UIA_AutomationFocusChangedEventId on role=group, name=tbody
+AutomationFocusChanged on role=group, name=tbody
diff --git a/content/test/data/accessibility/event/tfoot-focus-expected-win-uia.txt b/content/test/data/accessibility/event/tfoot-focus-expected-win-uia.txt
index 2fd788dc..06e9a988 100644
--- a/content/test/data/accessibility/event/tfoot-focus-expected-win-uia.txt
+++ b/content/test/data/accessibility/event/tfoot-focus-expected-win-uia.txt
@@ -1 +1 @@
-UIA_AutomationFocusChangedEventId on role=group, name=tfoot
+AutomationFocusChanged on role=group, name=tfoot
diff --git a/content/test/data/accessibility/event/thead-focus-expected-win-uia.txt b/content/test/data/accessibility/event/thead-focus-expected-win-uia.txt
index b9af00e..eaaa8d2a 100644
--- a/content/test/data/accessibility/event/thead-focus-expected-win-uia.txt
+++ b/content/test/data/accessibility/event/thead-focus-expected-win-uia.txt
@@ -1 +1 @@
-UIA_AutomationFocusChangedEventId on role=group, name=thead
+AutomationFocusChanged on role=group, name=thead
diff --git a/content/test/data/media/depth_stream_test_utilities.js b/content/test/data/media/depth_stream_test_utilities.js
index c316aba..89298c9 100644
--- a/content/test/data/media/depth_stream_test_utilities.js
+++ b/content/test/data/media/depth_stream_test_utilities.js
@@ -61,12 +61,15 @@
     var i = (width * row + column) * 4;
     var calculated = (data[0] + wrap_around +
                       step * ((flip_y ? -row : row) + column)) % wrap_around;
-    if (Math.abs(calculated - data[i]) > tolerance) {
+    var diff = Math.abs(calculated - data[i]);
+    // We reconstruct the values based on top left value. When the reconstructed
+    // value is near |wrap_around|, read value, data[i], could be wrapped
+    // around, and vice versa - "diff > wrap_around - tolerance", in that case.
+    if (diff >= tolerance && diff <= wrap_around - tolerance) {
       return Promise.reject(test_name + ": reference value " + data[i] +
-          " differs from calculated: " + calculated +
-          " at index (row, column) " + i + " (" + row + ", " + column +
-          "). TopLeft value:" + data[0] + ", step:" + step + ", flip_y:" +
-          flip_y);
+          " differs from calculated: " + calculated + " at index (row, column) "
+          + i + " (" + row + ", " + column + "). TopLeft value:" + data[0] +
+          ", step:" + step + ", flip_y:" + flip_y);
     }
   }
   return true;
diff --git a/content/test/gpu/gpu_tests/depth_capture_expectations.py b/content/test/gpu/gpu_tests/depth_capture_expectations.py
index 812dba5..f2a229e 100644
--- a/content/test/gpu/gpu_tests/depth_capture_expectations.py
+++ b/content/test/gpu/gpu_tests/depth_capture_expectations.py
@@ -17,10 +17,6 @@
                ['linux', ('nvidia', 0x104a)], bug=737410)
     self.Flaky('DepthCapture_depthStreamToRGBAUint8Texture',
                ['linux', ('nvidia', 0x104a)], bug=737410)
-    self.Flaky('DepthCapture_depthStreamToRGBAUint8Texture',
-               ['highsierra', ('amd', 0x6821)], bug=819661)
-    self.Flaky('DepthCapture_depthStreamToRGBAUint8Texture',
-               ['highsierra', ('intel', 0x0a2e)], bug=824438)
     self.Fail('DepthCapture_depthStreamToR32FloatTexture',
               ['android', ('qualcomm', 'Adreno (TM) 330')], bug=765913)
     self.Flaky('DepthCapture_depthStreamToR32FloatTexture',
diff --git a/content/utility/utility_service_factory.cc b/content/utility/utility_service_factory.cc
index b8bc22e6..a122c03 100644
--- a/content/utility/utility_service_factory.cc
+++ b/content/utility/utility_service_factory.cc
@@ -114,29 +114,30 @@
 
 UtilityServiceFactory::~UtilityServiceFactory() {}
 
-bool UtilityServiceFactory::HandleServiceRequest(
-    const std::string& name,
-    service_manager::mojom::ServiceRequest request) {
+void UtilityServiceFactory::RunService(
+    const std::string& service_name,
+    mojo::PendingReceiver<service_manager::mojom::Service> receiver) {
+  auto request = service_manager::mojom::ServiceRequest(std::move(receiver));
   auto* trace_log = base::trace_event::TraceLog::GetInstance();
   if (trace_log->IsProcessNameEmpty())
-    trace_log->set_process_name("Service: " + name);
+    trace_log->set_process_name("Service: " + service_name);
 
-  static auto* service_name = base::debug::AllocateCrashKeyString(
+  static auto* service_name_crash_key = base::debug::AllocateCrashKeyString(
       "service-name", base::debug::CrashKeySize::Size32);
-  base::debug::SetCrashKeyString(service_name, name);
+  base::debug::SetCrashKeyString(service_name_crash_key, service_name);
 
   std::unique_ptr<service_manager::Service> service;
-  if (name == audio::mojom::kServiceName) {
+  if (service_name == audio::mojom::kServiceName) {
     service = CreateAudioService(std::move(request));
-  } else if (name == data_decoder::mojom::kServiceName) {
+  } else if (service_name == data_decoder::mojom::kServiceName) {
     content::UtilityThread::Get()->EnsureBlinkInitialized();
     service =
         std::make_unique<data_decoder::DataDecoderService>(std::move(request));
-  } else if (name == tracing::mojom::kServiceName &&
+  } else if (service_name == tracing::mojom::kServiceName &&
              !base::FeatureList::IsEnabled(
                  features::kTracingServiceInProcess)) {
     service = std::make_unique<tracing::TracingService>(std::move(request));
-  } else if (name == mojom::kNetworkServiceName &&
+  } else if (service_name == mojom::kNetworkServiceName &&
              base::FeatureList::IsEnabled(network::features::kNetworkService)) {
     // Unlike other services supported by the utility process, the network
     // service runs on the IO thread and never self-terminates.
@@ -147,15 +148,15 @@
         base::BindOnce(&UtilityServiceFactory::RunNetworkServiceOnIOThread,
                        base::Unretained(this), std::move(request),
                        base::SequencedTaskRunnerHandle::Get()));
-    return true;
-  } else if (name == video_capture::mojom::kServiceName) {
+    return;
+  } else if (service_name == video_capture::mojom::kServiceName) {
     service = std::make_unique<video_capture::ServiceImpl>(
         std::move(request), base::ThreadTaskRunnerHandle::Get());
-  } else if (name == viz::mojom::kVizServiceName) {
+  } else if (service_name == viz::mojom::kVizServiceName) {
     service = std::make_unique<viz::Service>(std::move(request));
   }
 #if BUILDFLAG(ENABLE_LIBRARY_CDMS)
-  else if (name == media::mojom::kCdmServiceName) {
+  else if (service_name == media::mojom::kCdmServiceName) {
     service = std::make_unique<media::CdmService>(
         std::make_unique<ContentCdmServiceClient>(), std::move(request));
   }
@@ -166,14 +167,16 @@
         std::move(service),
         base::BindOnce(&UtilityThread::ReleaseProcess,
                        base::Unretained(UtilityThread::Get())));
-    return true;
+    return;
   }
 
-  return GetContentClient()->utility()->HandleServiceRequest(
-      name, std::move(request));
-}
+  if (GetContentClient()->utility()->HandleServiceRequest(service_name,
+                                                          std::move(request))) {
+    return;
+  }
 
-void UtilityServiceFactory::OnLoadFailed() {
+  // Nothing knew how to handle this request. Complain loudly and die.
+  LOG(ERROR) << "Ignoring request to start unknown service: " << service_name;
   UtilityThreadImpl* utility_thread =
       static_cast<UtilityThreadImpl*>(UtilityThread::Get());
   utility_thread->Shutdown();
diff --git a/content/utility/utility_service_factory.h b/content/utility/utility_service_factory.h
index 6faa61e9..129b2d0 100644
--- a/content/utility/utility_service_factory.h
+++ b/content/utility/utility_service_factory.h
@@ -11,28 +11,24 @@
 #include "base/macros.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/sequenced_task_runner.h"
-#include "content/child/service_factory.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "services/service_manager/public/cpp/binder_registry.h"
 #include "services/service_manager/public/cpp/service.h"
 #include "services/service_manager/public/mojom/service.mojom.h"
 
 namespace content {
 
-// Customization of ServiceFactory for the utility process. Exposed to the
-// browser via the utility process's InterfaceRegistry.
-class UtilityServiceFactory : public ServiceFactory {
+// Helper for handling incoming RunService requests on UtilityThreadImpl.
+class UtilityServiceFactory {
  public:
   UtilityServiceFactory();
-  ~UtilityServiceFactory() override;
+  ~UtilityServiceFactory();
 
-  // ServiceFactory overrides:
-  bool HandleServiceRequest(
-      const std::string& name,
-      service_manager::mojom::ServiceRequest request) override;
+  void RunService(
+      const std::string& service_name,
+      mojo::PendingReceiver<service_manager::mojom::Service> receiver);
 
  private:
-  void OnLoadFailed() override;
-
   void RunNetworkServiceOnIOThread(
       service_manager::mojom::ServiceRequest service_request,
       scoped_refptr<base::SequencedTaskRunner> main_thread_task_runner);
diff --git a/content/utility/utility_thread_impl.cc b/content/utility/utility_thread_impl.cc
index 80b9da23..1455be2 100644
--- a/content/utility/utility_thread_impl.cc
+++ b/content/utility/utility_thread_impl.cc
@@ -124,10 +124,6 @@
   ChildProcess::current()->AddRefProcess();
 
   auto registry = std::make_unique<service_manager::BinderRegistry>();
-  registry->AddInterface(
-      base::Bind(&UtilityThreadImpl::BindServiceFactoryRequest,
-                 base::Unretained(this)),
-      base::ThreadTaskRunnerHandle::Get());
 #if !defined(OS_ANDROID)
   if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
           service_manager::switches::kNoneSandboxAndElevatedPrivileges)) {
@@ -160,11 +156,11 @@
   return GetContentClient()->utility()->OnMessageReceived(msg);
 }
 
-void UtilityThreadImpl::BindServiceFactoryRequest(
-    service_manager::mojom::ServiceFactoryRequest request) {
+void UtilityThreadImpl::RunService(
+    const std::string& service_name,
+    mojo::PendingReceiver<service_manager::mojom::Service> receiver) {
   DCHECK(service_factory_);
-  service_factory_bindings_.AddBinding(service_factory_.get(),
-                                       std::move(request));
+  service_factory_->RunService(service_name, std::move(receiver));
 }
 
 }  // namespace content
diff --git a/content/utility/utility_thread_impl.h b/content/utility/utility_thread_impl.h
index 8cdafc5..348afb8 100644
--- a/content/utility/utility_thread_impl.h
+++ b/content/utility/utility_thread_impl.h
@@ -12,8 +12,6 @@
 #include "build/build_config.h"
 #include "content/child/child_thread_impl.h"
 #include "content/public/utility/utility_thread.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
-#include "services/service_manager/public/mojom/service_factory.mojom.h"
 #include "third_party/blink/public/platform/platform.h"
 
 namespace content {
@@ -48,22 +46,16 @@
 
   // ChildThreadImpl:
   bool OnControlMessageReceived(const IPC::Message& msg) override;
-
-  // Binds requests to our |service factory_|.
-  void BindServiceFactoryRequest(
-      service_manager::mojom::ServiceFactoryRequest request);
+  void RunService(
+      const std::string& service_name,
+      mojo::PendingReceiver<service_manager::mojom::Service> receiver) override;
 
   // blink::Platform implementation if needed.
   std::unique_ptr<blink::Platform> blink_platform_impl_;
 
-  // service_manager::mojom::ServiceFactory for service_manager::Service
-  // hosting.
+  // Helper to handle incoming RunService calls.
   std::unique_ptr<UtilityServiceFactory> service_factory_;
 
-  // Bindings to the service_manager::mojom::ServiceFactory impl.
-  mojo::BindingSet<service_manager::mojom::ServiceFactory>
-      service_factory_bindings_;
-
   DISALLOW_COPY_AND_ASSIGN(UtilityThreadImpl);
 };
 
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn
index 23a6576..096ffaf 100644
--- a/gpu/BUILD.gn
+++ b/gpu/BUILD.gn
@@ -253,7 +253,12 @@
   ]
 
   if (use_dawn) {
-    sources += [ "ipc/client/webgpu_in_process_context_tests.cc" ]
+    sources += [
+      "command_buffer/tests/webgpu_fence_unittest.cc",
+      "command_buffer/tests/webgpu_test.cc",
+      "command_buffer/tests/webgpu_test.h",
+      "ipc/client/webgpu_in_process_context_tests.cc",
+    ]
   }
 
   defines = [ "GL_GLEXT_PROTOTYPES" ]
@@ -287,6 +292,10 @@
     "//ui/gl/init",
   ]
 
+  if (use_dawn) {
+    deps += [ "//third_party/dawn/src/dawn:libdawn" ]
+  }
+
   libs = []
 
   if (is_android) {
diff --git a/gpu/command_buffer/client/BUILD.gn b/gpu/command_buffer/client/BUILD.gn
index f542cee..c9cfaa7 100644
--- a/gpu/command_buffer/client/BUILD.gn
+++ b/gpu/command_buffer/client/BUILD.gn
@@ -284,6 +284,9 @@
     ":webgpu_interface",
     "//gpu/command_buffer/common:webgpu",
   ]
+  public_deps = [
+    "//third_party/dawn/src/dawn:dawn_headers",
+  ]
   sources = [
     "webgpu_cmd_helper.cc",
     "webgpu_cmd_helper.h",
diff --git a/gpu/command_buffer/client/webgpu_implementation.cc b/gpu/command_buffer/client/webgpu_implementation.cc
index f13f326..66f4f4b 100644
--- a/gpu/command_buffer/client/webgpu_implementation.cc
+++ b/gpu/command_buffer/client/webgpu_implementation.cc
@@ -24,14 +24,32 @@
     TransferBufferInterface* transfer_buffer,
     GpuControl* gpu_control)
     : ImplementationBase(helper, transfer_buffer, gpu_control),
-      helper_(helper) {}
+      helper_(helper),
+#if BUILDFLAG(USE_DAWN)
+      wire_client_(new dawn_wire::WireClient(this)),
+      procs_(wire_client_->GetProcs()),
+#endif
+      c2s_buffer_(helper, transfer_buffer) {
+}
 
 WebGPUImplementation::~WebGPUImplementation() {}
 
 gpu::ContextResult WebGPUImplementation::Initialize(
     const SharedMemoryLimits& limits) {
   TRACE_EVENT0("gpu", "WebGPUImplementation::Initialize");
-  return ImplementationBase::Initialize(limits);
+  auto result = ImplementationBase::Initialize(limits);
+  if (result != gpu::ContextResult::kSuccess) {
+    return result;
+  }
+
+  // TODO(enga): Keep track of how much command space the application is using
+  // and adjust c2s_buffer_size_ accordingly.
+  c2s_buffer_size_ = limits.start_transfer_buffer_size;
+  DCHECK_GT(c2s_buffer_size_, 0u);
+  DCHECK(
+      base::CheckAdd(c2s_buffer_size_, c2s_buffer_size_).IsValid<uint32_t>());
+
+  return gpu::ContextResult::kSuccess;
 }
 
 // ContextSupport implementation.
@@ -149,8 +167,10 @@
 }
 void WebGPUImplementation::OnGpuControlReturnData(
     base::span<const uint8_t> data) {
-  // TODO: Handle return commands
-  NOTIMPLEMENTED();
+#if BUILDFLAG(USE_DAWN)
+  wire_client_->HandleCommands(reinterpret_cast<const char*>(data.data()),
+                               data.size());
+#endif
 }
 
 void WebGPUImplementation::Dummy() {
@@ -160,5 +180,78 @@
   helper_->Flush();
 }
 
+void* WebGPUImplementation::GetCmdSpace(size_t size) {
+  // The buffer size must be initialized before any commands are serialized.
+  if (c2s_buffer_size_ == 0u) {
+    NOTREACHED();
+    return nullptr;
+  }
+
+  // TODO(enga): Handle chunking commands if size > c2s_buffer_size_.
+  if (size > c2s_buffer_size_) {
+    NOTREACHED();
+    return nullptr;
+  }
+
+  // This should never be more than 2 * c2s_buffer_size_ which is checked in
+  // WebGPUImplementation::Initialize.
+  DCHECK_LE(c2s_put_offset_, c2s_buffer_size_);
+  DCHECK_LE(size, c2s_buffer_size_);
+  uint32_t next_offset = c2s_put_offset_ + static_cast<uint32_t>(size);
+
+  // If the buffer does not have enough space, or if the buffer is not
+  // initialized, flush and reset the command stream.
+  if (next_offset > c2s_buffer_.size() || !c2s_buffer_.valid()) {
+    Flush();
+
+    c2s_buffer_.Reset(c2s_buffer_size_);
+    c2s_put_offset_ = 0;
+    next_offset = size;
+
+    if (size > c2s_buffer_.size() || !c2s_buffer_.valid()) {
+      // TODO(enga): Handle OOM.
+      return nullptr;
+    }
+  }
+
+  DCHECK(c2s_buffer_.valid());
+  uint8_t* ptr = static_cast<uint8_t*>(c2s_buffer_.address());
+  ptr += c2s_put_offset_;
+
+  c2s_put_offset_ = next_offset;
+  return ptr;
+}
+
+bool WebGPUImplementation::Flush() {
+  if (c2s_buffer_.valid()) {
+    helper_->DawnCommands(c2s_buffer_.shm_id(), c2s_buffer_.offset(),
+                          c2s_put_offset_);
+    c2s_put_offset_ = 0;
+    c2s_buffer_.Release();
+  }
+  return true;
+}
+
+const DawnProcTable& WebGPUImplementation::GetProcs() const {
+#if !BUILDFLAG(USE_DAWN)
+  NOTREACHED();
+#endif
+  return procs_;
+}
+
+void WebGPUImplementation::FlushCommands() {
+  Flush();
+  helper_->Flush();
+}
+
+DawnDevice WebGPUImplementation::GetDefaultDevice() {
+#if BUILDFLAG(USE_DAWN)
+  return wire_client_->GetDevice();
+#else
+  NOTREACHED();
+  return {};
+#endif
+}
+
 }  // namespace webgpu
 }  // namespace gpu
diff --git a/gpu/command_buffer/client/webgpu_implementation.h b/gpu/command_buffer/client/webgpu_implementation.h
index 4c3ddaa7..e76ded88 100644
--- a/gpu/command_buffer/client/webgpu_implementation.h
+++ b/gpu/command_buffer/client/webgpu_implementation.h
@@ -5,6 +5,10 @@
 #ifndef GPU_COMMAND_BUFFER_CLIENT_WEBGPU_IMPLEMENTATION_H_
 #define GPU_COMMAND_BUFFER_CLIENT_WEBGPU_IMPLEMENTATION_H_
 
+#include <dawn/dawn.h>
+#include <dawn_wire/WireClient.h>
+
+#include <memory>
 #include <utility>
 #include <vector>
 
@@ -15,12 +19,17 @@
 #include "gpu/command_buffer/client/webgpu_cmd_helper.h"
 #include "gpu/command_buffer/client/webgpu_export.h"
 #include "gpu/command_buffer/client/webgpu_interface.h"
+#include "ui/gl/buildflags.h"
 
 namespace gpu {
 namespace webgpu {
 
-class WEBGPU_EXPORT WebGPUImplementation final : public WebGPUInterface,
-                                                 public ImplementationBase {
+class WEBGPU_EXPORT WebGPUImplementation final
+    : public dawn_wire::CommandSerializer,
+      public WebGPUInterface,
+      public ImplementationBase {
+  friend class WireClientCommandSerializer;
+
  public:
   explicit WebGPUImplementation(WebGPUCmdHelper* helper,
                                 TransferBufferInterface* transfer_buffer,
@@ -86,11 +95,31 @@
                              const gfx::PresentationFeedback& feedback) final;
   void OnGpuControlReturnData(base::span<const uint8_t> data) final;
 
+  // dawn_wire::CommandSerializer implementation
+  void* GetCmdSpace(size_t size) final;
+  bool Flush() final;
+
+  // WebGPUInterface implementation
+  const DawnProcTable& GetProcs() const override;
+  void FlushCommands() override;
+  DawnDevice GetDefaultDevice() override;
+
  private:
   const char* GetLogPrefix() const { return "webgpu"; }
 
   WebGPUCmdHelper* helper_;
+#if BUILDFLAG(USE_DAWN)
+  std::unique_ptr<dawn_wire::WireClient> wire_client_;
+#endif
+  DawnProcTable procs_ = {};
+
+  uint32_t c2s_buffer_size_ = 0;
+  uint32_t c2s_put_offset_ = 0;
+  ScopedTransferBufferPtr c2s_buffer_;
+
   LogSettings log_settings_;
+
+  DISALLOW_COPY_AND_ASSIGN(WebGPUImplementation);
 };
 
 }  // namespace webgpu
diff --git a/gpu/command_buffer/client/webgpu_implementation_unittest.cc b/gpu/command_buffer/client/webgpu_implementation_unittest.cc
index bf1c529..f3b37d4 100644
--- a/gpu/command_buffer/client/webgpu_implementation_unittest.cc
+++ b/gpu/command_buffer/client/webgpu_implementation_unittest.cc
@@ -93,6 +93,7 @@
   void SetUp() override { ASSERT_TRUE(Initialize()); }
 
   void TearDown() override {
+    gl_->Flush();
     Mock::VerifyAndClear(gl_.get());
     EXPECT_CALL(*command_buffer_, OnFlush()).Times(AnyNumber());
     // For command buffer.
diff --git a/gpu/command_buffer/client/webgpu_interface.h b/gpu/command_buffer/client/webgpu_interface.h
index 4360ac32..db704ed 100644
--- a/gpu/command_buffer/client/webgpu_interface.h
+++ b/gpu/command_buffer/client/webgpu_interface.h
@@ -5,6 +5,8 @@
 #ifndef GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_H_
 #define GPU_COMMAND_BUFFER_CLIENT_WEBGPU_INTERFACE_H_
 
+#include <dawn/dawn.h>
+
 extern "C" typedef struct _ClientBuffer* ClientBuffer;
 extern "C" typedef struct _GLColorSpace* GLColorSpace;
 
@@ -16,6 +18,10 @@
   WebGPUInterface() {}
   virtual ~WebGPUInterface() {}
 
+  virtual const DawnProcTable& GetProcs() const = 0;
+  virtual void FlushCommands() = 0;
+  virtual DawnDevice GetDefaultDevice() = 0;
+
 // Include the auto-generated part of this class. We split this because
 // it means we can easily edit the non-auto generated parts right here in
 // this file instead of having to edit some template or the code generator.
diff --git a/gpu/command_buffer/tests/webgpu_fence_unittest.cc b/gpu/command_buffer/tests/webgpu_fence_unittest.cc
new file mode 100644
index 0000000..58a41510
--- /dev/null
+++ b/gpu/command_buffer/tests/webgpu_fence_unittest.cc
@@ -0,0 +1,113 @@
+// Copyright 2019 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 <dawn/dawncpp.h>
+
+#include "gpu/command_buffer/client/webgpu_implementation.h"
+#include "gpu/command_buffer/tests/webgpu_test.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+class MockFenceOnCompletionCallback {
+ public:
+  MOCK_METHOD2(Call,
+               void(DawnFenceCompletionStatus status,
+                    DawnCallbackUserdata userdata));
+};
+
+std::unique_ptr<MockFenceOnCompletionCallback> mockFenceOnCompletionCallback;
+void ToMockFenceOnCompletionCallback(DawnFenceCompletionStatus status,
+                                     DawnCallbackUserdata userdata) {
+  mockFenceOnCompletionCallback->Call(status, userdata);
+}
+
+}  // namespace
+
+namespace gpu {
+
+class WebGPUFenceTest : public WebGPUTest {
+ protected:
+  void SetUp() override {
+    WebGPUTest::SetUp();
+    Initialize(WebGPUTest::Options());
+    mockFenceOnCompletionCallback =
+        std::make_unique<MockFenceOnCompletionCallback>();
+  }
+
+  void TearDown() override {
+    mockFenceOnCompletionCallback = nullptr;
+    WebGPUTest::TearDown();
+  }
+
+  void WaitForFence(dawn::Device device, dawn::Fence fence, uint64_t value) {
+    while (fence.GetCompletedValue() < value) {
+      device.Tick();
+      webgpu()->FlushCommands();
+      RunPendingTasks();
+    }
+  }
+};
+
+// Test that getting the value of the fence is the initial value.
+TEST_F(WebGPUFenceTest, InitialValue) {
+  dawn::Device device = dawn::Device::Acquire(webgpu()->GetDefaultDevice());
+  dawn::Queue queue = device.CreateQueue();
+  {
+    dawn::FenceDescriptor fence_desc{nullptr, 0};
+    dawn::Fence fence = queue.CreateFence(&fence_desc);
+    EXPECT_EQ(fence.GetCompletedValue(), 0u);
+  }
+  {
+    dawn::FenceDescriptor fence_desc{nullptr, 2};
+    dawn::Fence fence = queue.CreateFence(&fence_desc);
+    EXPECT_EQ(fence.GetCompletedValue(), 2u);
+  }
+}
+
+// Test that after signaling a fence, its completed value gets updated.
+TEST_F(WebGPUFenceTest, GetCompletedValue) {
+  dawn::Device device = dawn::Device::Acquire(webgpu()->GetDefaultDevice());
+  dawn::Queue queue = device.CreateQueue();
+  dawn::FenceDescriptor fence_desc{nullptr, 0};
+  dawn::Fence fence = queue.CreateFence(&fence_desc);
+  queue.Signal(fence, 2u);
+  WaitForFence(device, fence, 2u);
+  EXPECT_EQ(fence.GetCompletedValue(), 2u);
+}
+
+// Test that a fence's OnCompletion handler is called after the signal value
+// is completed.
+TEST_F(WebGPUFenceTest, OnCompletion) {
+  dawn::Device device = dawn::Device::Acquire(webgpu()->GetDefaultDevice());
+  dawn::Queue queue = device.CreateQueue();
+  dawn::FenceDescriptor fence_desc{nullptr, 0};
+  dawn::Fence fence = queue.CreateFence(&fence_desc);
+  queue.Signal(fence, 2u);
+
+  DawnCallbackUserdata userdata = 9847;
+  EXPECT_CALL(*mockFenceOnCompletionCallback,
+              Call(DAWN_FENCE_COMPLETION_STATUS_SUCCESS, userdata))
+      .Times(1);
+  fence.OnCompletion(2u, ToMockFenceOnCompletionCallback, userdata);
+  WaitForFence(device, fence, 2u);
+}
+
+// Test signaling a fence a million times.
+TEST_F(WebGPUFenceTest, SignalManyTimes) {
+  dawn::Device device = dawn::Device::Acquire(webgpu()->GetDefaultDevice());
+  dawn::Queue queue = device.CreateQueue();
+  dawn::FenceDescriptor fence_desc{nullptr, 0};
+  dawn::Fence fence = queue.CreateFence(&fence_desc);
+
+  uint64_t max_value = 1000000u;
+  for (uint64_t i = 1; i <= max_value; ++i) {
+    queue.Signal(fence, i);
+  }
+  WaitForFence(device, fence, max_value);
+  EXPECT_EQ(fence.GetCompletedValue(), max_value);
+}
+
+}  // namespace gpu
diff --git a/gpu/command_buffer/tests/webgpu_test.cc b/gpu/command_buffer/tests/webgpu_test.cc
new file mode 100644
index 0000000..d6d8a18
--- /dev/null
+++ b/gpu/command_buffer/tests/webgpu_test.cc
@@ -0,0 +1,61 @@
+// Copyright 2019 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 "gpu/command_buffer/tests/webgpu_test.h"
+
+#include <dawn/dawn.h>
+
+#include "base/test/test_simple_task_runner.h"
+#include "gpu/command_buffer/client/webgpu_implementation.h"
+#include "gpu/command_buffer/service/webgpu_decoder.h"
+#include "gpu/ipc/in_process_command_buffer.h"
+#include "gpu/ipc/in_process_gpu_thread_holder.h"
+#include "gpu/ipc/webgpu_in_process_context.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace gpu {
+
+WebGPUTest::Options::Options() = default;
+
+WebGPUTest::WebGPUTest() = default;
+WebGPUTest::~WebGPUTest() = default;
+
+void WebGPUTest::SetUp() {
+  gpu_thread_holder_ = std::make_unique<InProcessGpuThreadHolder>();
+  gpu_thread_holder_->GetGpuPreferences()->enable_webgpu = true;
+}
+
+void WebGPUTest::TearDown() {
+  context_.reset();
+}
+
+void WebGPUTest::Initialize(const Options& options) {
+  ContextCreationAttribs attributes;
+  attributes.bind_generates_resource = false;
+  attributes.enable_gles2_interface = false;
+  attributes.context_type = CONTEXT_TYPE_WEBGPU;
+
+  static constexpr GpuMemoryBufferManager* memory_buffer_manager = nullptr;
+  static constexpr ImageFactory* image_factory = nullptr;
+  static constexpr GpuChannelManagerDelegate* channel_manager = nullptr;
+  context_ = std::make_unique<WebGPUInProcessContext>();
+  ContextResult result =
+      context_->Initialize(gpu_thread_holder_->GetTaskExecutor(), attributes,
+                           options.shared_memory_limits, memory_buffer_manager,
+                           image_factory, channel_manager);
+  DCHECK_EQ(result, ContextResult::kSuccess);
+
+  DawnProcTable procs = webgpu()->GetProcs();
+  dawnSetProcs(&procs);
+}
+
+webgpu::WebGPUInterface* WebGPUTest::webgpu() const {
+  return context_->GetImplementation();
+}
+
+void WebGPUTest::RunPendingTasks() {
+  context_->GetTaskRunner()->RunPendingTasks();
+}
+
+}  // namespace gpu
diff --git a/gpu/command_buffer/tests/webgpu_test.h b/gpu/command_buffer/tests/webgpu_test.h
new file mode 100644
index 0000000..205f29e
--- /dev/null
+++ b/gpu/command_buffer/tests/webgpu_test.h
@@ -0,0 +1,51 @@
+// Copyright 2019 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 GPU_COMMAND_BUFFER_TESTS_WEBGPU_TEST_H_
+#define GPU_COMMAND_BUFFER_TESTS_WEBGPU_TEST_H_
+
+#include <memory>
+
+#include "gpu/command_buffer/client/shared_memory_limits.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace gpu {
+
+class InProcessGpuThreadHolder;
+class WebGPUInProcessContext;
+
+namespace webgpu {
+
+class WebGPUInterface;
+
+}  // namespace webgpu
+
+class WebGPUTest : public testing::Test {
+ protected:
+  struct Options {
+    Options();
+
+    // Shared memory limits
+    SharedMemoryLimits shared_memory_limits = {};
+  };
+
+  WebGPUTest();
+  ~WebGPUTest() override;
+
+  void SetUp() override;
+  void TearDown() override;
+
+  void Initialize(const Options& options);
+
+  webgpu::WebGPUInterface* webgpu() const;
+  void RunPendingTasks();
+
+ private:
+  std::unique_ptr<InProcessGpuThreadHolder> gpu_thread_holder_;
+  std::unique_ptr<WebGPUInProcessContext> context_;
+};
+
+}  // namespace gpu
+
+#endif  // GPU_COMMAND_BUFFER_TESTS_WEBGPU_TEST_H_
diff --git a/gpu/ipc/webgpu_in_process_context.cc b/gpu/ipc/webgpu_in_process_context.cc
index 2fd9c7f..4413605 100644
--- a/gpu/ipc/webgpu_in_process_context.cc
+++ b/gpu/ipc/webgpu_in_process_context.cc
@@ -100,6 +100,10 @@
   return webgpu_implementation_.get();
 }
 
+base::TestSimpleTaskRunner* WebGPUInProcessContext::GetTaskRunner() {
+  return client_task_runner_.get();
+}
+
 ServiceTransferCache* WebGPUInProcessContext::GetTransferCacheForTest() const {
   return command_buffer_->GetTransferCacheForTest();
 }
diff --git a/gpu/ipc/webgpu_in_process_context.h b/gpu/ipc/webgpu_in_process_context.h
index 7ef77c59..aab65aee 100644
--- a/gpu/ipc/webgpu_in_process_context.h
+++ b/gpu/ipc/webgpu_in_process_context.h
@@ -53,6 +53,7 @@
   // Allows direct access to the WebGPUImplementation so a
   // WebGPUInProcessContext can be used without making it current.
   gpu::webgpu::WebGPUInterface* GetImplementation();
+  base::TestSimpleTaskRunner* GetTaskRunner();
 
   // Test only functions.
   ServiceTransferCache* GetTransferCacheForTest() const;
diff --git a/media/capabilities/learning_helper.cc b/media/capabilities/learning_helper.cc
index 6109c6b..1bc19924 100644
--- a/media/capabilities/learning_helper.cc
+++ b/media/capabilities/learning_helper.cc
@@ -16,6 +16,8 @@
 using learning::LabelledExample;
 using learning::LearningSessionImpl;
 using learning::LearningTask;
+using learning::LearningTaskController;
+using learning::ObservationCompletion;
 using learning::SequenceBoundFeatureProvider;
 using learning::TargetValue;
 
@@ -57,17 +59,21 @@
 
   // Enable hacky reporting of accuracy.
   dropped_frame_task.uma_hacky_confusion_matrix =
-      "Media.Learning.MediaCapabilities.DroppedFrameRatioTask.BaseTree";
+      "Media.Learning.MediaCapabilities.DroppedFrameRatioTask.BaseTable";
   learning_session_->RegisterTask(dropped_frame_task,
                                   SequenceBoundFeatureProvider());
+  base_table_controller_ =
+      learning_session_->GetController(dropped_frame_task.name);
 
   // Modify the task to use ExtraTrees.
   dropped_frame_task.name = kDroppedFrameRatioBaseTreeTaskName;
   dropped_frame_task.model = LearningTask::Model::kExtraTrees;
   dropped_frame_task.uma_hacky_confusion_matrix =
-      "Media.Learning.MediaCapabilities.DroppedFrameRatioTask.BaseTable";
+      "Media.Learning.MediaCapabilities.DroppedFrameRatioTask.BaseTree";
   learning_session_->RegisterTask(dropped_frame_task,
                                   SequenceBoundFeatureProvider());
+  base_tree_controller_ =
+      learning_session_->GetController(dropped_frame_task.name);
 
   // Add common features, if we have a factory.
   if (feature_factory) {
@@ -80,6 +86,8 @@
         "Media.Learning.MediaCapabilities.DroppedFrameRatioTask.EnhancedTree";
     learning_session_->RegisterTask(dropped_frame_task,
                                     feature_factory.Run(dropped_frame_task));
+    enhanced_tree_controller_ =
+        learning_session_->GetController(dropped_frame_task.name);
   }
 }
 
@@ -119,12 +127,19 @@
       static_cast<double>(new_stats.frames_dropped) / new_stats.frames_decoded);
   example.weight = new_stats.frames_decoded;
 
-  // Add this example to both tasks.
-  learning_session_->AddExample(kDroppedFrameRatioBaseTreeTaskName, example);
-  learning_session_->AddExample(kDroppedFrameRatioBaseTableTaskName, example);
-  // Might fail, but that's okay.
-  learning_session_->AddExample(kDroppedFrameRatioEnhancedTreeTaskName,
-                                example);
+  // Add this example to all tasks.
+  AddExample(base_table_controller_.get(), example);
+  AddExample(base_tree_controller_.get(), example);
+  if (enhanced_tree_controller_)
+    AddExample(enhanced_tree_controller_.get(), example);
+}
+
+void LearningHelper::AddExample(LearningTaskController* controller,
+                                const LabelledExample& example) {
+  LearningTaskController::ObservationId id = 1;
+  controller->BeginObservation(id, example.features);
+  controller->CompleteObservation(
+      id, ObservationCompletion(example.target_value, example.weight));
 }
 
 }  // namespace media
diff --git a/media/capabilities/learning_helper.h b/media/capabilities/learning_helper.h
index 6014322..c3355ff7 100644
--- a/media/capabilities/learning_helper.h
+++ b/media/capabilities/learning_helper.h
@@ -5,6 +5,8 @@
 #ifndef MEDIA_CAPABILITIES_LEARNING_HELPER_H_
 #define MEDIA_CAPABILITIES_LEARNING_HELPER_H_
 
+#include <memory>
+
 #include "base/macros.h"
 #include "base/threading/sequence_bound.h"
 #include "media/base/media_export.h"
@@ -27,12 +29,20 @@
                    const VideoDecodeStatsDB::DecodeStatsEntry& new_stats);
 
  private:
-  // Learning session for our profile.  This isn't the way LearningSession is
-  // intended to be used -- one should expect to get a LearningTaskController
-  // for a particular task.  The LearningSession would be owned elsewhere (e.g.,
-  // the BrowserContext).  We do it this way here since LearningHelper is an
-  // hacky way to see if all this works.
+  // Convenience function to begin and complete an observation.
+  void AddExample(learning::LearningTaskController* controller,
+                  const learning::LabelledExample& example);
+
+  // Learning session for our profile.  Normally, we'd not have one of these
+  // directly, but would instead get one that's connected to a browser profile.
+  // For now, however, we just instantiate one and assume that we'll be
+  // destroyed when the profile changes / history is cleared.
   std::unique_ptr<learning::LearningSessionImpl> learning_session_;
+
+  // Controllers for each task.
+  std::unique_ptr<learning::LearningTaskController> base_table_controller_;
+  std::unique_ptr<learning::LearningTaskController> base_tree_controller_;
+  std::unique_ptr<learning::LearningTaskController> enhanced_tree_controller_;
 };
 
 }  // namespace media
diff --git a/media/learning/common/learning_session.h b/media/learning/common/learning_session.h
index 22db890c..f0fb9ba9 100644
--- a/media/learning/common/learning_session.h
+++ b/media/learning/common/learning_session.h
@@ -5,6 +5,7 @@
 #ifndef MEDIA_LEARNING_COMMON_LEARNING_SESSION_H_
 #define MEDIA_LEARNING_COMMON_LEARNING_SESSION_H_
 
+#include <memory>
 #include <string>
 
 #include "base/component_export.h"
@@ -15,18 +16,17 @@
 namespace media {
 namespace learning {
 
+class LearningTaskController;
+
 // Interface to provide a Learner given the task name.
 class COMPONENT_EXPORT(LEARNING_COMMON) LearningSession {
  public:
   LearningSession();
   virtual ~LearningSession();
 
-  // Add an observed example |example| to the learning task |task_name|.
-  // TODO(liberato): Consider making this an enum to match mojo.
-  virtual void AddExample(const std::string& task_name,
-                          const LabelledExample& example) = 0;
-
-  // TODO(liberato): Add prediction API.
+  // Return a LearningTaskController for the given task.
+  virtual std::unique_ptr<LearningTaskController> GetController(
+      const std::string& task_name) = 0;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(LearningSession);
diff --git a/media/learning/common/learning_task_controller.h b/media/learning/common/learning_task_controller.h
index 506216d..f316aa4 100644
--- a/media/learning/common/learning_task_controller.h
+++ b/media/learning/common/learning_task_controller.h
@@ -51,7 +51,8 @@
   // feature values at prediction time.  Later, if you want to turn these
   // features into an example for training a model, then call
   // CompleteObservation with the same id and an ObservationCompletion.
-  // Otherwise, call CancelObservation with |id|.
+  // Otherwise, call CancelObservation with |id|.  It's also okay to destroy the
+  // controller with outstanding observations; these will be cancelled.
   // TODO(liberato): This should optionally take a callback to receive a
   // prediction for the FeatureVector.
   // TODO(liberato): See if this ends up generating smaller code with pass-by-
diff --git a/media/learning/impl/learning_session_impl.cc b/media/learning/impl/learning_session_impl.cc
index 79b19ba..71cedf0f 100644
--- a/media/learning/impl/learning_session_impl.cc
+++ b/media/learning/impl/learning_session_impl.cc
@@ -4,6 +4,7 @@
 
 #include "media/learning/impl/learning_session_impl.h"
 
+#include <set>
 #include <utility>
 
 #include "base/bind.h"
@@ -14,6 +15,61 @@
 namespace media {
 namespace learning {
 
+// Allow multiple clients to own an LTC that points to the same underlying LTC.
+// Since we don't own the LTC, we also keep track of in-flight observations and
+// explicitly cancel them on destruction, since dropping an LTC implies that.
+class WeakLearningTaskController : public LearningTaskController {
+ public:
+  WeakLearningTaskController(
+      base::WeakPtr<LearningSessionImpl> weak_session,
+      base::SequenceBound<LearningTaskController>* controller)
+      : weak_session_(std::move(weak_session)), controller_(controller) {}
+
+  ~WeakLearningTaskController() override {
+    if (!weak_session_)
+      return;
+
+    // Cancel any outstanding observations.
+    for (auto& id : outstanding_ids_) {
+      controller_->Post(FROM_HERE, &LearningTaskController::CancelObservation,
+                        id);
+    }
+  }
+
+  void BeginObservation(ObservationId id,
+                        const FeatureVector& features) override {
+    if (!weak_session_)
+      return;
+
+    outstanding_ids_.insert(id);
+    controller_->Post(FROM_HERE, &LearningTaskController::BeginObservation, id,
+                      features);
+  }
+
+  void CompleteObservation(ObservationId id,
+                           const ObservationCompletion& completion) override {
+    if (!weak_session_)
+      return;
+    outstanding_ids_.erase(id);
+    controller_->Post(FROM_HERE, &LearningTaskController::CompleteObservation,
+                      id, completion);
+  }
+
+  void CancelObservation(ObservationId id) override {
+    if (!weak_session_)
+      return;
+    outstanding_ids_.erase(id);
+    controller_->Post(FROM_HERE, &LearningTaskController::CancelObservation,
+                      id);
+  }
+
+  base::WeakPtr<LearningSessionImpl> weak_session_;
+  base::SequenceBound<LearningTaskController>* controller_;
+
+  // Set of ids that have been started but not completed / cancelled yet.
+  std::set<ObservationId> outstanding_ids_;
+};
+
 LearningSessionImpl::LearningSessionImpl(
     scoped_refptr<base::SequencedTaskRunner> task_runner)
     : task_runner_(std::move(task_runner)),
@@ -25,7 +81,8 @@
             return base::SequenceBound<LearningTaskControllerImpl>(
                 task_runner, task, DistributionReporter::Create(task),
                 std::move(feature_provider));
-          })) {}
+          })),
+      weak_factory_(this) {}
 
 LearningSessionImpl::~LearningSessionImpl() = default;
 
@@ -34,19 +91,16 @@
   controller_factory_ = std::move(cb);
 }
 
-void LearningSessionImpl::AddExample(const std::string& task_name,
-                                     const LabelledExample& example) {
+std::unique_ptr<LearningTaskController> LearningSessionImpl::GetController(
+    const std::string& task_name) {
   auto iter = task_map_.find(task_name);
-  if (iter != task_map_.end()) {
-    // TODO(liberato): We shouldn't be adding examples.  We should provide the
-    // LearningTaskController instead, although ownership gets a bit weird.
-    LearningTaskController::ObservationId id = 1;
-    iter->second.Post(FROM_HERE, &LearningTaskController::BeginObservation, id,
-                      example.features);
-    iter->second.Post(
-        FROM_HERE, &LearningTaskController::CompleteObservation, id,
-        ObservationCompletion(example.target_value, example.weight));
-  }
+  if (iter == task_map_.end())
+    return nullptr;
+
+  // If there were any way to replace / destroy a controller other than when we
+  // destroy |this|, then this wouldn't be such a good idea.
+  return std::make_unique<WeakLearningTaskController>(
+      weak_factory_.GetWeakPtr(), &iter->second);
 }
 
 void LearningSessionImpl::RegisterTask(
diff --git a/media/learning/impl/learning_session_impl.h b/media/learning/impl/learning_session_impl.h
index 2761fa01..01402f5 100644
--- a/media/learning/impl/learning_session_impl.h
+++ b/media/learning/impl/learning_session_impl.h
@@ -8,6 +8,7 @@
 #include <map>
 
 #include "base/component_export.h"
+#include "base/memory/weak_ptr.h"
 #include "base/sequenced_task_runner.h"
 #include "base/threading/sequence_bound.h"
 #include "media/learning/common/learning_session.h"
@@ -36,8 +37,8 @@
   void SetTaskControllerFactoryCBForTesting(CreateTaskControllerCB cb);
 
   // LearningSession
-  void AddExample(const std::string& task_name,
-                  const LabelledExample& example) override;
+  std::unique_ptr<LearningTaskController> GetController(
+      const std::string& task_name) override;
 
   // Registers |task|, so that calls to AddExample with |task.name| will work.
   // This will create a new controller for the task.
@@ -55,6 +56,8 @@
   LearningTaskMap task_map_;
 
   CreateTaskControllerCB controller_factory_;
+
+  base::WeakPtrFactory<LearningSessionImpl> weak_factory_;
 };
 
 }  // namespace learning
diff --git a/media/learning/impl/learning_session_impl_unittest.cc b/media/learning/impl/learning_session_impl_unittest.cc
index 1526c49..cc3b33a 100644
--- a/media/learning/impl/learning_session_impl_unittest.cc
+++ b/media/learning/impl/learning_session_impl_unittest.cc
@@ -54,12 +54,15 @@
       example_.weight = completion.weight;
     }
 
-    void CancelObservation(ObservationId id) override { ASSERT_TRUE(false); }
+    void CancelObservation(ObservationId id) override { cancelled_id_ = id; }
 
     SequenceBoundFeatureProvider feature_provider_;
     ObservationId id_ = 0;
     FeatureVector features_;
     LabelledExample example_;
+
+    // Most recently cancelled id.
+    ObservationId cancelled_id_ = 0;
   };
 
   class FakeFeatureProvider : public FeatureProvider {
@@ -129,19 +132,45 @@
   session_->RegisterTask(task_0_);
   session_->RegisterTask(task_1_);
 
+  LearningTaskController::ObservationId id = 1;
+
   LabelledExample example_0({FeatureValue(123), FeatureValue(456)},
                             TargetValue(1234));
-  session_->AddExample(task_0_.name, example_0);
+  std::unique_ptr<LearningTaskController> ltc_0 =
+      session_->GetController(task_0_.name);
+  ltc_0->BeginObservation(id, example_0.features);
+  ltc_0->CompleteObservation(
+      id, ObservationCompletion(example_0.target_value, example_0.weight));
 
   LabelledExample example_1({FeatureValue(321), FeatureValue(654)},
                             TargetValue(4321));
-  session_->AddExample(task_1_.name, example_1);
+
+  std::unique_ptr<LearningTaskController> ltc_1 =
+      session_->GetController(task_1_.name);
+  ltc_1->BeginObservation(id, example_1.features);
+  ltc_1->CompleteObservation(
+      id, ObservationCompletion(example_1.target_value, example_1.weight));
 
   scoped_task_environment_.RunUntilIdle();
   EXPECT_EQ(task_controllers_[0]->example_, example_0);
   EXPECT_EQ(task_controllers_[1]->example_, example_1);
 }
 
+TEST_F(LearningSessionImplTest, ControllerLifetimeScopedToSession) {
+  session_->RegisterTask(task_0_);
+
+  std::unique_ptr<LearningTaskController> controller =
+      session_->GetController(task_0_.name);
+
+  // Destroy the session.  |controller| should still be usable, though it won't
+  // forward requests anymore.
+  session_.reset();
+  scoped_task_environment_.RunUntilIdle();
+
+  // Should not crash.
+  controller->BeginObservation(0, FeatureVector());
+}
+
 TEST_F(LearningSessionImplTest, FeatureProviderIsForwarded) {
   // Verify that a FeatureProvider actually gets forwarded to the LTC.
   bool flag = false;
@@ -153,5 +182,27 @@
   EXPECT_TRUE(flag);
 }
 
+TEST_F(LearningSessionImplTest, DestroyingControllerCancelsObservations) {
+  session_->RegisterTask(task_0_);
+
+  std::unique_ptr<LearningTaskController> controller =
+      session_->GetController(task_0_.name);
+  scoped_task_environment_.RunUntilIdle();
+
+  // Start an observation and verify that it starts.
+  LearningTaskController::ObservationId id = 1;
+  controller->BeginObservation(1, FeatureVector());
+  scoped_task_environment_.RunUntilIdle();
+  EXPECT_EQ(task_controllers_[0]->id_, id);
+  EXPECT_NE(task_controllers_[0]->cancelled_id_, id);
+
+  // Should result in cancelling the observation.
+  task_controllers_[0]->id_ = 0;  // So we can check that it's not completed.
+  controller.reset();
+  scoped_task_environment_.RunUntilIdle();
+  EXPECT_NE(task_controllers_[0]->id_, id);
+  EXPECT_EQ(task_controllers_[0]->cancelled_id_, id);
+}
+
 }  // namespace learning
 }  // namespace media
diff --git a/media/learning/mojo/BUILD.gn b/media/learning/mojo/BUILD.gn
index bfe45d1..624908cc 100644
--- a/media/learning/mojo/BUILD.gn
+++ b/media/learning/mojo/BUILD.gn
@@ -8,8 +8,7 @@
 component("impl") {
   output_name = "media_learning_mojo_impl"
   sources = [
-    "mojo_learning_session_impl.cc",
-    "mojo_learning_session_impl.h",
+    "dummy.cc",
   ]
 
   defines = [ "IS_MEDIA_LEARNING_MOJO_IMPL" ]
@@ -34,9 +33,7 @@
 source_set("unit_tests") {
   testonly = true
 
-  sources = [
-    "mojo_learning_session_impl_unittest.cc",
-  ]
+  sources = []
 
   deps = [
     ":impl",
diff --git a/media/learning/mojo/dummy.cc b/media/learning/mojo/dummy.cc
new file mode 100644
index 0000000..0a1d331
--- /dev/null
+++ b/media/learning/mojo/dummy.cc
@@ -0,0 +1,8 @@
+// Copyright 2019 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.
+
+// Because mac requires a non-empty .a, and removing the component requires
+// quite a bit more fiddling with other gn files.  Since there will be new
+// things in this directory very shortly, it's much easier just to add this.
+void media_learning_mojo_do_nothing() {}
diff --git a/media/learning/mojo/mojo_learning_session_impl.cc b/media/learning/mojo/mojo_learning_session_impl.cc
deleted file mode 100644
index 3cfb978..0000000
--- a/media/learning/mojo/mojo_learning_session_impl.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/learning/mojo/mojo_learning_session_impl.h"
-
-#include "media/learning/common/learning_session.h"
-
-namespace media {
-namespace learning {
-
-MojoLearningSessionImpl::MojoLearningSessionImpl(
-    std::unique_ptr<::media::learning::LearningSession> impl)
-    : impl_(std::move(impl)) {}
-
-MojoLearningSessionImpl::~MojoLearningSessionImpl() = default;
-
-void MojoLearningSessionImpl::Bind(mojom::LearningSessionRequest request) {
-  self_bindings_.AddBinding(this, std::move(request));
-}
-
-void MojoLearningSessionImpl::AddExample(mojom::LearningTaskType task_type,
-                                         const LabelledExample& example) {
-  // TODO(liberato): Convert |task_type| into a task name.
-  std::string task_name("no_task");
-
-  impl_->AddExample(task_name, example);
-}
-
-}  // namespace learning
-}  // namespace media
diff --git a/media/learning/mojo/mojo_learning_session_impl.h b/media/learning/mojo/mojo_learning_session_impl.h
deleted file mode 100644
index 83d0eb7..0000000
--- a/media/learning/mojo/mojo_learning_session_impl.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_LEARNING_MOJO_MOJO_LEARNING_SESSION_IMPL_H_
-#define MEDIA_LEARNING_MOJO_MOJO_LEARNING_SESSION_IMPL_H_
-
-#include <memory>
-
-#include "base/component_export.h"
-#include "base/macros.h"
-#include "media/learning/mojo/public/mojom/learning_session.mojom.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
-
-namespace media {
-namespace learning {
-
-class LearningSession;
-class MojoLearningSessionImplTest;
-
-// Mojo service that talks to a local LearningSession.
-class COMPONENT_EXPORT(MEDIA_LEARNING_MOJO) MojoLearningSessionImpl
-    : public mojom::LearningSession {
- public:
-  ~MojoLearningSessionImpl() override;
-
-  // Bind |request| to this instance.
-  void Bind(mojom::LearningSessionRequest request);
-
-  // mojom::LearningSession
-  void AddExample(mojom::LearningTaskType task_type,
-                  const LabelledExample& example) override;
-
- protected:
-  explicit MojoLearningSessionImpl(
-      std::unique_ptr<::media::learning::LearningSession> impl);
-
-  // Underlying session to which we proxy calls.
-  std::unique_ptr<::media::learning::LearningSession> impl_;
-
-  // We own our own bindings.  If we're ever not a singleton, then this should
-  // move to our owner.
-  mojo::BindingSet<mojom::LearningSession> self_bindings_;
-
-  friend class MojoLearningSessionImplTest;
-
-  DISALLOW_COPY_AND_ASSIGN(MojoLearningSessionImpl);
-};
-
-}  // namespace learning
-}  // namespace media
-
-#endif  // MEDIA_LEARNING_MOJO_MOJO_LEARNING_SESSION_IMPL_H_
diff --git a/media/learning/mojo/mojo_learning_session_impl_unittest.cc b/media/learning/mojo/mojo_learning_session_impl_unittest.cc
deleted file mode 100644
index 5399d20..0000000
--- a/media/learning/mojo/mojo_learning_session_impl_unittest.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "media/learning/common/learning_session.h"
-#include "media/learning/mojo/mojo_learning_session_impl.h"
-#include "media/learning/mojo/public/mojom/learning_types.mojom.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace media {
-namespace learning {
-
-class MojoLearningSessionImplTest : public ::testing::Test {
- public:
-  class FakeLearningSession : public ::media::learning::LearningSession {
-   public:
-    void AddExample(const std::string& task_name,
-                    const LabelledExample& example) override {
-      most_recent_task_name_ = task_name;
-      most_recent_example_ = example;
-    }
-
-    std::string most_recent_task_name_;
-    LabelledExample most_recent_example_;
-  };
-
- public:
-  MojoLearningSessionImplTest() = default;
-  ~MojoLearningSessionImplTest() override = default;
-
-  void SetUp() override {
-    // Create a mojo learner that forwards to a fake learner.
-    std::unique_ptr<FakeLearningSession> provider =
-        std::make_unique<FakeLearningSession>();
-    fake_learning_session_ = provider.get();
-    learning_session_impl_ = base::WrapUnique<MojoLearningSessionImpl>(
-        new MojoLearningSessionImpl(std::move(provider)));
-  }
-
-  FakeLearningSession* fake_learning_session_ = nullptr;
-
-  const mojom::LearningTaskType task_type_ =
-      mojom::LearningTaskType::kPlaceHolderTask;
-
-  // The learner provider under test.
-  std::unique_ptr<MojoLearningSessionImpl> learning_session_impl_;
-};
-
-TEST_F(MojoLearningSessionImplTest, FeaturesAndTargetValueAreCopied) {
-  mojom::LabelledExamplePtr example_ptr = mojom::LabelledExample::New();
-  const LabelledExample example = {{Value(123), Value(456), Value(890)},
-                                   TargetValue(1234)};
-
-  learning_session_impl_->AddExample(task_type_, example);
-  EXPECT_EQ(example, fake_learning_session_->most_recent_example_);
-}
-
-}  // namespace learning
-}  // namespace media
diff --git a/media/learning/mojo/public/cpp/BUILD.gn b/media/learning/mojo/public/cpp/BUILD.gn
index 2157282..3b0507e43 100644
--- a/media/learning/mojo/public/cpp/BUILD.gn
+++ b/media/learning/mojo/public/cpp/BUILD.gn
@@ -8,11 +8,6 @@
     "//media/learning/mojo/public/cpp:unit_tests",
   ]
 
-  sources = [
-    "mojo_learning_session.cc",
-    "mojo_learning_session.h",
-  ]
-
   defines = [ "IS_MEDIA_LEARNING_MOJO_IMPL" ]
 
   deps = [
@@ -25,10 +20,6 @@
 source_set("unit_tests") {
   testonly = true
 
-  sources = [
-    "mojo_learning_session_unittest.cc",
-  ]
-
   deps = [
     "//base",
     "//base/test:test_support",
diff --git a/media/learning/mojo/public/cpp/mojo_learning_session.cc b/media/learning/mojo/public/cpp/mojo_learning_session.cc
deleted file mode 100644
index c67f642..0000000
--- a/media/learning/mojo/public/cpp/mojo_learning_session.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/learning/mojo/public/cpp/mojo_learning_session.h"
-
-#include "mojo/public/cpp/bindings/binding.h"
-
-namespace media {
-namespace learning {
-
-MojoLearningSession::MojoLearningSession(mojom::LearningSessionPtr session_ptr)
-    : session_ptr_(std::move(session_ptr)) {}
-
-MojoLearningSession::~MojoLearningSession() = default;
-
-void MojoLearningSession::AddExample(const std::string& task_name,
-                                     const LabelledExample& example) {
-  // TODO(liberato): Convert from |task_name| to a task type.
-  session_ptr_->AddExample(mojom::LearningTaskType::kPlaceHolderTask, example);
-}
-
-}  // namespace learning
-}  // namespace media
diff --git a/media/learning/mojo/public/cpp/mojo_learning_session.h b/media/learning/mojo/public/cpp/mojo_learning_session.h
deleted file mode 100644
index 0e8af2b..0000000
--- a/media/learning/mojo/public/cpp/mojo_learning_session.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_LEARNING_MOJO_PUBLIC_CPP_MOJO_LEARNING_SESSION_H_
-#define MEDIA_LEARNING_MOJO_PUBLIC_CPP_MOJO_LEARNING_SESSION_H_
-
-#include "base/component_export.h"
-#include "base/macros.h"
-#include "media/learning/common/learning_session.h"
-#include "media/learning/mojo/public/mojom/learning_session.mojom.h"
-
-namespace media {
-namespace learning {
-
-// LearningSession implementation to forward to a remote impl via mojo.
-class COMPONENT_EXPORT(MEDIA_LEARNING_MOJO) MojoLearningSession
-    : public LearningSession {
- public:
-  explicit MojoLearningSession(mojom::LearningSessionPtr session_ptr);
-  ~MojoLearningSession() override;
-
-  // LearningSession
-  void AddExample(const std::string& task_name,
-                  const LabelledExample& example) override;
-
- private:
-  mojom::LearningSessionPtr session_ptr_;
-
-  DISALLOW_COPY_AND_ASSIGN(MojoLearningSession);
-};
-
-}  // namespace learning
-}  // namespace media
-
-#endif  // MEDIA_LEARNING_MOJO_PUBLIC_CPP_MOJO_LEARNING_SESSION_H_
diff --git a/media/learning/mojo/public/cpp/mojo_learning_session_unittest.cc b/media/learning/mojo/public/cpp/mojo_learning_session_unittest.cc
deleted file mode 100644
index 37cecb4d..0000000
--- a/media/learning/mojo/public/cpp/mojo_learning_session_unittest.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-
-#include "base/bind.h"
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/test/scoped_task_environment.h"
-#include "base/threading/thread.h"
-#include "media/learning/mojo/public/cpp/mojo_learning_session.h"
-#include "mojo/public/cpp/bindings/binding.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace media {
-namespace learning {
-
-class MojoLearningSessionTest : public ::testing::Test {
- public:
-  // Impl of a mojom::LearningSession that remembers call arguments.
-  class FakeMojoLearningSessionImpl : public mojom::LearningSession {
-   public:
-    void AddExample(mojom::LearningTaskType task_type,
-                    const LabelledExample& example) override {
-      task_type_ = std::move(task_type);
-      example_ = example;
-    }
-
-    mojom::LearningTaskType task_type_;
-    LabelledExample example_;
-  };
-
- public:
-  MojoLearningSessionTest()
-      : learning_session_binding_(&fake_learning_session_impl_) {}
-  ~MojoLearningSessionTest() override = default;
-
-  void SetUp() override {
-    // Create a fake learner provider mojo impl.
-    mojom::LearningSessionPtr learning_session_ptr;
-    learning_session_binding_.Bind(mojo::MakeRequest(&learning_session_ptr));
-
-    // Tell |learning_session_| to forward to the fake learner impl.
-    learning_session_ =
-        std::make_unique<MojoLearningSession>(std::move(learning_session_ptr));
-  }
-
-  // Mojo stuff.
-  base::test::ScopedTaskEnvironment scoped_task_environment_;
-
-  FakeMojoLearningSessionImpl fake_learning_session_impl_;
-  mojo::Binding<mojom::LearningSession> learning_session_binding_;
-
-  // The learner under test.
-  std::unique_ptr<MojoLearningSession> learning_session_;
-};
-
-TEST_F(MojoLearningSessionTest, ExampleIsCopied) {
-  LabelledExample example({FeatureValue(123), FeatureValue(456)},
-                          TargetValue(1234));
-  learning_session_->AddExample("unused task id", example);
-  learning_session_binding_.FlushForTesting();
-  EXPECT_EQ(fake_learning_session_impl_.example_, example);
-}
-
-}  // namespace learning
-}  // namespace media
diff --git a/net/quic/bidirectional_stream_quic_impl_unittest.cc b/net/quic/bidirectional_stream_quic_impl_unittest.cc
index 9b23b54..a5539ff4b 100644
--- a/net/quic/bidirectional_stream_quic_impl_unittest.cc
+++ b/net/quic/bidirectional_stream_quic_impl_unittest.cc
@@ -819,14 +819,14 @@
     return quic::test::GetNthClientInitiatedBidirectionalStreamId(version_, n);
   }
 
-  quic::QuicString ConstructDataHeader(size_t body_len) {
+  std::string ConstructDataHeader(size_t body_len) {
     if (version_ != quic::QUIC_VERSION_99) {
       return "";
     }
     quic::HttpEncoder encoder;
     std::unique_ptr<char[]> buffer;
     auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
-    return quic::QuicString(buffer.get(), header_length);
+    return std::string(buffer.get(), header_length);
   }
 
  protected:
@@ -919,7 +919,7 @@
   EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
   const char kResponseBody[] = "Hello world!";
   // Server sends data.
-  quic::QuicString header = ConstructDataHeader(strlen(kResponseBody));
+  std::string header = ConstructDataHeader(strlen(kResponseBody));
   ProcessPacket(ConstructServerDataPacket(3, !kIncludeVersion, !kFin, 0,
                                           header + kResponseBody));
   EXPECT_EQ(12, cb.WaitForResult());
@@ -1053,8 +1053,8 @@
   AddWrite(ConstructInitialSettingsPacket(1, &header_stream_offset));
   const char kBody1[] = "here are some data";
   const char kBody2[] = "data keep coming";
-  quic::QuicString header = ConstructDataHeader(strlen(kBody1));
-  quic::QuicString header2 = ConstructDataHeader(strlen(kBody2));
+  std::string header = ConstructDataHeader(strlen(kBody1));
+  std::string header2 = ConstructDataHeader(strlen(kBody2));
   std::vector<std::string> two_writes = {kBody1, kBody2};
   AddWrite(ConstructRequestHeadersPacketInner(
       2, GetNthClientInitiatedBidirectionalStreamId(0), !kFin, DEFAULT_PRIORITY,
@@ -1072,9 +1072,9 @@
   const char kBody3[] = "hello there";
   const char kBody4[] = "another piece of small data";
   const char kBody5[] = "really small";
-  quic::QuicString header3 = ConstructDataHeader(strlen(kBody3));
-  quic::QuicString header4 = ConstructDataHeader(strlen(kBody4));
-  quic::QuicString header5 = ConstructDataHeader(strlen(kBody5));
+  std::string header3 = ConstructDataHeader(strlen(kBody3));
+  std::string header4 = ConstructDataHeader(strlen(kBody4));
+  std::string header5 = ConstructDataHeader(strlen(kBody5));
   quic::QuicStreamOffset data_offset =
       strlen(kBody1) + strlen(kBody2) + header.length() + header2.length();
   if (version_ != quic::QUIC_VERSION_99) {
@@ -1136,7 +1136,7 @@
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
   EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
   const char kResponseBody[] = "Hello world!";
-  quic::QuicString header6 = ConstructDataHeader(strlen(kResponseBody));
+  std::string header6 = ConstructDataHeader(strlen(kResponseBody));
   // Server sends data.
   ProcessPacket(ConstructServerDataPacket(3, !kIncludeVersion, !kFin, 0,
                                           header6 + kResponseBody));
@@ -1193,7 +1193,7 @@
   quic::QuicStreamOffset header_stream_offset = 0;
   AddWrite(ConstructInitialSettingsPacket(1, &header_stream_offset));
   const char kBody1[] = "here are some data";
-  quic::QuicString header = ConstructDataHeader(strlen(kBody1));
+  std::string header = ConstructDataHeader(strlen(kBody1));
   if (version_ == quic::QUIC_VERSION_99) {
     AddWrite(ConstructRequestHeadersAndMultipleDataFramesPacket(
         2, !kFin, DEFAULT_PRIORITY, &header_stream_offset,
@@ -1207,7 +1207,7 @@
   // Ack server's data packet.
   AddWrite(ConstructClientAckPacket(3, 3, 1, 2));
   const char kBody2[] = "really small";
-  quic::QuicString header2 = ConstructDataHeader(strlen(kBody2));
+  std::string header2 = ConstructDataHeader(strlen(kBody2));
   quic::QuicStreamOffset data_offset = strlen(kBody1) + header.length();
   if (version_ == quic::QUIC_VERSION_99) {
     AddWrite(ConstructClientMultipleDataFramesPacket(
@@ -1260,7 +1260,7 @@
   EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
   const char kResponseBody[] = "Hello world!";
   // Server sends data.
-  quic::QuicString header3 = ConstructDataHeader(strlen(kResponseBody));
+  std::string header3 = ConstructDataHeader(strlen(kResponseBody));
   ProcessPacket(ConstructServerDataPacket(3, !kIncludeVersion, !kFin, 0,
                                           header3 + kResponseBody));
 
@@ -1310,8 +1310,8 @@
   AddWrite(ConstructInitialSettingsPacket(1, &header_stream_offset));
   const char kBody1[] = "here are some data";
   const char kBody2[] = "data keep coming";
-  quic::QuicString header = ConstructDataHeader(strlen(kBody1));
-  quic::QuicString header2 = ConstructDataHeader(strlen(kBody2));
+  std::string header = ConstructDataHeader(strlen(kBody1));
+  std::string header2 = ConstructDataHeader(strlen(kBody2));
 
   if (version_ == quic::QUIC_VERSION_99) {
     AddWrite(ConstructRequestHeadersAndMultipleDataFramesPacket(
@@ -1328,9 +1328,9 @@
   const char kBody3[] = "hello there";
   const char kBody4[] = "another piece of small data";
   const char kBody5[] = "really small";
-  quic::QuicString header3 = ConstructDataHeader(strlen(kBody3));
-  quic::QuicString header4 = ConstructDataHeader(strlen(kBody4));
-  quic::QuicString header5 = ConstructDataHeader(strlen(kBody5));
+  std::string header3 = ConstructDataHeader(strlen(kBody3));
+  std::string header4 = ConstructDataHeader(strlen(kBody4));
+  std::string header5 = ConstructDataHeader(strlen(kBody5));
   quic::QuicStreamOffset data_offset =
       strlen(kBody1) + strlen(kBody2) + header.length() + header2.length();
   if (version_ == quic::QUIC_VERSION_99) {
@@ -1387,7 +1387,7 @@
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
   EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
   const char kResponseBody[] = "Hello world!";
-  quic::QuicString header6 = ConstructDataHeader(strlen(kResponseBody));
+  std::string header6 = ConstructDataHeader(strlen(kResponseBody));
   // Server sends data.
   ProcessPacket(ConstructServerDataPacket(3, !kIncludeVersion, !kFin, 0,
                                           header6 + kResponseBody));
@@ -1519,7 +1519,7 @@
   AddWrite(ConstructRequestHeadersPacketInner(
       2, GetNthClientInitiatedBidirectionalStreamId(0), !kFin, DEFAULT_PRIORITY,
       &spdy_request_headers_frame_length, &header_stream_offset));
-  quic::QuicString header = ConstructDataHeader(strlen(kUploadData));
+  std::string header = ConstructDataHeader(strlen(kUploadData));
   if (version_ == quic::QUIC_VERSION_99) {
     AddWrite(ConstructClientMultipleDataFramesPacket(3, kIncludeVersion, kFin,
                                                      0, {header, kUploadData}));
@@ -1571,7 +1571,7 @@
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
   EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
   const char kResponseBody[] = "Hello world!";
-  quic::QuicString header2 = ConstructDataHeader(strlen(kResponseBody));
+  std::string header2 = ConstructDataHeader(strlen(kResponseBody));
   // Server sends data.
   ProcessPacket(ConstructServerDataPacket(3, !kIncludeVersion, !kFin, 0,
                                           header2 + kResponseBody));
@@ -1612,7 +1612,7 @@
   AddWrite(ConstructRequestHeadersPacketInner(
       2, GetNthClientInitiatedBidirectionalStreamId(0), !kFin, DEFAULT_PRIORITY,
       &spdy_request_headers_frame_length, &header_stream_offset));
-  quic::QuicString header = ConstructDataHeader(strlen(kUploadData));
+  std::string header = ConstructDataHeader(strlen(kUploadData));
   if (version_ == quic::QUIC_VERSION_99) {
     AddWrite(ConstructClientMultipleDataFramesPacket(3, kIncludeVersion, kFin,
                                                      0, {header, kUploadData}));
@@ -1666,7 +1666,7 @@
   EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
   const char kResponseBody[] = "Hello world!";
   // Server sends data.
-  quic::QuicString header2 = ConstructDataHeader(strlen(kResponseBody));
+  std::string header2 = ConstructDataHeader(strlen(kResponseBody));
   ProcessPacket(ConstructServerDataPacket(3, !kIncludeVersion, !kFin, 0,
                                           header2 + kResponseBody));
 
@@ -1707,7 +1707,7 @@
       2, GetNthClientInitiatedBidirectionalStreamId(0), !kFin, DEFAULT_PRIORITY,
       &spdy_request_headers_frame_length, &header_stream_offset));
 
-  quic::QuicString header = ConstructDataHeader(strlen(kUploadData));
+  std::string header = ConstructDataHeader(strlen(kUploadData));
   if (version_ != quic::QUIC_VERSION_99) {
     AddWrite(ConstructAckAndDataPacket(3, !kIncludeVersion, 2, 1, 2, !kFin, 0,
                                        kUploadData, &client_maker_));
@@ -1763,7 +1763,7 @@
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
   const char kResponseBody[] = "Hello world!";
 
-  quic::QuicString header2 = ConstructDataHeader(strlen(kResponseBody));
+  std::string header2 = ConstructDataHeader(strlen(kResponseBody));
   // Server sends a data packet.
   ProcessPacket(ConstructAckAndDataPacket(3, !kIncludeVersion, 2, 1, 1, !kFin,
                                           0, header2 + kResponseBody,
@@ -2235,7 +2235,7 @@
   int rv = delegate->ReadData(cb.callback());
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
   const char kResponseBody[] = "Hello world!";
-  quic::QuicString header = ConstructDataHeader(strlen(kResponseBody));
+  std::string header = ConstructDataHeader(strlen(kResponseBody));
   // Server sends data.
   ProcessPacket(ConstructServerDataPacket(3, !kIncludeVersion, !kFin, 0,
                                           header + kResponseBody));
@@ -2256,7 +2256,7 @@
   AddWrite(ConstructRequestHeadersPacketInner(
       2, GetNthClientInitiatedBidirectionalStreamId(0), !kFin, DEFAULT_PRIORITY,
       &spdy_request_headers_frame_length, &header_stream_offset));
-  quic::QuicString header = ConstructDataHeader(strlen(kBody));
+  std::string header = ConstructDataHeader(strlen(kBody));
   if (version_ == quic::QUIC_VERSION_99) {
     AddWrite(ConstructClientMultipleDataFramesPacket(3, kIncludeVersion, kFin,
                                                      0, {header, kBody}));
@@ -2310,7 +2310,7 @@
   int rv = delegate->ReadData(cb.callback());
   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
   const char kResponseBody[] = "Hello world!";
-  quic::QuicString header2 = ConstructDataHeader(strlen(kResponseBody));
+  std::string header2 = ConstructDataHeader(strlen(kResponseBody));
 
   // Server sends data with the fin set, which should result in the stream
   // being closed and hence no RST_STREAM will be sent.
@@ -2372,7 +2372,7 @@
   const char kResponseBody[] = "Hello world!";
 
   // Server sends data.
-  quic::QuicString header = ConstructDataHeader(strlen(kResponseBody));
+  std::string header = ConstructDataHeader(strlen(kResponseBody));
   ProcessPacket(ConstructServerDataPacket(3, !kIncludeVersion, !kFin, 0,
                                           header + kResponseBody));
 
diff --git a/net/quic/mock_crypto_client_stream.cc b/net/quic/mock_crypto_client_stream.cc
index 588a40c..549c2ff 100644
--- a/net/quic/mock_crypto_client_stream.cc
+++ b/net/quic/mock_crypto_client_stream.cc
@@ -42,10 +42,10 @@
 using quic::QuicServerId;
 using quic::QuicSession;
 using quic::QuicSpdyClientSessionBase;
-using quic::QuicString;
 using quic::QuicStringPiece;
 using quic::QuicTagVector;
 using quic::QuicTime;
+using std::string;
 
 namespace net {
 
@@ -244,7 +244,7 @@
 
   CryptoHandshakeMessage msg;
   config.ToHandshakeMessage(&msg);
-  QuicString error_details;
+  std::string error_details;
   const QuicErrorCode error =
       session()->config()->ProcessPeerHello(msg, CLIENT, &error_details);
   ASSERT_EQ(QUIC_NO_ERROR, error);
diff --git a/net/quic/platform/impl/quic_file_utils_impl.h b/net/quic/platform/impl/quic_file_utils_impl.h
index 8c2178e..18ac039 100644
--- a/net/quic/platform/impl/quic_file_utils_impl.h
+++ b/net/quic/platform/impl/quic_file_utils_impl.h
@@ -18,8 +18,8 @@
 
 // Traverses the directory |dirname| and retuns all of the files
 // it contains.
-std::vector<QuicString> ReadFileContentsImpl(const QuicString& dirname) {
-  std::vector<QuicString> files;
+std::vector<std::string> ReadFileContentsImpl(const std::string& dirname) {
+  std::vector<std::string> files;
   FilePath directory(FilePath::FromUTF8Unsafe(dirname));
   base::FileEnumerator file_list(directory, true, base::FileEnumerator::FILES);
   for (FilePath file_iter = file_list.Next(); !file_iter.empty();
@@ -30,7 +30,7 @@
 }
 
 // Reads the contents of |filename| as a string into |contents|.
-void ReadFileContentsImpl(QuicStringPiece filename, QuicString* contents) {
+void ReadFileContentsImpl(QuicStringPiece filename, std::string* contents) {
   base::ReadFileToString(FilePath::FromUTF8Unsafe(filename), contents);
 }
 
diff --git a/net/quic/platform/impl/quic_flags_impl.cc b/net/quic/platform/impl/quic_flags_impl.cc
index d561407f..d3a9e8d 100644
--- a/net/quic/platform/impl/quic_flags_impl.cc
+++ b/net/quic/platform/impl/quic_flags_impl.cc
@@ -29,15 +29,15 @@
 namespace {
 
 // Overload for platforms where base::CommandLine::StringType == std::string.
-std::vector<QuicString> __attribute__((unused))
+std::vector<std::string> __attribute__((unused))
 ToQuicStringVector(const std::vector<std::string>& v) {
   return v;
 }
 
 // Overload for platforms where base::CommandLine::StringType == base::string16.
-std::vector<QuicString> __attribute__((unused))
+std::vector<std::string> __attribute__((unused))
 ToQuicStringVector(const std::vector<base::string16>& v) {
-  std::vector<QuicString> qsv;
+  std::vector<std::string> qsv;
   for (const auto& s : v) {
     if (!base::IsStringASCII(s)) {
       QUIC_LOG(ERROR) << "Unable to convert to ASCII: " << s;
@@ -179,7 +179,7 @@
 }
 
 template <>
-bool TypedQuicFlagHelper<QuicString>::SetFlag(const std::string& s) const {
+bool TypedQuicFlagHelper<std::string>::SetFlag(const std::string& s) const {
   *flag_ = s;
   return true;
 }
@@ -189,11 +189,12 @@
 template class EXPORT_TEMPLATE_DEFINE(QUIC_EXPORT_PRIVATE)
     TypedQuicFlagHelper<int32_t>;
 template class EXPORT_TEMPLATE_DEFINE(QUIC_EXPORT_PRIVATE)
-    TypedQuicFlagHelper<QuicString>;
+    TypedQuicFlagHelper<std::string>;
 
-std::vector<QuicString> QuicParseCommandLineFlagsImpl(const char* usage,
-                                                      int argc,
-                                                      const char* const* argv) {
+std::vector<std::string> QuicParseCommandLineFlagsImpl(
+    const char* usage,
+    int argc,
+    const char* const* argv) {
   base::CommandLine::Init(argc, argv);
   auto result = QuicParseCommandLineFlagsHelper(
       usage, *base::CommandLine::ForCurrentProcess());
diff --git a/net/quic/platform/impl/quic_flags_impl.h b/net/quic/platform/impl/quic_flags_impl.h
index 5e66abef..184c18a 100644
--- a/net/quic/platform/impl/quic_flags_impl.h
+++ b/net/quic/platform/impl/quic_flags_impl.h
@@ -111,7 +111,7 @@
 QUIC_EXPORT_PRIVATE bool TypedQuicFlagHelper<int32_t>::SetFlag(
     const std::string&) const;
 template <>
-QUIC_EXPORT_PRIVATE bool TypedQuicFlagHelper<QuicString>::SetFlag(
+QUIC_EXPORT_PRIVATE bool TypedQuicFlagHelper<std::string>::SetFlag(
     const std::string&) const;
 
 // TypedQuicFlagHelper instantiations are in .cc file.
@@ -120,7 +120,7 @@
 extern template class EXPORT_TEMPLATE_DECLARE(QUIC_EXPORT_PRIVATE)
     TypedQuicFlagHelper<int32_t>;
 extern template class EXPORT_TEMPLATE_DECLARE(QUIC_EXPORT_PRIVATE)
-    TypedQuicFlagHelper<QuicString>;
+    TypedQuicFlagHelper<std::string>;
 
 // Registry of QuicFlagHelpers.
 class QUIC_EXPORT_PRIVATE QuicFlagRegistry {
@@ -178,7 +178,7 @@
   bool FLAGS_no##name =                                                     \
       quic::QuicFlagSetup<type>(&FLAGS_##name, #name, default_value, help)
 
-QUIC_EXPORT_PRIVATE std::vector<QuicString> QuicParseCommandLineFlagsImpl(
+QUIC_EXPORT_PRIVATE std::vector<std::string> QuicParseCommandLineFlagsImpl(
     const char* usage,
     int argc,
     const char* const* argv);
@@ -190,7 +190,7 @@
   QuicParseCommandLineFlagsResult(const QuicParseCommandLineFlagsResult&);
   ~QuicParseCommandLineFlagsResult();
 
-  std::vector<QuicString> non_flag_args;
+  std::vector<std::string> non_flag_args;
   base::Optional<int> exit_status;
 };
 
diff --git a/net/quic/platform/impl/quic_flags_test.cc b/net/quic/platform/impl/quic_flags_test.cc
index 115f22e..d5f3d7c6 100644
--- a/net/quic/platform/impl/quic_flags_test.cc
+++ b/net/quic/platform/impl/quic_flags_test.cc
@@ -17,10 +17,7 @@
 
 DEFINE_QUIC_COMMAND_LINE_FLAG(bool, foo, false, "An old silent pond...");
 DEFINE_QUIC_COMMAND_LINE_FLAG(int32_t, bar, 123, "A frog jumps into the pond,");
-DEFINE_QUIC_COMMAND_LINE_FLAG(quic::QuicString,
-                              baz,
-                              "splash!",
-                              "Silence again.");
+DEFINE_QUIC_COMMAND_LINE_FLAG(std::string, baz, "splash!", "Silence again.");
 
 namespace quic {
 namespace test {
@@ -70,7 +67,7 @@
   auto parse_result =
       QuicParseCommandLineFlagsForTest("usage message", base::size(argv), argv);
   EXPECT_FALSE(parse_result.exit_status.has_value());
-  std::vector<QuicString> expected_args{"two", "three"};
+  std::vector<std::string> expected_args{"two", "three"};
   EXPECT_EQ(expected_args, parse_result.non_flag_args);
 
   EXPECT_EQ(false, GetQuicFlag(FLAGS_foo));
diff --git a/net/quic/platform/impl/quic_hostname_utils_impl.cc b/net/quic/platform/impl/quic_hostname_utils_impl.cc
index 772cc43..661763bb 100644
--- a/net/quic/platform/impl/quic_hostname_utils_impl.cc
+++ b/net/quic/platform/impl/quic_hostname_utils_impl.cc
@@ -26,7 +26,7 @@
 }
 
 // static
-QuicString QuicHostnameUtilsImpl::NormalizeHostname(QuicStringPiece hostname) {
+std::string QuicHostnameUtilsImpl::NormalizeHostname(QuicStringPiece hostname) {
   url::CanonHostInfo host_info;
   std::string host(net::CanonicalizeHost(
       base::StringPiece(hostname.data(), hostname.size()), &host_info));
diff --git a/net/quic/platform/impl/quic_hostname_utils_impl.h b/net/quic/platform/impl/quic_hostname_utils_impl.h
index 4a698412..a168a58 100644
--- a/net/quic/platform/impl/quic_hostname_utils_impl.h
+++ b/net/quic/platform/impl/quic_hostname_utils_impl.h
@@ -22,7 +22,7 @@
 
   // Convert hostname to lowercase and remove the trailing '.'.
   // WARNING: mutates |hostname| in place and returns |hostname|.
-  static QuicString NormalizeHostname(QuicStringPiece hostname);
+  static std::string NormalizeHostname(QuicStringPiece hostname);
 
  private:
   DISALLOW_COPY_AND_ASSIGN(QuicHostnameUtilsImpl);
diff --git a/net/quic/platform/impl/quic_linux_socket_utils_test.cc b/net/quic/platform/impl/quic_linux_socket_utils_test.cc
index e87a16b..6be5762 100644
--- a/net/quic/platform/impl/quic_linux_socket_utils_test.cc
+++ b/net/quic/platform/impl/quic_linux_socket_utils_test.cc
@@ -81,7 +81,7 @@
   EXPECT_EQ(cmsg->cmsg_level, is_ipv4 ? IPPROTO_IP : IPPROTO_IPV6);
   EXPECT_EQ(cmsg->cmsg_type, is_ipv4 ? IP_PKTINFO : IPV6_PKTINFO);
 
-  const QuicString& self_addr_str = self_addr.ToPackedString();
+  const std::string& self_addr_str = self_addr.ToPackedString();
   if (is_ipv4) {
     in_pktinfo* pktinfo = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg));
     EXPECT_EQ(0, memcmp(&pktinfo->ipi_spec_dst, self_addr_str.c_str(),
@@ -188,7 +188,7 @@
   QuicDeque<BufferedWrite> buffered_writes;
   const int kNumBufferedWrites = 10;
   static_assert(kNumBufferedWrites < 256, "Must be less than 256");
-  std::vector<QuicString> buffer_holder;
+  std::vector<std::string> buffer_holder;
   for (int i = 0; i < kNumBufferedWrites; ++i) {
     size_t buf_len = (i + 1) * 2;
     std::ostringstream buffer_ostream;
diff --git a/net/quic/platform/impl/quic_socket_utils.cc b/net/quic/platform/impl/quic_socket_utils.cc
index 47680f1..3bf2477 100644
--- a/net/quic/platform/impl/quic_socket_utils.cc
+++ b/net/quic/platform/impl/quic_socket_utils.cc
@@ -359,7 +359,7 @@
 void QuicSocketUtils::SetIpInfoInCmsgData(const QuicIpAddress& self_address,
                                           void* cmsg_data) {
   DCHECK(self_address.IsInitialized());
-  const QuicString& address_str = self_address.ToPackedString();
+  const std::string& address_str = self_address.ToPackedString();
   if (self_address.IsIPv4()) {
     in_pktinfo* pktinfo = static_cast<in_pktinfo*>(cmsg_data);
     pktinfo->ipi_ifindex = 0;
diff --git a/net/quic/platform/impl/quic_string_utils_impl.h b/net/quic/platform/impl/quic_string_utils_impl.h
index ee31278..b737f752 100644
--- a/net/quic/platform/impl/quic_string_utils_impl.h
+++ b/net/quic/platform/impl/quic_string_utils_impl.h
@@ -18,7 +18,7 @@
 namespace quic {
 
 template <typename... Args>
-inline void QuicStrAppendImpl(QuicString* output, const Args&... args) {
+inline void QuicStrAppendImpl(std::string* output, const Args&... args) {
   output->append(QuicStrCatImpl(args...));
 }
 
diff --git a/net/quic/platform/impl/quic_thread_impl.h b/net/quic/platform/impl/quic_thread_impl.h
index cb635343..ecb614d7 100644
--- a/net/quic/platform/impl/quic_thread_impl.h
+++ b/net/quic/platform/impl/quic_thread_impl.h
@@ -13,7 +13,7 @@
 // A class representing a thread of execution in QUIC.
 class QuicThreadImpl : public base::SimpleThread {
  public:
-  QuicThreadImpl(const QuicString& string) : base::SimpleThread(string) {}
+  QuicThreadImpl(const std::string& string) : base::SimpleThread(string) {}
   QuicThreadImpl(const QuicThreadImpl&) = delete;
   QuicThreadImpl& operator=(const QuicThreadImpl&) = delete;
 };
diff --git a/net/quic/quic_chromium_client_stream_test.cc b/net/quic/quic_chromium_client_stream_test.cc
index 9c663a2..90ee9828 100644
--- a/net/quic/quic_chromium_client_stream_test.cc
+++ b/net/quic/quic_chromium_client_stream_test.cc
@@ -256,14 +256,14 @@
     stream->Reset(quic::QUIC_STREAM_CANCELLED);
   }
 
-  quic::QuicString ConstructDataHeader(size_t body_len) {
+  std::string ConstructDataHeader(size_t body_len) {
     if (GetParam() != quic::QUIC_VERSION_99) {
       return "";
     }
     quic::HttpEncoder encoder;
     std::unique_ptr<char[]> buffer;
     auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
-    return quic::QuicString(buffer.get(), header_length);
+    return std::string(buffer.get(), header_length);
   }
 
   quic::QuicCryptoClientConfig crypto_config_;
@@ -313,7 +313,7 @@
   const size_t kDataLen = base::size(kData1);
 
   // All data written.
-  quic::QuicString header = ConstructDataHeader(kDataLen);
+  std::string header = ConstructDataHeader(kDataLen);
   if (GetParam() == quic::QUIC_VERSION_99) {
     EXPECT_CALL(session_, WritevData(stream_, stream_->id(), _, _, _))
         .WillOnce(Return(quic::QuicConsumedData(header.length(), false)));
@@ -425,7 +425,7 @@
   int data_len = strlen(data);
   size_t offset = 0;
   if (GetParam() == quic::QUIC_VERSION_99) {
-    quic::QuicString header = ConstructDataHeader(data_len);
+    std::string header = ConstructDataHeader(data_len);
     stream_->OnStreamFrame(quic::QuicStreamFrame(
         quic::test::GetNthClientInitiatedBidirectionalStreamId(GetParam(), 0),
         /*fin=*/false,
@@ -461,7 +461,7 @@
 
   size_t offset = 0;
   if (GetParam() == quic::QUIC_VERSION_99) {
-    quic::QuicString header = ConstructDataHeader(data_len);
+    std::string header = ConstructDataHeader(data_len);
     stream_->OnStreamFrame(quic::QuicStreamFrame(
         quic::test::GetNthClientInitiatedBidirectionalStreamId(GetParam(), 0),
         /*fin=*/false,
@@ -521,7 +521,7 @@
   // Receive the data and close the stream during the callback.
   size_t offset = 0;
   if (GetParam() == quic::QUIC_VERSION_99) {
-    quic::QuicString header = ConstructDataHeader(data_len);
+    std::string header = ConstructDataHeader(data_len);
     stream_->OnStreamFrame(quic::QuicStreamFrame(
         quic::test::GetNthClientInitiatedBidirectionalStreamId(GetParam(), 0),
         /*fin=*/false,
@@ -551,7 +551,7 @@
   int data_len = strlen(data);
   size_t offset = 0;
   if (GetParam() == quic::QUIC_VERSION_99) {
-    quic::QuicString header = ConstructDataHeader(data_len);
+    std::string header = ConstructDataHeader(data_len);
     stream_->OnStreamFrame(quic::QuicStreamFrame(
         quic::test::GetNthClientInitiatedBidirectionalStreamId(GetParam(), 0),
         /*fin=*/false,
@@ -603,7 +603,7 @@
   int data_len = strlen(data);
   size_t offset = 0;
   if (GetParam() == quic::QUIC_VERSION_99) {
-    quic::QuicString header = ConstructDataHeader(data_len);
+    std::string header = ConstructDataHeader(data_len);
     stream_->OnStreamFrame(quic::QuicStreamFrame(
         quic::test::GetNthClientInitiatedBidirectionalStreamId(GetParam(), 0),
         /*fin=*/false,
@@ -662,7 +662,7 @@
   int data_len = strlen(data);
   size_t offset = 0;
   if (GetParam() == quic::QUIC_VERSION_99) {
-    quic::QuicString header = ConstructDataHeader(data_len);
+    std::string header = ConstructDataHeader(data_len);
     stream_->OnStreamFrame(quic::QuicStreamFrame(
         quic::test::GetNthClientInitiatedBidirectionalStreamId(GetParam(), 0),
         /*fin=*/false,
@@ -725,7 +725,7 @@
 
   // All data written.
   if (GetParam() == quic::QUIC_VERSION_99) {
-    quic::QuicString header = ConstructDataHeader(kDataLen);
+    std::string header = ConstructDataHeader(kDataLen);
     EXPECT_CALL(session_, WritevData(stream_, stream_->id(), _, _, _))
         .WillOnce(Return(quic::QuicConsumedData(header.length(), false)));
   }
@@ -753,7 +753,7 @@
 
   // All data written.
   if (GetParam() == quic::QUIC_VERSION_99) {
-    quic::QuicString header = ConstructDataHeader(kDataLen);
+    std::string header = ConstructDataHeader(kDataLen);
     EXPECT_CALL(session_, WritevData(stream_, stream_->id(), _, _, _))
         .WillOnce(Return(quic::QuicConsumedData(header.length(), false)));
   }
@@ -777,14 +777,14 @@
 
   // All data written.
   if (GetParam() == quic::QUIC_VERSION_99) {
-    quic::QuicString header = ConstructDataHeader(buf1->size());
+    std::string header = ConstructDataHeader(buf1->size());
     EXPECT_CALL(session_, WritevData(stream_, stream_->id(), _, _, _))
         .WillOnce(Return(quic::QuicConsumedData(header.length(), false)));
   }
   EXPECT_CALL(session_, WritevData(stream_, stream_->id(), _, _, _))
       .WillOnce(Return(quic::QuicConsumedData(buf1->size(), false)));
   if (GetParam() == quic::QUIC_VERSION_99) {
-    quic::QuicString header = ConstructDataHeader(buf2->size());
+    std::string header = ConstructDataHeader(buf2->size());
     EXPECT_CALL(session_, WritevData(stream_, stream_->id(), _, _, _))
         .WillOnce(Return(quic::QuicConsumedData(header.length(), false)));
   }
@@ -805,7 +805,7 @@
 
   // Only a part of the data is written.
   if (GetParam() == quic::QUIC_VERSION_99) {
-    quic::QuicString header = ConstructDataHeader(buf1->size());
+    std::string header = ConstructDataHeader(buf1->size());
     EXPECT_CALL(session_, WritevData(stream_, stream_->id(), _, _, _))
         .WillOnce(Return(quic::QuicConsumedData(header.length(), false)));
   }
@@ -824,7 +824,7 @@
 
   // The second piece of data is written.
   if (GetParam() == quic::QUIC_VERSION_99) {
-    quic::QuicString header = ConstructDataHeader(buf2->size());
+    std::string header = ConstructDataHeader(buf2->size());
     EXPECT_CALL(session_, WritevData(stream_, stream_->id(), _, _, _))
         .WillOnce(Return(quic::QuicConsumedData(header.length(), false)));
   }
@@ -881,7 +881,7 @@
 
   size_t offset = 0;
   if (GetParam() == quic::QUIC_VERSION_99) {
-    quic::QuicString header = ConstructDataHeader(strlen(data));
+    std::string header = ConstructDataHeader(strlen(data));
     stream2->OnStreamFrame(quic::QuicStreamFrame(stream_id,
                                                  /*fin=*/false,
                                                  /*offset=*/offset, header));
diff --git a/net/quic/quic_http_stream_test.cc b/net/quic/quic_http_stream_test.cc
index 2dd974a2..fc38079d 100644
--- a/net/quic/quic_http_stream_test.cc
+++ b/net/quic/quic_http_stream_test.cc
@@ -638,14 +638,14 @@
     return client_maker_.MakeInitialSettingsPacket(1, offset);
   }
 
-  quic::QuicString ConstructDataHeader(size_t body_len) {
+  std::string ConstructDataHeader(size_t body_len) {
     if (version_ != quic::QUIC_VERSION_99) {
       return "";
     }
     quic::HttpEncoder encoder;
     std::unique_ptr<char[]> buffer;
     auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
-    return quic::QuicString(buffer.get(), header_length);
+    return std::string(buffer.get(), header_length);
   }
 
   void ReceivePromise(quic::QuicStreamId id) {
@@ -949,7 +949,7 @@
 
   // Send the response body.
   const char kResponseBody[] = "Hello world!";
-  quic::QuicString header = ConstructDataHeader(strlen(kResponseBody));
+  std::string header = ConstructDataHeader(strlen(kResponseBody));
   ProcessPacket(ConstructServerDataPacket(3, false, !kFin, /*offset=*/0,
                                           header + kResponseBody));
   spdy::SpdyHeaderBlock trailers;
@@ -1244,7 +1244,7 @@
   quic::QuicStreamOffset header_stream_offset = 0;
   AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
 
-  quic::QuicString header = ConstructDataHeader(strlen(kUploadData));
+  std::string header = ConstructDataHeader(strlen(kUploadData));
   if (version_ != quic::QUIC_VERSION_99) {
     AddWrite(ConstructRequestHeadersAndDataFramesPacket(
         2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
@@ -1296,7 +1296,7 @@
 
   // Send the response body.
   const char kResponseBody[] = "Hello world!";
-  quic::QuicString header2 = ConstructDataHeader(strlen(kResponseBody));
+  std::string header2 = ConstructDataHeader(strlen(kResponseBody));
   ProcessPacket(
       ConstructServerDataPacket(3, false, kFin, 0, header2 + kResponseBody));
   // Since the body has already arrived, this should return immediately.
@@ -1325,7 +1325,7 @@
   size_t spdy_request_headers_frame_length;
   quic::QuicStreamOffset header_stream_offset = 0;
   AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
-  quic::QuicString header = ConstructDataHeader(strlen(kUploadData));
+  std::string header = ConstructDataHeader(strlen(kUploadData));
   if (version_ != quic::QUIC_VERSION_99) {
     AddWrite(ConstructRequestHeadersAndDataFramesPacket(
         2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion, kFin,
@@ -1377,7 +1377,7 @@
 
   // Send the response body.
   const char kResponseBody[] = "Hello world!";
-  quic::QuicString header2 = ConstructDataHeader(strlen(kResponseBody));
+  std::string header2 = ConstructDataHeader(strlen(kResponseBody));
   ProcessPacket(
       ConstructServerDataPacket(3, false, !kFin, 0, header2 + kResponseBody));
   // Since the body has already arrived, this should return immediately.
@@ -1409,7 +1409,7 @@
   size_t spdy_request_headers_frame_length;
   quic::QuicStreamOffset header_stream_offset = 0;
   AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
-  quic::QuicString header = ConstructDataHeader(chunk_size);
+  std::string header = ConstructDataHeader(chunk_size);
   if (version_ == quic::QUIC_VERSION_99) {
     AddWrite(ConstructRequestHeadersAndDataFramesPacket(
         2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
@@ -1467,7 +1467,7 @@
 
   // Send the response body.
   const char kResponseBody[] = "Hello world!";
-  quic::QuicString header2 = ConstructDataHeader(strlen(kResponseBody));
+  std::string header2 = ConstructDataHeader(strlen(kResponseBody));
   ProcessPacket(ConstructServerDataPacket(
       3, false, kFin, response_data_.length(), header2 + kResponseBody));
 
@@ -1495,7 +1495,7 @@
   size_t spdy_request_headers_frame_length;
   quic::QuicStreamOffset header_stream_offset = 0;
   AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
-  quic::QuicString header = ConstructDataHeader(chunk_size);
+  std::string header = ConstructDataHeader(chunk_size);
 
   if (version_ != quic::QUIC_VERSION_99) {
     AddWrite(ConstructRequestHeadersAndDataFramesPacket(
@@ -1549,7 +1549,7 @@
 
   // Send the response body.
   const char kResponseBody[] = "Hello world!";
-  quic::QuicString header2 = ConstructDataHeader(strlen(kResponseBody));
+  std::string header2 = ConstructDataHeader(strlen(kResponseBody));
   ProcessPacket(ConstructServerDataPacket(
       3, false, kFin, response_data_.length(), header2 + kResponseBody));
 
@@ -1618,7 +1618,7 @@
 
   // Send the response body.
   const char kResponseBody[] = "Hello world!";
-  quic::QuicString header = ConstructDataHeader(strlen(kResponseBody));
+  std::string header = ConstructDataHeader(strlen(kResponseBody));
   ProcessPacket(ConstructServerDataPacket(
       3, false, kFin, response_data_.length(), header + kResponseBody));
 
@@ -1733,7 +1733,7 @@
   size_t spdy_request_headers_frame_length;
   quic::QuicStreamOffset header_stream_offset = 0;
   AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
-  quic::QuicString header = ConstructDataHeader(strlen(kUploadData));
+  std::string header = ConstructDataHeader(strlen(kUploadData));
   if (version_ != quic::QUIC_VERSION_99) {
     AddWrite(ConstructRequestHeadersAndDataFramesPacket(
         2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
@@ -1894,7 +1894,7 @@
   size_t spdy_request_headers_frame_length;
   quic::QuicStreamOffset header_stream_offset = 0;
   AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
-  quic::QuicString header = ConstructDataHeader(strlen(kUploadData));
+  std::string header = ConstructDataHeader(strlen(kUploadData));
   if (version_ != quic::QUIC_VERSION_99) {
     AddWrite(ConstructRequestHeadersAndDataFramesPacket(
         2, GetNthClientInitiatedBidirectionalStreamId(0), kIncludeVersion,
@@ -1976,7 +1976,7 @@
 
   // Receive the promised response body.
   const char kResponseBody[] = "Hello world!";
-  quic::QuicString header = ConstructDataHeader(strlen(kResponseBody));
+  std::string header = ConstructDataHeader(strlen(kResponseBody));
   ProcessPacket(InnerConstructDataPacket(
       2, promise_id_, false, kFin, 0, header + kResponseBody, &server_maker_));
 
@@ -2048,7 +2048,7 @@
 
   // Receive the promised response body.
   const char kResponseBody[] = "Hello world!";
-  quic::QuicString header = ConstructDataHeader(strlen(kResponseBody));
+  std::string header = ConstructDataHeader(strlen(kResponseBody));
   ProcessPacket(InnerConstructDataPacket(
       2, promise_id_, false, kFin, 0, header + kResponseBody, &server_maker_));
 
@@ -2164,7 +2164,7 @@
 
   // Receive the promised response body.
   const char kResponseBody[] = "Hello world!";
-  quic::QuicString header = ConstructDataHeader(strlen(kResponseBody));
+  std::string header = ConstructDataHeader(strlen(kResponseBody));
   ProcessPacket(InnerConstructDataPacket(
       2, promise_id_, false, kFin, 0, header + kResponseBody, &server_maker_));
 
@@ -2264,7 +2264,7 @@
 
   // Receive the promised response body.
   const char kResponseBody[] = "Hello world!";
-  quic::QuicString header = ConstructDataHeader(strlen(kResponseBody));
+  std::string header = ConstructDataHeader(strlen(kResponseBody));
   ProcessPacket(InnerConstructDataPacket(
       2, promise_id_, false, kFin, 0, header + kResponseBody, &server_maker_));
 
diff --git a/net/quic/quic_network_transaction_unittest.cc b/net/quic/quic_network_transaction_unittest.cc
index cfa1b43..d2350cb 100644
--- a/net/quic/quic_network_transaction_unittest.cc
+++ b/net/quic/quic_network_transaction_unittest.cc
@@ -673,14 +673,14 @@
         std::move(headers), offset);
   }
 
-  quic::QuicString ConstructDataHeader(size_t body_len) {
+  std::string ConstructDataHeader(size_t body_len) {
     if (version_ != quic::QUIC_VERSION_99) {
       return "";
     }
     quic::HttpEncoder encoder;
     std::unique_ptr<char[]> buffer;
     auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
-    return quic::QuicString(buffer.get(), header_length);
+    return std::string(buffer.get(), header_length);
   }
 
   void CreateSession(
@@ -1088,7 +1088,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -1125,7 +1125,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -1162,7 +1162,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -1256,7 +1256,7 @@
                    offset, base::StringPiece(spdy_frame.data() + offset, len)));
   }
 
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
@@ -1315,7 +1315,7 @@
                    offset, base::StringPiece(spdy_frame.data() + offset, len)));
   }
 
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
 
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
@@ -1357,7 +1357,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -1392,7 +1392,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -1441,7 +1441,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -1502,7 +1502,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -1592,7 +1592,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -1786,7 +1786,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -1855,7 +1855,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -1918,7 +1918,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -1963,7 +1963,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -2088,7 +2088,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -2149,7 +2149,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -2192,7 +2192,7 @@
                              2, quic::QUIC_ERROR_MIGRATING_PORT,
                              "connection migration with port change only"));
   mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       SYNCHRONOUS, ConstructServerDataPacket(
                        3, GetNthClientInitiatedBidirectionalStreamId(0), false,
@@ -2546,8 +2546,8 @@
   quic_data2.AddWrite(SYNCHRONOUS,
                       client_maker_.MakeDummyCHLOPacket(1));  // CHLO
 
-  const quic::QuicString body = "hello!";
-  quic::QuicString header = ConstructDataHeader(body.length());
+  const std::string body = "hello!";
+  std::string header = ConstructDataHeader(body.length());
 
   client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
   quic_data2.AddWrite(SYNCHRONOUS,
@@ -3949,7 +3949,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK"), &response_header_offset));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -4025,7 +4025,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK"), &response_header_offset));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -4176,7 +4176,7 @@
       ConstructServerResponseHeadersPacket(
           1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
           GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -4246,7 +4246,7 @@
       ConstructServerResponseHeadersPacket(
           1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
           GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -4329,7 +4329,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK"), &response_header_offset));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -4415,7 +4415,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK"), &response_header_offset));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -4556,7 +4556,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK"), &response_header_offset));
-  quic::QuicString header = ConstructDataHeader(21);
+  std::string header = ConstructDataHeader(21);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -4663,7 +4663,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -4720,7 +4720,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -4757,7 +4757,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -4859,7 +4859,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -4894,7 +4894,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -4962,7 +4962,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -5046,7 +5046,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
                  GetResponseHeaders("200 OK"), &server_header_stream_offset));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
@@ -5514,7 +5514,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -5574,7 +5574,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -5864,7 +5864,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -6028,7 +6028,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   socket_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -6064,7 +6064,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   socket_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -6164,7 +6164,7 @@
   session_params_.retry_without_alt_svc_on_quic_errors = false;
   session_params_.origins_to_force_quic_on.insert(
       HostPortPair::FromString("mail.example.org:443"));
-  const quic::QuicString error_details =
+  const std::string error_details =
       quic::QuicStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
                        strerror(ERR_MSG_TOO_BIG), ")");
 
@@ -6235,14 +6235,14 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
                  false, GetResponseHeaders("200 OK"), &server_header_offset));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
                  0, header + "hello!"));
   mock_quic_data.AddWrite(
       SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
-  quic::QuicString header2 = ConstructDataHeader(10);
+  std::string header2 = ConstructDataHeader(10);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
@@ -6328,7 +6328,7 @@
   mock_quic_data.AddWrite(
       SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
   // Response body for first request.
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -6386,7 +6386,7 @@
   mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
                                            write_packet_index++, &offset));
 
-  quic::QuicString header = ConstructDataHeader(1);
+  std::string header = ConstructDataHeader(1);
   if (version_ != quic::QUIC_VERSION_99) {
     mock_quic_data.AddWrite(
         SYNCHRONOUS,
@@ -6410,7 +6410,7 @@
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
 
-  quic::QuicString header2 = ConstructDataHeader(6);
+  std::string header2 = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -6494,7 +6494,7 @@
           1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
           GetResponseHeaders("200 OK"), &expected_raw_header_response_size));
 
-  quic::QuicString header = ConstructDataHeader(18);
+  std::string header = ConstructDataHeader(18);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -6593,7 +6593,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
                  false, GetResponseHeaders("200 OK"), &server_header_offset));
-  quic::QuicString header = ConstructDataHeader(20);
+  std::string header = ConstructDataHeader(20);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
@@ -6601,7 +6601,7 @@
 
   mock_quic_data.AddWrite(
       SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
-  quic::QuicString header2 = ConstructDataHeader(18);
+  std::string header2 = ConstructDataHeader(18);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -6672,7 +6672,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
                  GetResponseHeaders("200 OK")));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -6858,12 +6858,12 @@
       uint64_t packet_number,
       quic::QuicStreamId stream_id,
       QuicTestPacketMaker* maker) {
-    quic::QuicString header = "";
+    std::string header = "";
     if (version_ == quic::QUIC_VERSION_99) {
       quic::HttpEncoder encoder;
       std::unique_ptr<char[]> buffer;
       auto header_length = encoder.SerializeDataFrameHeader(5, &buffer);
-      header = quic::QuicString(buffer.get(), header_length);
+      header = std::string(buffer.get(), header_length);
     }
     return maker->MakeDataPacket(packet_number, stream_id, false, true, 0,
                                  header + "hello");
@@ -7261,7 +7261,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
                  false, GetResponseHeaders("200 OK"), &server_header_offset));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -7269,7 +7269,7 @@
   mock_quic_data.AddWrite(
       SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
 
-  quic::QuicString header2 = ConstructDataHeader(10);
+  std::string header2 = ConstructDataHeader(10);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
@@ -7284,7 +7284,7 @@
                               GetNthServerInitiatedUnidirectionalStreamId(0),
                               quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
   const char kBody[] = "1";
-  quic::QuicString header3 = ConstructDataHeader(1);
+  std::string header3 = ConstructDataHeader(1);
   if (version_ != quic::QUIC_VERSION_99) {
     mock_quic_data.AddWrite(
         SYNCHRONOUS,
@@ -7384,7 +7384,7 @@
       ASYNC, ConstructServerResponseHeadersPacket(
                  3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
                  false, GetResponseHeaders("200 OK"), &server_header_offset));
-  quic::QuicString header = ConstructDataHeader(6);
+  std::string header = ConstructDataHeader(6);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
@@ -7432,7 +7432,7 @@
       "GET / HTTP/1.1\r\n"
       "Host: mail.example.org\r\n"
       "Connection: keep-alive\r\n\r\n";
-  quic::QuicString header = ConstructDataHeader(strlen(get_request));
+  std::string header = ConstructDataHeader(strlen(get_request));
   if (version_ != quic::QUIC_VERSION_99) {
     mock_quic_data.AddWrite(
         SYNCHRONOUS,
@@ -7444,23 +7444,23 @@
         SYNCHRONOUS,
         ConstructClientAckAndMultipleDataFramesPacket(
             3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
-            false, 0, {header, quic::QuicString(get_request)}));
+            false, 0, {header, std::string(get_request)}));
   }
 
   const char get_response[] =
       "HTTP/1.1 200 OK\r\n"
       "Content-Length: 10\r\n\r\n";
-  quic::QuicString header2 = ConstructDataHeader(strlen(get_response));
+  std::string header2 = ConstructDataHeader(strlen(get_response));
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
-                 0, header2 + quic::QuicString(get_response)));
-  quic::QuicString header3 = ConstructDataHeader(10);
+                 0, header2 + std::string(get_response)));
+  std::string header3 = ConstructDataHeader(10);
   mock_quic_data.AddRead(
       SYNCHRONOUS, ConstructServerDataPacket(
                        3, GetNthClientInitiatedBidirectionalStreamId(0), false,
                        false, strlen(get_response) + header2.length(),
-                       header3 + quic::QuicString("0123456789")));
+                       header3 + std::string("0123456789")));
   mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
   mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);  // No more data to read
 
@@ -7524,7 +7524,7 @@
 
   spdy::SpdySerializedFrame get_frame =
       spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
-  quic::QuicString header = ConstructDataHeader(get_frame.size());
+  std::string header = ConstructDataHeader(get_frame.size());
   if (version_ != quic::QUIC_VERSION_99) {
     mock_quic_data.AddWrite(
         SYNCHRONOUS,
@@ -7538,26 +7538,26 @@
         ConstructClientAckAndMultipleDataFramesPacket(
             3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
             false, 0,
-            {header, quic::QuicString(get_frame.data(), get_frame.size())}));
+            {header, std::string(get_frame.data(), get_frame.size())}));
   }
   spdy::SpdySerializedFrame resp_frame =
       spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
-  quic::QuicString header2 = ConstructDataHeader(resp_frame.size());
+  std::string header2 = ConstructDataHeader(resp_frame.size());
   mock_quic_data.AddRead(
       ASYNC,
       ConstructServerDataPacket(
           2, GetNthClientInitiatedBidirectionalStreamId(0), false, false, 0,
-          header2 + quic::QuicString(resp_frame.data(), resp_frame.size())));
+          header2 + std::string(resp_frame.data(), resp_frame.size())));
 
   spdy::SpdySerializedFrame data_frame =
       spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
-  quic::QuicString header3 = ConstructDataHeader(resp_frame.size());
+  std::string header3 = ConstructDataHeader(resp_frame.size());
   mock_quic_data.AddRead(
       SYNCHRONOUS,
       ConstructServerDataPacket(
           3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
           resp_frame.size() + header2.length(),
-          header3 + quic::QuicString(data_frame.data(), data_frame.size())));
+          header3 + std::string(data_frame.data(), data_frame.size())));
   mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
   mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);  // No more data to read
 
@@ -7628,7 +7628,7 @@
       "GET / HTTP/1.1\r\n"
       "Host: mail.example.org\r\n"
       "Connection: keep-alive\r\n\r\n";
-  quic::QuicString header = ConstructDataHeader(strlen(get_request_1));
+  std::string header = ConstructDataHeader(strlen(get_request_1));
   if (version_ != quic::QUIC_VERSION_99) {
     mock_quic_data.AddWrite(
         SYNCHRONOUS,
@@ -7642,7 +7642,7 @@
         ConstructClientAckAndMultipleDataFramesPacket(
             write_packet_index++, false,
             GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false,
-            client_data_offset, {header, quic::QuicString(get_request_1)}));
+            client_data_offset, {header, std::string(get_request_1)}));
   }
 
   client_data_offset += strlen(get_request_1) + header.length();
@@ -7650,20 +7650,19 @@
   const char get_response_1[] =
       "HTTP/1.1 200 OK\r\n"
       "Content-Length: 10\r\n\r\n";
-  quic::QuicString header2 = ConstructDataHeader(strlen(get_response_1));
+  std::string header2 = ConstructDataHeader(strlen(get_response_1));
   mock_quic_data.AddRead(
-      ASYNC,
-      ConstructServerDataPacket(
-          2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
-          server_data_offset, header2 + quic::QuicString(get_response_1)));
+      ASYNC, ConstructServerDataPacket(
+                 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
+                 server_data_offset, header2 + std::string(get_response_1)));
   server_data_offset += strlen(get_response_1) + header2.length();
 
-  quic::QuicString header3 = ConstructDataHeader(10);
+  std::string header3 = ConstructDataHeader(10);
   mock_quic_data.AddRead(
       SYNCHRONOUS,
       ConstructServerDataPacket(
           3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
-          server_data_offset, header3 + quic::QuicString("0123456789")));
+          server_data_offset, header3 + std::string("0123456789")));
   server_data_offset += 10 + header3.length();
 
   mock_quic_data.AddWrite(
@@ -7673,14 +7672,14 @@
       "GET /2 HTTP/1.1\r\n"
       "Host: mail.example.org\r\n"
       "Connection: keep-alive\r\n\r\n";
-  quic::QuicString header4 = ConstructDataHeader(strlen(get_request_2));
+  std::string header4 = ConstructDataHeader(strlen(get_request_2));
   if (version_ == quic::QUIC_VERSION_99) {
     mock_quic_data.AddWrite(
         SYNCHRONOUS,
         ConstructClientMultipleDataFramesPacket(
             write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
             false, false, client_data_offset,
-            {header4, quic::QuicString(get_request_2)}));
+            {header4, std::string(get_request_2)}));
     client_data_offset += header4.length() + strlen(get_request_2);
   } else {
     mock_quic_data.AddWrite(
@@ -7695,20 +7694,19 @@
   const char get_response_2[] =
       "HTTP/1.1 200 OK\r\n"
       "Content-Length: 7\r\n\r\n";
-  quic::QuicString header5 = ConstructDataHeader(strlen(get_response_2));
+  std::string header5 = ConstructDataHeader(strlen(get_response_2));
   mock_quic_data.AddRead(
-      ASYNC,
-      ConstructServerDataPacket(
-          4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
-          server_data_offset, header5 + quic::QuicString(get_response_2)));
+      ASYNC, ConstructServerDataPacket(
+                 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
+                 server_data_offset, header5 + std::string(get_response_2)));
   server_data_offset += strlen(get_response_2) + header5.length();
 
-  quic::QuicString header6 = ConstructDataHeader(7);
+  std::string header6 = ConstructDataHeader(7);
   mock_quic_data.AddRead(
       SYNCHRONOUS,
       ConstructServerDataPacket(
           5, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
-          server_data_offset, header6 + quic::QuicString("0123456")));
+          server_data_offset, header6 + std::string("0123456")));
   server_data_offset += 7 + header6.length();
 
   mock_quic_data.AddWrite(
@@ -7793,7 +7791,7 @@
       "GET / HTTP/1.1\r\n"
       "Host: mail.example.org\r\n"
       "Connection: keep-alive\r\n\r\n";
-  quic::QuicString header = ConstructDataHeader(strlen(get_request));
+  std::string header = ConstructDataHeader(strlen(get_request));
   if (version_ != quic::QUIC_VERSION_99) {
     mock_quic_data.AddWrite(
         SYNCHRONOUS,
@@ -7805,23 +7803,23 @@
         SYNCHRONOUS,
         ConstructClientAckAndMultipleDataFramesPacket(
             3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
-            false, 0, {header, quic::QuicString(get_request)}));
+            false, 0, {header, std::string(get_request)}));
   }
 
   const char get_response[] =
       "HTTP/1.1 200 OK\r\n"
       "Content-Length: 10\r\n\r\n";
-  quic::QuicString header2 = ConstructDataHeader(strlen(get_response));
+  std::string header2 = ConstructDataHeader(strlen(get_response));
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
-                 0, header2 + quic::QuicString(get_response)));
-  quic::QuicString header3 = ConstructDataHeader(10);
+                 0, header2 + std::string(get_response)));
+  std::string header3 = ConstructDataHeader(10);
   mock_quic_data.AddRead(
       SYNCHRONOUS, ConstructServerDataPacket(
                        3, GetNthClientInitiatedBidirectionalStreamId(0), false,
                        false, strlen(get_response) + header2.length(),
-                       header3 + quic::QuicString("0123456789")));
+                       header3 + std::string("0123456789")));
   mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
 
   // CONNECT request and response for second request
@@ -7841,7 +7839,7 @@
   SpdyTestUtil spdy_util;
   spdy::SpdySerializedFrame get_frame =
       spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
-  quic::QuicString header4 = ConstructDataHeader(get_frame.size());
+  std::string header4 = ConstructDataHeader(get_frame.size());
   if (version_ != quic::QUIC_VERSION_99) {
     mock_quic_data.AddWrite(
         SYNCHRONOUS,
@@ -7855,27 +7853,26 @@
         ConstructClientAckAndMultipleDataFramesPacket(
             6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
             false, 0,
-            {header4, quic::QuicString(get_frame.data(), get_frame.size())}));
+            {header4, std::string(get_frame.data(), get_frame.size())}));
   }
 
   spdy::SpdySerializedFrame resp_frame =
       spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
-  quic::QuicString header5 = ConstructDataHeader(resp_frame.size());
+  std::string header5 = ConstructDataHeader(resp_frame.size());
   mock_quic_data.AddRead(
       ASYNC,
       ConstructServerDataPacket(
           5, GetNthClientInitiatedBidirectionalStreamId(1), false, false, 0,
-          header5 + quic::QuicString(resp_frame.data(), resp_frame.size())));
+          header5 + std::string(resp_frame.data(), resp_frame.size())));
 
   spdy::SpdySerializedFrame data_frame =
       spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
-  quic::QuicString header6 = ConstructDataHeader(data_frame.size());
+  std::string header6 = ConstructDataHeader(data_frame.size());
   mock_quic_data.AddRead(
-      ASYNC,
-      ConstructServerDataPacket(
-          6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
-          resp_frame.size() + header5.length(),
-          header6 + quic::QuicString(data_frame.data(), data_frame.size())));
+      ASYNC, ConstructServerDataPacket(
+                 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
+                 resp_frame.size() + header5.length(),
+                 header6 + std::string(data_frame.data(), data_frame.size())));
 
   mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(7, 6, 5, 1));
   mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);  // No more data to read
@@ -8063,7 +8060,7 @@
       "GET / HTTP/1.1\r\n"
       "Host: mail.example.org\r\n"
       "Connection: keep-alive\r\n\r\n";
-  quic::QuicString header = ConstructDataHeader(strlen(get_request));
+  std::string header = ConstructDataHeader(strlen(get_request));
   if (version_ != quic::QUIC_VERSION_99) {
     mock_quic_data.AddWrite(
         SYNCHRONOUS,
@@ -8075,23 +8072,23 @@
         SYNCHRONOUS,
         ConstructClientAckAndMultipleDataFramesPacket(
             5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
-            false, 0, {header, quic::QuicString(get_request)}));
+            false, 0, {header, std::string(get_request)}));
   }
   const char get_response[] =
       "HTTP/1.1 200 OK\r\n"
       "Content-Length: 10\r\n\r\n";
-  quic::QuicString header2 = ConstructDataHeader(strlen(get_response));
+  std::string header2 = ConstructDataHeader(strlen(get_response));
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(
                  3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
-                 0, header2 + quic::QuicString(get_response)));
+                 0, header2 + std::string(get_response)));
 
-  quic::QuicString header3 = ConstructDataHeader(10);
+  std::string header3 = ConstructDataHeader(10);
   mock_quic_data.AddRead(
       SYNCHRONOUS, ConstructServerDataPacket(
                        4, GetNthClientInitiatedBidirectionalStreamId(1), false,
                        false, strlen(get_response) + header2.length(),
-                       header3 + quic::QuicString("0123456789")));
+                       header3 + std::string("0123456789")));
   mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(6, 4, 3, 1));
   mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);  // No more data to read
 
@@ -8510,7 +8507,7 @@
           &header_stream_offset));
 
   // Server sends data for the three requests and the two push promises.
-  quic::QuicString header = ConstructDataHeader(8);
+  std::string header = ConstructDataHeader(8);
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true, 0,
                                        header + "hello 0!"));
@@ -8521,7 +8518,7 @@
   mock_quic_data.AddRead(
       ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true, 0,
                                        header + "hello 2!"));
-  quic::QuicString header2 = ConstructDataHeader(12);
+  std::string header2 = ConstructDataHeader(12);
   mock_quic_data.AddRead(
       SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true, 0,
                                              header2 + "and hello 0!"));
diff --git a/net/quic/quic_proxy_client_socket_unittest.cc b/net/quic/quic_proxy_client_socket_unittest.cc
index e0a6bfe..d693d21 100644
--- a/net/quic/quic_proxy_client_socket_unittest.cc
+++ b/net/quic/quic_proxy_client_socket_unittest.cc
@@ -552,14 +552,14 @@
               spdy::SpdyString(read_buf_->data(), len));
   }
 
-  quic::QuicString ConstructDataHeader(size_t body_len) {
+  std::string ConstructDataHeader(size_t body_len) {
     if (version_ != quic::QUIC_VERSION_99) {
       return "";
     }
     quic::HttpEncoder encoder;
     std::unique_ptr<char[]> buffer;
     auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
-    return quic::QuicString(buffer.get(), header_length);
+    return std::string(buffer.get(), header_length);
   }
 
   const quic::QuicTransportVersion version_;
@@ -765,10 +765,9 @@
   mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
   mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause
 
-  quic::QuicString header = ConstructDataHeader(kLen1);
-  mock_quic_data_.AddRead(
-      ASYNC,
-      ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
+  std::string header = ConstructDataHeader(kLen1);
+  mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
+                                     2, 0, header + std::string(kMsg1, kLen1)));
   mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
   mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
   mock_quic_data_.AddWrite(
@@ -798,10 +797,10 @@
   mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
   mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause
 
-  quic::QuicString header = ConstructDataHeader(kLen333);
+  std::string header = ConstructDataHeader(kLen333);
   mock_quic_data_.AddRead(
-      ASYNC, ConstructServerDataPacket(
-                 2, 0, header + quic::QuicString(kMsg333, kLen333)));
+      ASYNC,
+      ConstructServerDataPacket(2, 0, header + std::string(kMsg333, kLen333)));
   mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
   mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
   mock_quic_data_.AddWrite(
@@ -855,27 +854,25 @@
   mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
   mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
   if (version_ == quic::QUIC_VERSION_99) {
-    quic::QuicString header = ConstructDataHeader(kLen1);
+    std::string header = ConstructDataHeader(kLen1);
+    mock_quic_data_.AddWrite(
+        SYNCHRONOUS, ConstructAckAndMultipleDataFramesPacket(
+                         3, 1, 1, 1, 0, {header, std::string(kMsg1, kLen1)}));
+    std::string header2 = ConstructDataHeader(kLen2);
     mock_quic_data_.AddWrite(
         SYNCHRONOUS,
-        ConstructAckAndMultipleDataFramesPacket(
-            3, 1, 1, 1, 0, {header, quic::QuicString(kMsg1, kLen1)}));
-    quic::QuicString header2 = ConstructDataHeader(kLen2);
-    mock_quic_data_.AddWrite(SYNCHRONOUS,
-                             ConstructMultipleDataFramesPacket(
-                                 4, kLen1 + header.length(),
-                                 {header2, quic::QuicString(kMsg2, kLen2)}));
+        ConstructMultipleDataFramesPacket(
+            4, kLen1 + header.length(), {header2, std::string(kMsg2, kLen2)}));
     mock_quic_data_.AddWrite(
         SYNCHRONOUS,
         ConstructRstPacket(5, quic::QUIC_STREAM_CANCELLED,
                            kLen1 + kLen2 + header.length() + header2.length()));
   } else {
     mock_quic_data_.AddWrite(
-        SYNCHRONOUS, ConstructAckAndDataPacket(3, 1, 1, 1, 0,
-                                               quic::QuicString(kMsg1, kLen1)));
-    mock_quic_data_.AddWrite(
         SYNCHRONOUS,
-        ConstructDataPacket(4, kLen1, quic::QuicString(kMsg2, kLen2)));
+        ConstructAckAndDataPacket(3, 1, 1, 1, 0, std::string(kMsg1, kLen1)));
+    mock_quic_data_.AddWrite(
+        SYNCHRONOUS, ConstructDataPacket(4, kLen1, std::string(kMsg2, kLen2)));
     mock_quic_data_.AddWrite(
         SYNCHRONOUS,
         ConstructRstPacket(5, quic::QUIC_STREAM_CANCELLED, kLen1 + kLen2));
@@ -897,16 +894,16 @@
                            ConstructConnectRequestPacket(write_packet_index++));
   mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
   mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
-  quic::QuicString header = ConstructDataHeader(kLen1);
+  std::string header = ConstructDataHeader(kLen1);
   if (version_ != quic::QUIC_VERSION_99) {
     mock_quic_data_.AddWrite(
         SYNCHRONOUS, ConstructAckAndDataPacket(write_packet_index++, 1, 1, 1, 0,
-                                               quic::QuicString(kMsg1, kLen1)));
+                                               std::string(kMsg1, kLen1)));
   } else {
     mock_quic_data_.AddWrite(SYNCHRONOUS,
                              ConstructAckAndMultipleDataFramesPacket(
                                  write_packet_index++, 1, 1, 1, 0,
-                                 {header, quic::QuicString(kMsg1, kLen1)}));
+                                 {header, std::string(kMsg1, kLen1)}));
   }
 
   // Expect |kNumDataPackets| data packets, each containing the max possible
@@ -926,25 +923,23 @@
         quic::PACKET_1BYTE_PACKET_NUMBER, offset);
     if (version_ == quic::QUIC_VERSION_99 && i == 0) {
       // 3973 is the data frame length from packet length.
-      quic::QuicString header2 = ConstructDataHeader(3973);
+      std::string header2 = ConstructDataHeader(3973);
       mock_quic_data_.AddWrite(
-          SYNCHRONOUS,
-          ConstructMultipleDataFramesPacket(
-              write_packet_index++, offset,
-              {header2,
-               quic::QuicString(data.c_str(), max_packet_data_length - 7)}));
+          SYNCHRONOUS, ConstructMultipleDataFramesPacket(
+                           write_packet_index++, offset,
+                           {header2, std::string(data.c_str(),
+                                                 max_packet_data_length - 7)}));
       offset += max_packet_data_length - header2.length() - 1;
     } else if (version_ == quic::QUIC_VERSION_99 && i == numDataPackets - 1) {
       mock_quic_data_.AddWrite(
           SYNCHRONOUS, ConstructDataPacket(write_packet_index++, offset,
-                                           quic::QuicString(data.c_str(), 7)));
+                                           std::string(data.c_str(), 7)));
       offset += 7;
     } else {
       mock_quic_data_.AddWrite(
-          SYNCHRONOUS,
-          ConstructDataPacket(
-              write_packet_index++, offset,
-              quic::QuicString(data.c_str(), max_packet_data_length)));
+          SYNCHRONOUS, ConstructDataPacket(
+                           write_packet_index++, offset,
+                           std::string(data.c_str(), max_packet_data_length)));
       offset += max_packet_data_length;
     }
     if (i != 3) {
@@ -978,10 +973,9 @@
   mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
   mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause
 
-  quic::QuicString header = ConstructDataHeader(kLen1);
-  mock_quic_data_.AddRead(
-      ASYNC,
-      ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
+  std::string header = ConstructDataHeader(kLen1);
+  mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
+                                     2, 0, header + std::string(kMsg1, kLen1)));
   mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
   mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
   mock_quic_data_.AddWrite(
@@ -1001,17 +995,16 @@
   mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
   mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause
 
-  quic::QuicString header = ConstructDataHeader(kLen1);
-  mock_quic_data_.AddRead(
-      ASYNC,
-      ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
+  std::string header = ConstructDataHeader(kLen1);
+  mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
+                                     2, 0, header + std::string(kMsg1, kLen1)));
   mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
   mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause
 
-  quic::QuicString header2 = ConstructDataHeader(kLen2);
-  mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
-                                     3, kLen1 + header.length(),
-                                     header2 + quic::QuicString(kMsg2, kLen2)));
+  std::string header2 = ConstructDataHeader(kLen2);
+  mock_quic_data_.AddRead(
+      ASYNC, ConstructServerDataPacket(3, kLen1 + header.length(),
+                                       header2 + std::string(kMsg2, kLen2)));
   mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
 
   mock_quic_data_.AddWrite(
@@ -1035,15 +1028,14 @@
   mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
   mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause
 
-  quic::QuicString header = ConstructDataHeader(kLen1);
-  mock_quic_data_.AddRead(
-      ASYNC,
-      ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
-  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
-  quic::QuicString header2 = ConstructDataHeader(kLen2);
+  std::string header = ConstructDataHeader(kLen1);
   mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
-                                     3, kLen1 + header.length(),
-                                     header2 + quic::QuicString(kMsg2, kLen2)));
+                                     2, 0, header + std::string(kMsg1, kLen1)));
+  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
+  std::string header2 = ConstructDataHeader(kLen2);
+  mock_quic_data_.AddRead(
+      ASYNC, ConstructServerDataPacket(3, kLen1 + header.length(),
+                                       header2 + std::string(kMsg2, kLen2)));
   mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
 
   mock_quic_data_.AddWrite(
@@ -1067,15 +1059,14 @@
   mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
   mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause
 
-  quic::QuicString header = ConstructDataHeader(kLen3);
-  mock_quic_data_.AddRead(
-      ASYNC,
-      ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg3, kLen3)));
-  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
-  quic::QuicString header2 = ConstructDataHeader(kLen3);
+  std::string header = ConstructDataHeader(kLen3);
   mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
-                                     3, kLen3 + header.length(),
-                                     header2 + quic::QuicString(kMsg3, kLen3)));
+                                     2, 0, header + std::string(kMsg3, kLen3)));
+  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
+  std::string header2 = ConstructDataHeader(kLen3);
+  mock_quic_data_.AddRead(
+      ASYNC, ConstructServerDataPacket(3, kLen3 + header.length(),
+                                       header2 + std::string(kMsg3, kLen3)));
   mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
 
   mock_quic_data_.AddWrite(
@@ -1101,28 +1092,28 @@
 
   int offset = 0;
 
-  quic::QuicString header = ConstructDataHeader(kLen1);
+  std::string header = ConstructDataHeader(kLen1);
   mock_quic_data_.AddRead(
-      ASYNC, ConstructServerDataPacket(
-                 2, offset, header + quic::QuicString(kMsg1, kLen1)));
+      ASYNC,
+      ConstructServerDataPacket(2, offset, header + std::string(kMsg1, kLen1)));
   offset += kLen1 + header.length();
   mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
 
-  quic::QuicString header2 = ConstructDataHeader(kLen3);
+  std::string header2 = ConstructDataHeader(kLen3);
   mock_quic_data_.AddRead(
-      ASYNC, ConstructServerDataPacket(
-                 3, offset, header2 + quic::QuicString(kMsg3, kLen3)));
+      ASYNC, ConstructServerDataPacket(3, offset,
+                                       header2 + std::string(kMsg3, kLen3)));
   offset += kLen3 + header2.length();
   mock_quic_data_.AddRead(
-      ASYNC, ConstructServerDataPacket(
-                 4, offset, header2 + quic::QuicString(kMsg3, kLen3)));
+      ASYNC, ConstructServerDataPacket(4, offset,
+                                       header2 + std::string(kMsg3, kLen3)));
   offset += kLen3 + header2.length();
   mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(4, 4, 3, 1));
 
-  quic::QuicString header3 = ConstructDataHeader(kLen2);
+  std::string header3 = ConstructDataHeader(kLen2);
   mock_quic_data_.AddRead(
-      ASYNC, ConstructServerDataPacket(
-                 5, offset, header3 + quic::QuicString(kMsg2, kLen2)));
+      ASYNC, ConstructServerDataPacket(5, offset,
+                                       header3 + std::string(kMsg2, kLen2)));
   offset += kLen2 + header3.length();
   mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
 
@@ -1150,16 +1141,14 @@
   mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
   mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause
 
-  quic::QuicString header = ConstructDataHeader(kLen1);
-  mock_quic_data_.AddRead(
-      ASYNC,
-      ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
+  std::string header = ConstructDataHeader(kLen1);
+  mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
+                                     2, 0, header + std::string(kMsg1, kLen1)));
   mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
-  quic::QuicString header2 = ConstructDataHeader(kLen33);
+  std::string header2 = ConstructDataHeader(kLen33);
   mock_quic_data_.AddRead(
-      ASYNC,
-      ConstructServerDataPacket(3, kLen1 + header.length(),
-                                header2 + quic::QuicString(kMsg33, kLen33)));
+      ASYNC, ConstructServerDataPacket(3, kLen1 + header.length(),
+                                       header2 + std::string(kMsg33, kLen33)));
   mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
 
   mock_quic_data_.AddWrite(
@@ -1186,10 +1175,10 @@
   mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
   mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause
 
-  quic::QuicString header = ConstructDataHeader(kLen333);
+  std::string header = ConstructDataHeader(kLen333);
   mock_quic_data_.AddRead(
-      ASYNC, ConstructServerDataPacket(
-                 2, 0, header + quic::QuicString(kMsg333, kLen333)));
+      ASYNC,
+      ConstructServerDataPacket(2, 0, header + std::string(kMsg333, kLen333)));
   mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
   mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
 
@@ -1222,15 +1211,14 @@
                           ConstructServerConnectAuthReplyPacket(1, !kFin));
   mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause
 
-  quic::QuicString header = ConstructDataHeader(kLen1);
-  mock_quic_data_.AddRead(
-      ASYNC,
-      ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
-  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
-  quic::QuicString header2 = ConstructDataHeader(kLen2);
+  std::string header = ConstructDataHeader(kLen1);
   mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
-                                     3, kLen1 + header.length(),
-                                     header2 + quic::QuicString(kMsg2, kLen2)));
+                                     2, 0, header + std::string(kMsg1, kLen1)));
+  mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
+  std::string header2 = ConstructDataHeader(kLen2);
+  mock_quic_data_.AddRead(
+      ASYNC, ConstructServerDataPacket(3, kLen1 + header.length(),
+                                       header2 + std::string(kMsg2, kLen2)));
   mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
 
   mock_quic_data_.AddWrite(
@@ -1253,16 +1241,16 @@
   mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructConnectRequestPacket(2));
   mock_quic_data_.AddRead(ASYNC,
                           ConstructServerConnectErrorReplyPacket(1, !kFin));
-  quic::QuicString header = ConstructDataHeader(kLen1);
+  std::string header = ConstructDataHeader(kLen1);
   mock_quic_data_.AddRead(
       SYNCHRONOUS,
-      ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
+      ConstructServerDataPacket(2, 0, header + std::string(kMsg1, kLen1)));
   mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
-  quic::QuicString header2 = ConstructDataHeader(kLen2);
+  std::string header2 = ConstructDataHeader(kLen2);
   mock_quic_data_.AddRead(
       SYNCHRONOUS,
       ConstructServerDataPacket(3, kLen1 + header.length(),
-                                header2 + quic::QuicString(kMsg2, kLen2)));
+                                header2 + std::string(kMsg2, kLen2)));
   mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
 
   mock_quic_data_.AddWrite(
@@ -1284,31 +1272,30 @@
   mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
   mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause
 
-  quic::QuicString header = ConstructDataHeader(kLen1);
-  mock_quic_data_.AddRead(
-      ASYNC,
-      ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
+  std::string header = ConstructDataHeader(kLen1);
+  mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
+                                     2, 0, header + std::string(kMsg1, kLen1)));
   mock_quic_data_.AddWrite(SYNCHRONOUS,
                            ConstructAckPacket(write_packet_index++, 2, 1, 1));
 
-  quic::QuicString header2 = ConstructDataHeader(kLen2);
+  std::string header2 = ConstructDataHeader(kLen2);
   if (version_ == quic::QUIC_VERSION_99) {
-    mock_quic_data_.AddWrite(SYNCHRONOUS,
-                             ConstructMultipleDataFramesPacket(
-                                 write_packet_index++, 0,
-                                 {header2, quic::QuicString(kMsg2, kLen2)}));
+    mock_quic_data_.AddWrite(
+        SYNCHRONOUS,
+        ConstructMultipleDataFramesPacket(
+            write_packet_index++, 0, {header2, std::string(kMsg2, kLen2)}));
   } else {
     mock_quic_data_.AddWrite(
-      SYNCHRONOUS, ConstructDataPacket(write_packet_index++, header2.length(),
-                                       quic::QuicString(kMsg2, kLen2)));
+        SYNCHRONOUS, ConstructDataPacket(write_packet_index++, header2.length(),
+                                         std::string(kMsg2, kLen2)));
   }
 
   mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause
 
-  quic::QuicString header3 = ConstructDataHeader(kLen3);
-  mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
-                                     3, kLen1 + header.length(),
-                                     header3 + quic::QuicString(kMsg3, kLen3)));
+  std::string header3 = ConstructDataHeader(kLen3);
+  mock_quic_data_.AddRead(
+      ASYNC, ConstructServerDataPacket(3, kLen1 + header.length(),
+                                       header3 + std::string(kMsg3, kLen3)));
   mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
 
   mock_quic_data_.AddWrite(
@@ -1342,36 +1329,34 @@
   mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
   mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause
 
-  quic::QuicString header = ConstructDataHeader(kLen1);
-  mock_quic_data_.AddRead(
-      ASYNC,
-      ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
+  std::string header = ConstructDataHeader(kLen1);
+  mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
+                                     2, 0, header + std::string(kMsg1, kLen1)));
   mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
   mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause
 
-  quic::QuicString header2 = ConstructDataHeader(kLen3);
-  mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
-                                     3, kLen1 + header.length(),
-                                     header2 + quic::QuicString(kMsg3, kLen3)));
+  std::string header2 = ConstructDataHeader(kLen3);
+  mock_quic_data_.AddRead(
+      ASYNC, ConstructServerDataPacket(3, kLen1 + header.length(),
+                                       header2 + std::string(kMsg3, kLen3)));
   mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
 
   mock_quic_data_.AddWrite(ASYNC, ERR_IO_PENDING);  // Pause
 
-  quic::QuicString header3 = ConstructDataHeader(kLen2);
+  std::string header3 = ConstructDataHeader(kLen2);
   if (version_ != quic::QUIC_VERSION_99) {
     mock_quic_data_.AddWrite(
-        ASYNC, ConstructDataPacket(4, 0, quic::QuicString(kMsg2, kLen2)));
+        ASYNC, ConstructDataPacket(4, 0, std::string(kMsg2, kLen2)));
     mock_quic_data_.AddWrite(
         SYNCHRONOUS, ConstructAckAndDataPacket(5, 3, 3, 1, kLen2,
-                                               quic::QuicString(kMsg2, kLen2)));
+                                               std::string(kMsg2, kLen2)));
   } else {
+    mock_quic_data_.AddWrite(ASYNC,
+                             ConstructMultipleDataFramesPacket(
+                                 4, 0, {header3, std::string(kMsg2, kLen2)}));
     mock_quic_data_.AddWrite(
-        ASYNC, ConstructMultipleDataFramesPacket(
-                   4, 0, {header3, quic::QuicString(kMsg2, kLen2)}));
-    mock_quic_data_.AddWrite(
-        ASYNC,
-        ConstructAckAndDataPacket(5, 3, 3, 1, header3.length() + kLen2,
-                                  header3 + quic::QuicString(kMsg2, kLen2)));
+        ASYNC, ConstructAckAndDataPacket(5, 3, 3, 1, header3.length() + kLen2,
+                                         header3 + std::string(kMsg2, kLen2)));
   }
 
   mock_quic_data_.AddWrite(
@@ -1474,10 +1459,9 @@
   mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
   mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause
 
-  quic::QuicString header = ConstructDataHeader(kLen1);
-  mock_quic_data_.AddRead(ASYNC,
-                          ConstructServerDataFinPacket(
-                              2, 0, header + quic::QuicString(kMsg1, kLen1)));
+  std::string header = ConstructDataHeader(kLen1);
+  mock_quic_data_.AddRead(ASYNC, ConstructServerDataFinPacket(
+                                     2, 0, header + std::string(kMsg1, kLen1)));
   mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
   mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
   mock_quic_data_.AddWrite(
@@ -1640,18 +1624,18 @@
   mock_quic_data_.AddRead(
       ASYNC, ConstructServerRstPacket(2, quic::QUIC_STREAM_CANCELLED, 0));
   mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
-  quic::QuicString header = ConstructDataHeader(kLen2);
+  std::string header = ConstructDataHeader(kLen2);
   if (version_ != quic::QUIC_VERSION_99) {
     mock_quic_data_.AddWrite(
-        ASYNC, ConstructAckAndDataPacket(3, 1, 1, 1, 0,
-                                         quic::QuicString(kMsg2, kLen2)));
+        ASYNC,
+        ConstructAckAndDataPacket(3, 1, 1, 1, 0, std::string(kMsg2, kLen2)));
     mock_quic_data_.AddWrite(
         SYNCHRONOUS, ConstructAckAndRstPacket(4, quic::QUIC_RST_ACKNOWLEDGEMENT,
                                               2, 2, 1, kLen2));
   } else {
     mock_quic_data_.AddWrite(
         ASYNC, ConstructAckAndMultipleDataFramesPacket(
-                   3, 1, 1, 1, 0, {header, quic::QuicString(kMsg2, kLen2)}));
+                   3, 1, 1, 1, 0, {header, std::string(kMsg2, kLen2)}));
     mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckAndRstOnlyPacket(
                                               4, quic::QUIC_STREAM_CANCELLED, 2,
                                               2, 1, header.length() + kLen2));
@@ -1688,10 +1672,9 @@
   mock_quic_data_.AddRead(ASYNC, ConstructServerConnectReplyPacket(1, !kFin));
   mock_quic_data_.AddRead(ASYNC, ERR_IO_PENDING);  // Pause
 
-  quic::QuicString header = ConstructDataHeader(kLen1);
-  mock_quic_data_.AddRead(
-      ASYNC,
-      ConstructServerDataPacket(2, 0, header + quic::QuicString(kMsg1, kLen1)));
+  std::string header = ConstructDataHeader(kLen1);
+  mock_quic_data_.AddRead(ASYNC, ConstructServerDataPacket(
+                                     2, 0, header + std::string(kMsg1, kLen1)));
   mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 2, 1, 1));
   mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
   mock_quic_data_.AddWrite(
@@ -1776,16 +1759,16 @@
   mock_quic_data_.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
   if (version_ != quic::QUIC_VERSION_99) {
     mock_quic_data_.AddWrite(
-        ASYNC, ConstructAckAndDataPacket(3, 1, 1, 1, 0,
-                                         quic::QuicString(kMsg1, kLen1)));
+        ASYNC,
+        ConstructAckAndDataPacket(3, 1, 1, 1, 0, std::string(kMsg1, kLen1)));
     mock_quic_data_.AddWrite(
         SYNCHRONOUS, ConstructAckAndRstPacket(4, quic::QUIC_RST_ACKNOWLEDGEMENT,
                                               2, 2, 1, kLen1));
   } else {
-    quic::QuicString header = ConstructDataHeader(kLen1);
+    std::string header = ConstructDataHeader(kLen1);
     mock_quic_data_.AddWrite(
         ASYNC, ConstructAckAndMultipleDataFramesPacket(
-                   3, 1, 1, 1, 0, {header, quic::QuicString(kMsg1, kLen1)}));
+                   3, 1, 1, 1, 0, {header, std::string(kMsg1, kLen1)}));
     mock_quic_data_.AddWrite(SYNCHRONOUS, ConstructAckAndRstOnlyPacket(
                                               4, quic::QUIC_STREAM_CANCELLED, 2,
                                               2, 1, header.length() + kLen1));
diff --git a/net/quic/quic_stream_factory_test.cc b/net/quic/quic_stream_factory_test.cc
index a11cf23..4fa4779 100644
--- a/net/quic/quic_stream_factory_test.cc
+++ b/net/quic/quic_stream_factory_test.cc
@@ -5100,7 +5100,7 @@
   EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
 
   // Cause the connection to close due to |quic_error| before handshake.
-  quic::QuicString error_details;
+  std::string error_details;
   if (quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT) {
     error_details = "No recent network activity.";
   } else {
@@ -5215,7 +5215,7 @@
   EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
   EXPECT_FALSE(failed_on_default_network_);
 
-  quic::QuicString error_details;
+  std::string error_details;
   if (quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT) {
     error_details = "No recent network activity.";
   } else {
diff --git a/services/network/cors/cors_url_loader_factory.cc b/services/network/cors/cors_url_loader_factory.cc
index 9d225be..c172485b 100644
--- a/services/network/cors/cors_url_loader_factory.cc
+++ b/services/network/cors/cors_url_loader_factory.cc
@@ -104,8 +104,7 @@
     return;
   }
 
-  if (base::FeatureList::IsEnabled(features::kOutOfBlinkCors) &&
-      !disable_web_security_) {
+  if (features::ShouldEnableOutOfBlinkCors() && !disable_web_security_) {
     auto loader = std::make_unique<CorsURLLoader>(
         std::move(request), routing_id, request_id, options,
         base::BindOnce(&CorsURLLoaderFactory::DestroyURLLoader,
diff --git a/services/network/cors/cors_url_loader_unittest.cc b/services/network/cors/cors_url_loader_unittest.cc
index 92903bb..e1b60cf 100644
--- a/services/network/cors/cors_url_loader_unittest.cc
+++ b/services/network/cors/cors_url_loader_unittest.cc
@@ -143,7 +143,8 @@
  protected:
   // testing::Test implementation.
   void SetUp() override {
-    feature_list_.InitAndEnableFeature(features::kOutOfBlinkCors);
+    feature_list_.InitWithFeatures(
+        {features::kOutOfBlinkCors, features::kNetworkService}, {});
 
     network_service_ = NetworkService::CreateForTesting();
 
diff --git a/services/network/public/cpp/features.cc b/services/network/public/cpp/features.cc
index 72e96fb..5276ed9 100644
--- a/services/network/public/cpp/features.cc
+++ b/services/network/public/cpp/features.cc
@@ -59,5 +59,13 @@
 const base::Feature kEnforceRequestInitiatorLockForCorb{
     "EnforceRequestInitiatorLockForCorb", base::FEATURE_ENABLED_BY_DEFAULT};
 
+bool ShouldEnableOutOfBlinkCors() {
+  // OOR-CORS requires NetworkService.
+  if (!base::FeatureList::IsEnabled(features::kNetworkService))
+    return false;
+
+  return base::FeatureList::IsEnabled(features::kOutOfBlinkCors);
+}
+
 }  // namespace features
 }  // namespace network
diff --git a/services/network/public/cpp/features.h b/services/network/public/cpp/features.h
index 72618b3..cbf53f1f 100644
--- a/services/network/public/cpp/features.h
+++ b/services/network/public/cpp/features.h
@@ -28,6 +28,8 @@
 COMPONENT_EXPORT(NETWORK_CPP)
 extern const base::Feature kEnforceRequestInitiatorLockForCorb;
 
+COMPONENT_EXPORT(NETWORK_CPP) bool ShouldEnableOutOfBlinkCors();
+
 }  // namespace features
 }  // namespace network
 
diff --git a/services/ws/gpu_host/gpu_host.cc b/services/ws/gpu_host/gpu_host.cc
index 078f6aa..c5917b5 100644
--- a/services/ws/gpu_host/gpu_host.cc
+++ b/services/ws/gpu_host/gpu_host.cc
@@ -303,6 +303,12 @@
   NOTREACHED();
 }
 
+void GpuHost::RunService(
+    const std::string& service_name,
+    mojo::PendingReceiver<service_manager::mojom::Service> receiver) {
+  NOTREACHED();
+}
+
 #if defined(USE_OZONE)
 void GpuHost::TerminateGpuProcess(const std::string& message) {}
 
diff --git a/services/ws/gpu_host/gpu_host.h b/services/ws/gpu_host/gpu_host.h
index 38b523a..94192f7 100644
--- a/services/ws/gpu_host/gpu_host.h
+++ b/services/ws/gpu_host/gpu_host.h
@@ -102,6 +102,9 @@
       override;
   void BindInterface(const std::string& interface_name,
                      mojo::ScopedMessagePipeHandle interface_pipe) override;
+  void RunService(
+      const std::string& service_name,
+      mojo::PendingReceiver<service_manager::mojom::Service> receiver) override;
 #if defined(USE_OZONE)
   void TerminateGpuProcess(const std::string& message) override;
   void SendGpuProcessMessage(IPC::Message* message) override;
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json
index ee2f629..57abcbe 100644
--- a/testing/buildbot/chromium.gpu.fyi.json
+++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -5564,25 +5564,6 @@
       {
         "args": [
           "--use-gpu-in-tests",
-          "--test-launcher-retry-limit=0"
-        ],
-        "should_retry_with_patch": false,
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:5912-18.0.5",
-              "os": "Ubuntu",
-              "pool": "Chrome-GPU"
-            }
-          ],
-          "shards": 4
-        },
-        "test": "angle_end2end_tests"
-      },
-      {
-        "args": [
-          "--use-gpu-in-tests",
           "--test-launcher-retry-limit=0",
           "--no-xvfb"
         ],
@@ -5618,56 +5599,6 @@
       },
       {
         "args": [
-          "--enable-gpu",
-          "--test-launcher-bot-mode",
-          "--test-launcher-jobs=1",
-          "--gtest_filter=CastStreamingApiTestWithPixelOutput.EndToEnd*:TabCaptureApiPixelTest.EndToEnd*",
-          "--no-xvfb"
-        ],
-        "name": "tab_capture_end2end_tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:5912-18.0.5",
-              "os": "Ubuntu",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "test": "browser_tests"
-      },
-      {
-        "args": [
-          "--enable-gpu",
-          "--test-launcher-bot-mode",
-          "--test-launcher-jobs=1",
-          "--test-launcher-filter-file=../../testing/buildbot/filters/vulkan.content_browsertests.filter",
-          "--enable-features=VizDisplayCompositor,UseSkiaRenderer,UiGpuRasterization",
-          "--use-gl=any",
-          "--enable-oop-rasterization",
-          "--enable-vulkan",
-          "--enable-gpu-rasterization",
-          "--enable-raster-to-sk-image",
-          "--force-gpu-rasterization",
-          "--disable-software-compositing-fallback",
-          "--no-xvfb"
-        ],
-        "name": "vulkan_content_browsertests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "8086:5912-18.0.5",
-              "os": "Ubuntu",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "test": "content_browsertests"
-      },
-      {
-        "args": [
           "--use-gpu-in-tests",
           "--use-cmd-decoder=validating"
         ],
@@ -6774,44 +6705,6 @@
       },
       {
         "args": [
-          "--enable-gpu",
-          "--test-launcher-bot-mode",
-          "--test-launcher-jobs=1",
-          "--test-launcher-filter-file=../../testing/buildbot/filters/vulkan.content_browsertests.filter",
-          "--enable-features=VizDisplayCompositor,UseSkiaRenderer,UiGpuRasterization",
-          "--use-gl=any",
-          "--enable-oop-rasterization",
-          "--enable-vulkan",
-          "--enable-gpu-rasterization",
-          "--enable-raster-to-sk-image",
-          "--force-gpu-rasterization",
-          "--disable-software-compositing-fallback",
-          "--no-xvfb"
-        ],
-        "name": "vulkan_content_browsertests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "gpu": "10de:1cb3-384.90",
-              "os": "Ubuntu",
-              "pool": "Chrome-GPU"
-            }
-          ]
-        },
-        "test": "content_browsertests",
-        "trigger_script": {
-          "args": [
-            "--multiple-trigger-configs",
-            "[{\"gpu\": \"10de:1cb3-384.90\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}, {\"gpu\": \"10de:1cb3-410.78\", \"os\": \"Ubuntu\", \"pool\": \"Chrome-GPU\"}]",
-            "--multiple-dimension-script-verbose",
-            "True"
-          ],
-          "script": "//testing/trigger_scripts/trigger_multiple_dimensions.py"
-        }
-      },
-      {
-        "args": [
           "--use-gpu-in-tests",
           "--test-launcher-retry-limit=0"
         ],
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index 52502a8e3..443416d 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -33,6 +33,8 @@
       'Android FYI Release (Nexus 9)',
       # Temporarily disabled due to AMDGPU-PRO issues crbug.com/786219
       'Linux FYI Release (AMD R7 240)',
+      # Disabled due to numerous ES2_VULKAN failures crbug.com/940750
+      'Linux FYI Experimental Release (Intel HD 630)',
     ],
   },
   'angle_perftests': {
@@ -1131,6 +1133,8 @@
       'Mac Retina Debug (AMD)',
       'Win10 Debug (NVIDIA)',
       # chromium.gpu.fyi
+      # Disabled due to dbus crashes crbug.com/927465
+      'Linux FYI Experimental Release (Intel HD 630)',
       'Win10 FYI Debug (NVIDIA)',
       'Win7 FYI Debug (AMD)',
     ],
@@ -1351,6 +1355,14 @@
       'VR Linux',
     ],
   },
+  'vulkan_content_browsertests' : {
+    'remove_from': [
+      # Flaky hangs crbug.com/940723
+      'Linux FYI GPU TSAN Release',
+      # Consistent hangs crbug.com/940750
+      'Linux FYI Experimental Release (Intel HD 630)',
+    ],
+  },
   'wayland_client_perftests': {
     'remove_from': [
       'linux-chromeos-dbg',  # https://crbug.com/859307
diff --git a/third_party/blink/common/service_worker/service_worker_type_converters.cc b/third_party/blink/common/service_worker/service_worker_type_converters.cc
index 8119eed..2bbec48 100644
--- a/third_party/blink/common/service_worker/service_worker_type_converters.cc
+++ b/third_party/blink/common/service_worker/service_worker_type_converters.cc
@@ -19,6 +19,8 @@
       return blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected;
     case blink::mojom::ServiceWorkerEventStatus::ABORTED:
       return blink::ServiceWorkerStatusCode::kErrorAbort;
+    case blink::mojom::ServiceWorkerEventStatus::TIMEOUT:
+      return blink::ServiceWorkerStatusCode::kErrorTimeout;
   }
   NOTREACHED() << status;
   return blink::ServiceWorkerStatusCode::kErrorFailed;
diff --git a/third_party/blink/public/common/BUILD.gn b/third_party/blink/public/common/BUILD.gn
index 28387e2..d45c565 100644
--- a/third_party/blink/public/common/BUILD.gn
+++ b/third_party/blink/public/common/BUILD.gn
@@ -51,6 +51,7 @@
     "frame/frame_owner_element_type.h",
     "frame/frame_policy.h",
     "frame/from_ad_state.h",
+    "frame/occlusion_state.h",
     "frame/sandbox_flags.h",
     "frame/user_activation_state.h",
     "frame/user_activation_update_source.h",
diff --git a/third_party/blink/public/common/frame/occlusion_state.h b/third_party/blink/public/common/frame/occlusion_state.h
new file mode 100644
index 0000000..b6ca000
--- /dev/null
+++ b/third_party/blink/public/common/frame/occlusion_state.h
@@ -0,0 +1,26 @@
+// Copyright 2019 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_PUBLIC_COMMON_FRAME_OCCLUSION_STATE_H_
+#define THIRD_PARTY_BLINK_PUBLIC_COMMON_FRAME_OCCLUSION_STATE_H_
+
+#include "third_party/blink/public/common/common_export.h"
+
+namespace blink {
+
+// Indicates whether a child frame is occluded or visually altered by content
+// or styles in the parent frame.
+enum FrameOcclusionState {
+  // No occlusion determination was made.
+  kUnknownOcclusionState = 0,
+  // The frame *may* be occluded or visually altered.
+  kPossiblyOccluded = 1,
+  // The frame is definitely not occluded or visually altered.
+  kGuaranteedNotOccluded = 2,
+  kMaxOcclusionState = kGuaranteedNotOccluded
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_PUBLIC_COMMON_FRAME_OCCLUSION_STATE_H_
diff --git a/third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom b/third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom
index d126f4c..83d7855 100644
--- a/third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom
+++ b/third_party/blink/public/mojom/service_worker/service_worker_event_status.mojom
@@ -21,15 +21,13 @@
   // to network.
   REJECTED,
 
-  // ABORTED happens in at least two cases:
-  // - The service worker execution context was destroyed while the event was
-  // alive.
-  // - The event timed out.
-  //
-  // TODO(falken): It seems useful to add a TIMEOUT status.
+  // The service worker execution context was destroyed while the event was alive.
   ABORTED,
 
-  MAX=ABORTED
+  // The event failed to finish within the time limit.
+  TIMEOUT,
+
+  MAX=TIMEOUT
 };
 
 // The result of starting a service worker.
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom
index 74496bf3..c6d55d3e 100644
--- a/third_party/blink/public/mojom/web_feature/web_feature.mojom
+++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -2264,6 +2264,7 @@
   kFlexboxWithOverflowFlexItemIntrinsicSize = 2828,
   kCSSSelectorHostContextInSnapshotProfile = 2829,
   kCSSSelectorHostContextInLiveProfile = 2830,
+  kImportMap = 2831,
 
   // Add new features immediately above this line. Don't change assigned
   // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h b/third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h
index f27c6e61..11fdce2 100644
--- a/third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h
+++ b/third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h
@@ -62,7 +62,7 @@
 class BLINK_PLATFORM_EXPORT MediaStreamAudioSource
     : public WebPlatformMediaStreamSource {
  public:
-  explicit MediaStreamAudioSource(
+  MediaStreamAudioSource(
       scoped_refptr<base::SingleThreadTaskRunner> task_runner,
       bool is_local_source);
   MediaStreamAudioSource(
diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h
index a6be471..f57b42fd 100644
--- a/third_party/blink/public/platform/web_runtime_features.h
+++ b/third_party/blink/public/platform/web_runtime_features.h
@@ -155,7 +155,6 @@
   BLINK_PLATFORM_EXPORT static void EnablePictureInPictureAPI(bool);
   BLINK_PLATFORM_EXPORT static void EnablePortals(bool);
   BLINK_PLATFORM_EXPORT static void EnablePreciseMemoryInfo(bool);
-  BLINK_PLATFORM_EXPORT static void EnablePreloadImageSrcSetEnabled(bool);
   BLINK_PLATFORM_EXPORT static void EnablePrintBrowser(bool);
   BLINK_PLATFORM_EXPORT static void EnablePresentationAPI(bool);
   BLINK_PLATFORM_EXPORT static void EnablePushMessaging(bool);
diff --git a/third_party/blink/public/platform/web_url_response.h b/third_party/blink/public/platform/web_url_response.h
index cd6279a..a2572fd 100644
--- a/third_party/blink/public/platform/web_url_response.h
+++ b/third_party/blink/public/platform/web_url_response.h
@@ -175,7 +175,7 @@
   BLINK_PLATFORM_EXPORT void SetResponseTime(base::Time);
 
   BLINK_PLATFORM_EXPORT WebString MimeType() const;
-  BLINK_PLATFORM_EXPORT void SetMIMEType(const WebString&);
+  BLINK_PLATFORM_EXPORT void SetMimeType(const WebString&);
 
   BLINK_PLATFORM_EXPORT long long ExpectedContentLength() const;
   BLINK_PLATFORM_EXPORT void SetExpectedContentLength(long long);
diff --git a/third_party/blink/public/web/web_frame_widget.h b/third_party/blink/public/web/web_frame_widget.h
index b4e526a..d7d9dcc 100644
--- a/third_party/blink/public/web/web_frame_widget.h
+++ b/third_party/blink/public/web/web_frame_widget.h
@@ -31,6 +31,7 @@
 #ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_FRAME_WIDGET_H_
 #define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_FRAME_WIDGET_H_
 
+#include "third_party/blink/public/common/frame/occlusion_state.h"
 #include "third_party/blink/public/platform/web_common.h"
 #include "third_party/blink/public/platform/web_drag_operation.h"
 #include "third_party/blink/public/platform/web_touch_action.h"
@@ -103,7 +104,8 @@
   // and indicates whether the frame may be painted over or obscured in the
   // parent. This is needed for out-of-process iframes to know if they are
   // clipped or obscured by ancestor frames in another process.
-  virtual void SetRemoteViewportIntersection(const WebRect&, bool) {}
+  virtual void SetRemoteViewportIntersection(const WebRect&,
+                                             FrameOcclusionState) {}
 
   // Sets the inert bit on an out-of-process iframe, causing it to ignore
   // input.
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h
index 4ec9ce16..b16662ed 100644
--- a/third_party/blink/public/web/web_local_frame_client.h
+++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -319,6 +319,10 @@
   // is being dragged.
   virtual void SetMouseCapture(bool capture) {}
 
+  // Announces that an embedded frame needs occlusion information from its
+  // parent frame.
+  virtual void SetNeedsOcclusionTracking(bool needs_tracking) {}
+
   // Console messages ----------------------------------------------------
 
   // Whether or not we should report a detailed message for the given source.
diff --git a/third_party/blink/public/web/web_remote_frame.h b/third_party/blink/public/web/web_remote_frame.h
index c790c4a..6a6a04c 100644
--- a/third_party/blink/public/web/web_remote_frame.h
+++ b/third_party/blink/public/web/web_remote_frame.h
@@ -114,6 +114,8 @@
 
   virtual void DispatchLoadEventForFrameOwner() = 0;
 
+  virtual void SetNeedsOcclusionTracking(bool) = 0;
+
   virtual void DidStartLoading() = 0;
   virtual void DidStopLoading() = 0;
 
diff --git a/third_party/blink/public/web/web_remote_frame_client.h b/third_party/blink/public/web/web_remote_frame_client.h
index 21558161..fd46b52 100644
--- a/third_party/blink/public/web/web_remote_frame_client.h
+++ b/third_party/blink/public/web/web_remote_frame_client.h
@@ -6,12 +6,13 @@
 #define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_REMOTE_FRAME_CLIENT_H_
 
 #include "cc/paint/paint_canvas.h"
+#include "third_party/blink/public/common/frame/occlusion_state.h"
 #include "third_party/blink/public/mojom/frame/lifecycle.mojom-shared.h"
 #include "third_party/blink/public/platform/web_focus_type.h"
 #include "third_party/blink/public/platform/web_security_origin.h"
 #include "third_party/blink/public/platform/web_touch_action.h"
 #include "third_party/blink/public/web/web_dom_message_event.h"
-#include "third_party/blink/public/web/web_frame.h"
+#include "third_party/blink/public/web/web_remote_frame.h"
 
 namespace blink {
 class WebURLRequest;
@@ -49,7 +50,7 @@
 
   virtual void UpdateRemoteViewportIntersection(
       const WebRect& viewport_intersection,
-      bool occluded_or_obscured) {}
+      FrameOcclusionState occlusion_state) {}
 
   virtual void VisibilityChanged(blink::mojom::FrameVisibility visibility) {}
 
diff --git a/third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.cc b/third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.cc
index 8a55626..4718cda 100644
--- a/third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.cc
+++ b/third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.cc
@@ -205,8 +205,9 @@
   if (source_location)
     return source_location;
   // Fallback to uncompiled source info.
-  return SourceLocation::Create(source_url_, position_.line_.ZeroBasedInt(),
-                                position_.column_.ZeroBasedInt(), nullptr);
+  return std::make_unique<SourceLocation>(
+      source_url_, position_.line_.ZeroBasedInt(),
+      position_.column_.ZeroBasedInt(), nullptr);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/bindings/core/v8/rejected_promises.cc b/third_party/blink/renderer/bindings/core/v8/rejected_promises.cc
index d667ffa..abc120a 100644
--- a/third_party/blink/renderer/bindings/core/v8/rejected_promises.cc
+++ b/third_party/blink/renderer/bindings/core/v8/rejected_promises.cc
@@ -27,18 +27,6 @@
 
 class RejectedPromises::Message final {
  public:
-  static std::unique_ptr<Message> Create(
-      ScriptState* script_state,
-      v8::Local<v8::Promise> promise,
-      v8::Local<v8::Value> exception,
-      const String& error_message,
-      std::unique_ptr<SourceLocation> location,
-      SanitizeScriptErrors sanitize_script_errors) {
-    return base::WrapUnique(new Message(script_state, promise, exception,
-                                        error_message, std::move(location),
-                                        sanitize_script_errors));
-  }
-
   Message(ScriptState* script_state,
           v8::Local<v8::Promise> promise,
           v8::Local<v8::Value> exception,
@@ -198,7 +186,7 @@
     const String& error_message,
     std::unique_ptr<SourceLocation> location,
     SanitizeScriptErrors sanitize_script_errors) {
-  queue_.push_back(Message::Create(
+  queue_.push_back(std::make_unique<Message>(
       script_state, data.GetPromise(), data.GetValue(), error_message,
       std::move(location), sanitize_script_errors));
 }
diff --git a/third_party/blink/renderer/bindings/core/v8/source_location.cc b/third_party/blink/renderer/bindings/core/v8/source_location.cc
index 476a14a..3585c18 100644
--- a/third_party/blink/renderer/bindings/core/v8/source_location.cc
+++ b/third_party/blink/renderer/bindings/core/v8/source_location.cc
@@ -43,8 +43,8 @@
   if (stack_trace && !stack_trace->isEmpty())
     return SourceLocation::CreateFromNonEmptyV8StackTrace(
         std::move(stack_trace), 0);
-  return SourceLocation::Create(url, line_number, column_number,
-                                std::move(stack_trace));
+  return std::make_unique<SourceLocation>(url, line_number, column_number,
+                                          std::move(stack_trace));
 }
 
 // static
@@ -64,11 +64,11 @@
         line_number =
             document->GetScriptableDocumentParser()->LineNumber().OneBasedInt();
     }
-    return SourceLocation::Create(document->Url().GetString(), line_number, 0,
-                                  std::move(stack_trace));
+    return std::make_unique<SourceLocation>(
+        document->Url().GetString(), line_number, 0, std::move(stack_trace));
   }
 
-  return SourceLocation::Create(
+  return std::make_unique<SourceLocation>(
       execution_context ? execution_context->Url().GetString() : String(), 0, 0,
       std::move(stack_trace));
 }
@@ -106,19 +106,8 @@
       message->GetScriptOrigin().ResourceName());
   if (url.IsEmpty())
     url = execution_context->Url();
-  return SourceLocation::Create(url, line_number, column_number,
-                                std::move(stack_trace), script_id);
-}
-
-// static
-std::unique_ptr<SourceLocation> SourceLocation::Create(
-    const String& url,
-    unsigned line_number,
-    unsigned column_number,
-    std::unique_ptr<v8_inspector::V8StackTrace> stack_trace,
-    int script_id) {
-  return base::WrapUnique(new SourceLocation(
-      url, line_number, column_number, std::move(stack_trace), script_id));
+  return std::make_unique<SourceLocation>(url, line_number, column_number,
+                                          std::move(stack_trace), script_id);
 }
 
 // static
@@ -137,12 +126,12 @@
 std::unique_ptr<SourceLocation> SourceLocation::FromFunction(
     v8::Local<v8::Function> function) {
   if (!function.IsEmpty())
-    return SourceLocation::Create(
+    return std::make_unique<SourceLocation>(
         ToCoreStringWithUndefinedOrNullCheck(
             function->GetScriptOrigin().ResourceName()),
         function->GetScriptLineNumber() + 1,
         function->GetScriptColumnNumber() + 1, nullptr, function->ScriptId());
-  return SourceLocation::Create(String(), 0, 0, nullptr, 0);
+  return std::make_unique<SourceLocation>(String(), 0, 0, nullptr, 0);
 }
 
 // static
@@ -152,7 +141,7 @@
   if (stack_trace && !stack_trace->isEmpty())
     return SourceLocation::CreateFromNonEmptyV8StackTrace(
         std::move(stack_trace), 0);
-  return SourceLocation::Create(String(), 0, 0, nullptr, 0);
+  return std::make_unique<SourceLocation>(String(), 0, 0, nullptr, 0);
 }
 
 SourceLocation::SourceLocation(
diff --git a/third_party/blink/renderer/bindings/core/v8/source_location.h b/third_party/blink/renderer/bindings/core/v8/source_location.h
index 5ed4a1a..cc8a12d 100644
--- a/third_party/blink/renderer/bindings/core/v8/source_location.h
+++ b/third_party/blink/renderer/bindings/core/v8/source_location.h
@@ -40,12 +40,11 @@
   // Forces full stack trace.
   static std::unique_ptr<SourceLocation> CaptureWithFullStackTrace();
 
-  static std::unique_ptr<SourceLocation> Create(
-      const String& url,
-      unsigned line_number,
-      unsigned column_number,
-      std::unique_ptr<v8_inspector::V8StackTrace>,
-      int script_id = 0);
+  SourceLocation(const String& url,
+                 unsigned line_number,
+                 unsigned column_number,
+                 std::unique_ptr<v8_inspector::V8StackTrace>,
+                 int script_id = 0);
   ~SourceLocation();
 
   bool IsUnknown() const {
@@ -73,11 +72,6 @@
   BuildInspectorObject() const;
 
  private:
-  SourceLocation(const String& url,
-                 unsigned line_number,
-                 unsigned column_number,
-                 std::unique_ptr<v8_inspector::V8StackTrace>,
-                 int script_id);
   static std::unique_ptr<SourceLocation> CreateFromNonEmptyV8StackTrace(
       std::unique_ptr<v8_inspector::V8StackTrace>,
       int script_id);
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
index 06154336..2f5645b 100644
--- a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
+++ b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
@@ -372,8 +372,8 @@
     if (message->IsSharedCrossOrigin())
       sanitize_script_errors = SanitizeScriptErrors::kDoNotSanitize;
   } else {
-    location =
-        SourceLocation::Create(context->Url().GetString(), 0, 0, nullptr);
+    location = std::make_unique<SourceLocation>(context->Url().GetString(), 0,
+                                                0, nullptr);
   }
 
   String message_for_console =
diff --git a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc
index 3d6afca..36e2924 100644
--- a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc
+++ b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc
@@ -140,9 +140,7 @@
   script_state_->DissociateContext();
 }
 
-bool WorkerOrWorkletScriptController::InitializeContext(
-    const String& human_readable_name,
-    const KURL& url_for_debugger) {
+bool WorkerOrWorkletScriptController::Initialize(const KURL& url_for_debugger) {
   v8::HandleScope handle_scope(isolate_);
 
   DCHECK(!IsContextInitialized());
@@ -219,12 +217,10 @@
   V8PerContextData::From(context)->ConstructorForType(wrapper_type_info);
 
   if (global_scope_->IsMainThreadWorkletGlobalScope()) {
-    // Set the human readable name for the world if the call passes an actual
-    // |human_readable name|.
-    if (!human_readable_name.IsEmpty()) {
-      world_->SetNonMainWorldHumanReadableName(world_->GetWorldId(),
-                                               human_readable_name);
-    }
+    // Set the human readable name for the world.
+    DCHECK(!global_scope_->Name().IsEmpty());
+    world_->SetNonMainWorldHumanReadableName(world_->GetWorldId(),
+                                             global_scope_->Name());
   } else {
     // Name new context for debugging. For main thread worklet global scopes
     // this is done once the context is initialized.
diff --git a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h
index 65dd76f..8b0d4b5c 100644
--- a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h
+++ b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h
@@ -72,11 +72,11 @@
 
   // For WorkerGlobalScope and threaded WorkletGlobalScope, |url_for_debugger|
   // is and should be used only for setting name/origin that appears in
-  // DevTools. For other global scopes, |human_readable_name| is used for
-  // setting DOMWrapperWorld's human readable name.
+  // DevTools.
+  // For main thread WorkletGlobalScope, WorkerOrWorkletGlobalScope::Name() is
+  // used for setting DOMWrapperWorld's human readable name.
   // This should be called only once.
-  bool InitializeContext(const String& human_readable_name,
-                         const KURL& url_for_debugger);
+  bool Initialize(const KURL& url_for_debugger);
 
   // Used by WorkerGlobalScope:
   void RethrowExceptionFromImportedScript(ErrorEvent*, ExceptionState&);
diff --git a/third_party/blink/renderer/controller/oom_intervention_impl.cc b/third_party/blink/renderer/controller/oom_intervention_impl.cc
index b2b27b3..163b22c 100644
--- a/third_party/blink/renderer/controller/oom_intervention_impl.cc
+++ b/third_party/blink/renderer/controller/oom_intervention_impl.cc
@@ -188,8 +188,8 @@
 }
 
 int ToMemoryUsageDeltaSample(uint64_t after_kb, uint64_t before_kb) {
-  int delta_mb = (base::saturated_cast<int>(after_kb) -
-                  base::saturated_cast<int>(before_kb)) /
+  int delta_mb = (base::saturated_cast<int>(before_kb) -
+                  base::saturated_cast<int>(after_kb)) /
                  1024;
   return std::min(std::max(delta_mb, -500), 500);
 }
@@ -207,26 +207,26 @@
   switch (number_of_report_needed_--) {
     case 3:
       base::UmaHistogramSparse(
-          "Memory.Experimental.OomIntervention.ReducedBlinkUsageAfter10secs",
+          "Memory.Experimental.OomIntervention.ReducedBlinkUsageAfter10secs2",
           blink_usage_delta);
       base::UmaHistogramSparse(
-          "Memory.Experimental.OomIntervention.ReducedRendererPMFAfter10secs",
+          "Memory.Experimental.OomIntervention.ReducedRendererPMFAfter10secs2",
           private_footprint_delta);
       break;
     case 2:
       base::UmaHistogramSparse(
-          "Memory.Experimental.OomIntervention.ReducedBlinkUsageAfter20secs",
+          "Memory.Experimental.OomIntervention.ReducedBlinkUsageAfter20secs2",
           blink_usage_delta);
       base::UmaHistogramSparse(
-          "Memory.Experimental.OomIntervention.ReducedRendererPMFAfter20secs",
+          "Memory.Experimental.OomIntervention.ReducedRendererPMFAfter20secs2",
           private_footprint_delta);
       break;
     case 1:
       base::UmaHistogramSparse(
-          "Memory.Experimental.OomIntervention.ReducedBlinkUsageAfter30secs",
+          "Memory.Experimental.OomIntervention.ReducedBlinkUsageAfter30secs2",
           blink_usage_delta);
       base::UmaHistogramSparse(
-          "Memory.Experimental.OomIntervention.ReducedRendererPMFAfter30secs",
+          "Memory.Experimental.OomIntervention.ReducedRendererPMFAfter30secs2",
           private_footprint_delta);
       delayed_report_timer_.Stop();
       break;
diff --git a/third_party/blink/renderer/controller/oom_intervention_impl_test.cc b/third_party/blink/renderer/controller/oom_intervention_impl_test.cc
index ad7bbf3e..c5db1ae 100644
--- a/third_party/blink/renderer/controller/oom_intervention_impl_test.cc
+++ b/third_party/blink/renderer/controller/oom_intervention_impl_test.cc
@@ -331,10 +331,10 @@
   intervention_->mock_memory_usage_monitor()->SetMockMemoryUsage(usage);
   test::RunDelayedTasks(TimeDelta::FromSeconds(10));
   histogram_tester.ExpectUniqueSample(
-      "Memory.Experimental.OomIntervention.ReducedBlinkUsageAfter10secs", -2,
+      "Memory.Experimental.OomIntervention.ReducedBlinkUsageAfter10secs2", 2,
       1);
   histogram_tester.ExpectUniqueSample(
-      "Memory.Experimental.OomIntervention.ReducedRendererPMFAfter10secs", 2,
+      "Memory.Experimental.OomIntervention.ReducedRendererPMFAfter10secs2", -2,
       1);
 
   usage.v8_bytes = initial_blink_usage_bytes - 1;
@@ -342,9 +342,10 @@
   intervention_->mock_memory_usage_monitor()->SetMockMemoryUsage(usage);
   test::RunDelayedTasks(TimeDelta::FromSeconds(10));
   histogram_tester.ExpectUniqueSample(
-      "Memory.Experimental.OomIntervention.ReducedBlinkUsageAfter20secs", 0, 1);
+      "Memory.Experimental.OomIntervention.ReducedBlinkUsageAfter20secs2", 0,
+      1);
   histogram_tester.ExpectUniqueSample(
-      "Memory.Experimental.OomIntervention.ReducedRendererPMFAfter20secs", 0,
+      "Memory.Experimental.OomIntervention.ReducedRendererPMFAfter20secs2", 0,
       1);
 
   usage.v8_bytes = initial_blink_usage_bytes - 800 * 1024 * 1024;
@@ -353,11 +354,11 @@
   intervention_->mock_memory_usage_monitor()->SetMockMemoryUsage(usage);
   test::RunDelayedTasks(TimeDelta::FromSeconds(10));
   histogram_tester.ExpectUniqueSample(
-      "Memory.Experimental.OomIntervention.ReducedBlinkUsageAfter30secs", -500,
+      "Memory.Experimental.OomIntervention.ReducedBlinkUsageAfter30secs2", 500,
       1);
   histogram_tester.ExpectUniqueSample(
-      "Memory.Experimental.OomIntervention.ReducedRendererPMFAfter30secs", 500,
-      1);
+      "Memory.Experimental.OomIntervention.ReducedRendererPMFAfter30secs2",
+      -500, 1);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/animation/css_font_size_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_font_size_interpolation_type.cc
index e525d13..fc72465 100644
--- a/third_party/blink/renderer/core/animation/css_font_size_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_font_size_interpolation_type.cc
@@ -21,12 +21,9 @@
 
 class IsMonospaceChecker : public CSSInterpolationType::CSSConversionChecker {
  public:
-  static std::unique_ptr<IsMonospaceChecker> Create(bool is_monospace) {
-    return base::WrapUnique(new IsMonospaceChecker(is_monospace));
-  }
+  IsMonospaceChecker(bool is_monospace) : is_monospace_(is_monospace) {}
 
  private:
-  IsMonospaceChecker(bool is_monospace) : is_monospace_(is_monospace) {}
 
   bool IsValid(const StyleResolverState& state,
                const InterpolationValue&) const final {
@@ -39,15 +36,10 @@
 class InheritedFontSizeChecker
     : public CSSInterpolationType::CSSConversionChecker {
  public:
-  static std::unique_ptr<InheritedFontSizeChecker> Create(
-      const FontDescription::Size& inherited_font_size) {
-    return base::WrapUnique(new InheritedFontSizeChecker(inherited_font_size));
-  }
-
- private:
   InheritedFontSizeChecker(const FontDescription::Size& inherited_font_size)
       : inherited_font_size_(inherited_font_size.value) {}
 
+ private:
   bool IsValid(const StyleResolverState& state,
                const InterpolationValue&) const final {
     return inherited_font_size_ ==
@@ -68,7 +60,8 @@
     InterpolationType::ConversionCheckers& conversion_checkers) {
   if (FontSizeFunctions::IsValidValueID(value_id)) {
     bool is_monospace = state.Style()->GetFontDescription().IsMonospace();
-    conversion_checkers.push_back(IsMonospaceChecker::Create(is_monospace));
+    conversion_checkers.push_back(
+        std::make_unique<IsMonospaceChecker>(is_monospace));
     return ConvertFontSize(state.GetFontBuilder().FontSizeForKeyword(
         FontSizeFunctions::KeywordSize(value_id), is_monospace));
   }
@@ -79,7 +72,7 @@
   const FontDescription::Size& inherited_font_size =
       state.ParentFontDescription().GetSize();
   conversion_checkers.push_back(
-      InheritedFontSizeChecker::Create(inherited_font_size));
+      std::make_unique<InheritedFontSizeChecker>(inherited_font_size));
   if (value_id == CSSValueSmaller)
     return ConvertFontSize(
         FontDescription::SmallerSize(inherited_font_size).value);
@@ -109,7 +102,7 @@
   const FontDescription::Size& inherited_font_size =
       state.ParentFontDescription().GetSize();
   conversion_checkers.push_back(
-      InheritedFontSizeChecker::Create(inherited_font_size));
+      std::make_unique<InheritedFontSizeChecker>(inherited_font_size));
   return ConvertFontSize(inherited_font_size.value);
 }
 
diff --git a/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc b/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc
index 067f9b6..ad72d0b 100644
--- a/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc
+++ b/third_party/blink/renderer/core/animation/css_image_interpolation_type.cc
@@ -159,17 +159,11 @@
 class UnderlyingImageChecker
     : public CSSInterpolationType::CSSConversionChecker {
  public:
-  ~UnderlyingImageChecker() final = default;
-
-  static std::unique_ptr<UnderlyingImageChecker> Create(
-      const InterpolationValue& underlying) {
-    return base::WrapUnique(new UnderlyingImageChecker(underlying));
-  }
-
- private:
   UnderlyingImageChecker(const InterpolationValue& underlying)
       : underlying_(underlying.Clone()) {}
+  ~UnderlyingImageChecker() final = default;
 
+ private:
   bool IsValid(const StyleResolverState&,
                const InterpolationValue& underlying) const final {
     if (!underlying && !underlying_)
@@ -189,7 +183,8 @@
 InterpolationValue CSSImageInterpolationType::MaybeConvertNeutral(
     const InterpolationValue& underlying,
     ConversionCheckers& conversion_checkers) const {
-  conversion_checkers.push_back(UnderlyingImageChecker::Create(underlying));
+  conversion_checkers.push_back(
+      std::make_unique<UnderlyingImageChecker>(underlying));
   return InterpolationValue(underlying.Clone());
 }
 
@@ -202,20 +197,12 @@
 class InheritedImageChecker
     : public CSSInterpolationType::CSSConversionChecker {
  public:
-  ~InheritedImageChecker() final = default;
-
-  static std::unique_ptr<InheritedImageChecker> Create(
-      const CSSProperty& property,
-      StyleImage* inherited_image) {
-    return base::WrapUnique(
-        new InheritedImageChecker(property, inherited_image));
-  }
-
- private:
   InheritedImageChecker(const CSSProperty& property,
                         StyleImage* inherited_image)
       : property_(property), inherited_image_(inherited_image) {}
+  ~InheritedImageChecker() final = default;
 
+ private:
   bool IsValid(const StyleResolverState& state,
                const InterpolationValue& underlying) const final {
     const StyleImage* inherited_image =
@@ -241,7 +228,7 @@
       GetStyleImage(CssProperty(), *state.ParentStyle());
   StyleImage* refable_image = const_cast<StyleImage*>(inherited_image);
   conversion_checkers.push_back(
-      InheritedImageChecker::Create(CssProperty(), refable_image));
+      std::make_unique<InheritedImageChecker>(CssProperty(), refable_image));
   return MaybeConvertStyleImage(inherited_image, true);
 }
 
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context.cc b/third_party/blink/renderer/core/display_lock/display_lock_context.cc
index 52a5525..c879ab7 100644
--- a/third_party/blink/renderer/core/display_lock/display_lock_context.cc
+++ b/third_party/blink/renderer/core/display_lock/display_lock_context.cc
@@ -84,8 +84,8 @@
       document_(&element_->GetDocument()),
       state_(this),
       weak_factory_(this) {
-  DCHECK(document_->View());
-  document_->View()->RegisterForLifecycleNotifications(this);
+  if (document_->View())
+    document_->View()->RegisterForLifecycleNotifications(this);
 }
 
 DisplayLockContext::~DisplayLockContext() {
@@ -173,7 +173,7 @@
 
   // If we're already connected then we need to ensure that 1. layout is clean
   // and 2. we have removed the current painted output.
-  if (element_->isConnected()) {
+  if (ConnectedToView()) {
     acquire_resolver_ = ScriptPromiseResolver::Create(script_state);
     state_ = kPendingAcquire;
     MarkPaintLayerNeedsRepaint();
@@ -190,8 +190,7 @@
 ScriptPromise DisplayLockContext::update(ScriptState* script_state) {
   TRACE_EVENT0("blink", "DisplayLockContext::update()");
   // Reject if we're unlocked or disconnected.
-  if (state_ == kUnlocked || state_ == kPendingAcquire ||
-      !element_->isConnected()) {
+  if (state_ == kUnlocked || state_ == kPendingAcquire || !ConnectedToView()) {
     return GetRejectedPromise(script_state,
                               rejection_names::kElementIsUnlocked);
   }
@@ -247,7 +246,7 @@
   // haven't acquired the lock, or we're already sync committing), then do
   // whatever commit() would do.
   if (state_ == kPendingAcquire || state_ == kCommitting ||
-      !element_->isConnected()) {
+      !ConnectedToView()) {
     return commit(script_state);
   }
 
@@ -387,7 +386,7 @@
 
 void DisplayLockContext::CommitForActivation() {
   DCHECK(element_);
-  DCHECK(element_->isConnected());
+  DCHECK(ConnectedToView());
   DCHECK(ShouldCommitForActivation());
   StartCommit();
 }
@@ -454,7 +453,7 @@
 void DisplayLockContext::StartCommit() {
   // If we don't have an element or we're not connected, then the process of
   // committing is the same as just unlocking the element.
-  if (!element_ || !element_->isConnected()) {
+  if (!element_ || !ConnectedToView()) {
     state_ = kUnlocked;
     update_budget_.reset();
     CancelTimeoutTask();
@@ -674,7 +673,7 @@
 
   // If we became disconnected for any reason, then we should reject the
   // update promise and go back to the locked state.
-  if (!element_ || !element_->isConnected()) {
+  if (!element_ || !ConnectedToView()) {
     FinishUpdateResolver(kReject, rejection_names::kElementIsDisconnected);
     update_budget_.reset();
 
@@ -717,7 +716,7 @@
 
 void DisplayLockContext::ScheduleAnimation() {
   DCHECK(element_);
-  DCHECK(element_->isConnected());
+  DCHECK(ConnectedToView());
 
   // Schedule an animation to perform the lifecycle phases.
   document_->GetPage()->Animator().ScheduleVisualUpdate(document_->GetFrame());
@@ -783,6 +782,11 @@
   return !style || (style->ContainsStyle() && style->ContainsLayout());
 }
 
+bool DisplayLockContext::ConnectedToView() const {
+  DCHECK(element_);
+  return element_->isConnected() && document_->View();
+}
+
 // Scoped objects implementation
 // -----------------------------------------------
 
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context.h b/third_party/blink/renderer/core/display_lock/display_lock_context.h
index e965a536..aee69443 100644
--- a/third_party/blink/renderer/core/display_lock/display_lock_context.h
+++ b/third_party/blink/renderer/core/display_lock/display_lock_context.h
@@ -250,6 +250,12 @@
   // exists. Otherwise, falls back to checking computed style.
   bool ElementSupportsDisplayLocking() const;
 
+  // Returns true if the element is connected to a document that has a view.
+  // If we're not connected,  or if we're connected but the document doesn't
+  // have a view (e.g. templates) we shouldn't do style calculations etc and
+  // when acquiring this lock should immediately resolve the acquire promise.
+  bool ConnectedToView() const;
+
   std::unique_ptr<DisplayLockBudget> update_budget_;
 
   Member<ScriptPromiseResolver> commit_resolver_;
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc b/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc
index c8f9c71..32a0df9 100644
--- a/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc
+++ b/third_party/blink/renderer/core/display_lock/display_lock_context_test.cc
@@ -5,12 +5,15 @@
 #include "third_party/blink/renderer/core/display_lock/display_lock_context.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
 #include "third_party/blink/renderer/core/display_lock/display_lock_options.h"
+#include "third_party/blink/renderer/core/dom/node_computed_style.h"
 #include "third_party/blink/renderer/core/editing/ephemeral_range.h"
 #include "third_party/blink/renderer/core/editing/finder/text_finder.h"
 #include "third_party/blink/renderer/core/editing/visible_units.h"
 #include "third_party/blink/renderer/core/frame/find_in_page.h"
 #include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
 #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
+#include "third_party/blink/renderer/core/html/html_template_element.h"
+#include "third_party/blink/renderer/core/style/computed_style.h"
 #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
@@ -1088,4 +1091,91 @@
   EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 0);
   EXPECT_TRUE(activatable->GetDisplayLockContext()->IsActivatable());
 }
+
+TEST_F(DisplayLockContextTest, ElementInTemplate) {
+  ResizeAndFocus();
+  SetHtmlInnerHTML(R"HTML(
+    <style>
+    div {
+      width: 100px;
+      height: 100px;
+      contain: content;
+    }
+    </style>
+    <body>
+      <template id="template"><div id="child">foo</div></template>
+    </body>
+  )HTML");
+
+  EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 0);
+  EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 0);
+
+  auto* template_el =
+      ToHTMLTemplateElement(GetDocument().getElementById("template"));
+  auto* child = ToElement(template_el->content()->firstChild());
+  EXPECT_FALSE(child->isConnected());
+  ASSERT_TRUE(child->getDisplayLockForBindings());
+
+  // Try to lock an element in a template.
+  auto* script_state = ToScriptStateForMainWorld(GetDocument().GetFrame());
+  {
+    ScriptState::Scope scope(script_state);
+    child->getDisplayLockForBindings()->acquire(script_state, nullptr);
+  }
+
+  UpdateAllLifecyclePhasesForTest();
+
+  EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 0);
+  EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 0);
+  EXPECT_TRUE(child->getDisplayLockForBindings()->IsLocked());
+
+  // commit() will unlock the element.
+  {
+    ScriptState::Scope scope(script_state);
+    child->getDisplayLockForBindings()->commit(script_state);
+  }
+  UpdateAllLifecyclePhasesForTest();
+  EXPECT_FALSE(child->getDisplayLockForBindings()->IsLocked());
+
+  // Try to lock an element that was moved from a template to a document.
+  auto* document_child =
+      ToElement(GetDocument().adoptNode(child, ASSERT_NO_EXCEPTION));
+  GetDocument().body()->appendChild(document_child);
+
+  {
+    ScriptState::Scope scope(script_state);
+    document_child->getDisplayLockForBindings()->acquire(script_state, nullptr);
+  }
+
+  UpdateAllLifecyclePhasesForTest();
+
+  EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 1);
+  EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 1);
+  EXPECT_TRUE(document_child->getDisplayLockForBindings()->IsLocked());
+
+  document_child->setAttribute("style", "color: red;");
+
+  EXPECT_TRUE(document_child->NeedsStyleRecalc());
+
+  UpdateAllLifecyclePhasesForTest();
+
+  EXPECT_TRUE(document_child->NeedsStyleRecalc());
+
+  // commit() will unlock the element and update the style.
+  {
+    ScriptState::Scope scope(script_state);
+    document_child->getDisplayLockForBindings()->commit(script_state);
+  }
+  UpdateAllLifecyclePhasesForTest();
+  EXPECT_FALSE(document_child->getDisplayLockForBindings()->IsLocked());
+  EXPECT_EQ(GetDocument().LockedDisplayLockCount(), 0);
+  EXPECT_EQ(GetDocument().ActivationBlockingDisplayLockCount(), 0);
+
+  EXPECT_FALSE(document_child->NeedsStyleRecalc());
+  ASSERT_TRUE(document_child->GetComputedStyle());
+  EXPECT_EQ(document_child->GetComputedStyle()->VisitedDependentColor(
+                GetCSSPropertyColor()),
+            MakeRGB(255, 0, 0));
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index 0e5f5aa..d52c978a 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -6823,7 +6823,8 @@
     console_message = ConsoleMessage::Create(
         console_message->Source(), console_message->Level(),
         console_message->Message(),
-        SourceLocation::Create(Url().GetString(), line_number, 0, nullptr));
+        std::make_unique<SourceLocation>(Url().GetString(), line_number, 0,
+                                         nullptr));
     console_message->SetNodes(frame_, std::move(nodes));
   }
 
@@ -7904,10 +7905,11 @@
 
 void Document::SendViolationReport(
     mojom::blink::CSPViolationParamsPtr violation_params) {
-  std::unique_ptr<SourceLocation> source_location = SourceLocation::Create(
-      violation_params->source_location->url,
-      violation_params->source_location->line_number,
-      violation_params->source_location->column_number, nullptr);
+  std::unique_ptr<SourceLocation> source_location =
+      std::make_unique<SourceLocation>(
+          violation_params->source_location->url,
+          violation_params->source_location->line_number,
+          violation_params->source_location->column_number, nullptr);
 
   Vector<String> report_endpoints;
   for (const WebString& end_point : violation_params->report_endpoints)
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index e84ee06..56ccfad 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -1945,7 +1945,8 @@
     if (rare_data->IntersectionObserverData() &&
         rare_data->IntersectionObserverData()->HasObservations()) {
       GetDocument().EnsureIntersectionObserverController().AddTrackedTarget(
-          *this);
+          *this,
+          rare_data->IntersectionObserverData()->NeedsOcclusionTracking());
       if (LocalFrameView* frame_view = GetDocument().View())
         frame_view->SetIntersectionObservationState(LocalFrameView::kRequired);
     }
@@ -3612,9 +3613,16 @@
   return EnsureElementRareData().EnsureIntersectionObserverData();
 }
 
-void Element::ComputeIntersectionObservations(unsigned flags) {
+bool Element::ComputeIntersectionObservations(unsigned flags) {
   if (ElementIntersectionObserverData* data = IntersectionObserverData())
-    data->ComputeObservations(flags);
+    return data->ComputeObservations(flags);
+  return false;
+}
+
+bool Element::NeedsOcclusionTracking() const {
+  if (ElementIntersectionObserverData* data = IntersectionObserverData())
+    return data->NeedsOcclusionTracking();
+  return false;
 }
 
 HeapHashMap<TraceWrapperMember<ResizeObserver>, Member<ResizeObservation>>*
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h
index fabdf480..1e41a38 100644
--- a/third_party/blink/renderer/core/dom/element.h
+++ b/third_party/blink/renderer/core/dom/element.h
@@ -885,7 +885,10 @@
 
   ElementIntersectionObserverData* IntersectionObserverData() const;
   ElementIntersectionObserverData& EnsureIntersectionObserverData();
-  void ComputeIntersectionObservations(unsigned flags);
+  bool ComputeIntersectionObservations(unsigned flags);
+  // Returns true if the Element is being observed by an IntersectionObserver
+  // for which trackVisibility() is true.
+  bool NeedsOcclusionTracking() const;
 
   HeapHashMap<TraceWrapperMember<ResizeObserver>, Member<ResizeObservation>>*
   ResizeObserverData() const;
diff --git a/third_party/blink/renderer/core/events/error_event.cc b/third_party/blink/renderer/core/events/error_event.cc
index 635b06d..2a2bd50 100644
--- a/third_party/blink/renderer/core/events/error_event.cc
+++ b/third_party/blink/renderer/core/events/error_event.cc
@@ -44,13 +44,14 @@
   // https://html.spec.whatwg.org/C/#runtime-script-errors:muted-errors
   DCHECK(script_state);
   return MakeGarbageCollected<ErrorEvent>(
-      "Script error.", SourceLocation::Create(String(), 0, 0, nullptr),
+      "Script error.",
+      std::make_unique<SourceLocation>(String(), 0, 0, nullptr),
       ScriptValue::CreateNull(script_state), &script_state->World());
 }
 
 ErrorEvent::ErrorEvent()
     : sanitized_message_(),
-      location_(SourceLocation::Create(String(), 0, 0, nullptr)),
+      location_(std::make_unique<SourceLocation>(String(), 0, 0, nullptr)),
       world_(&DOMWrapperWorld::Current(v8::Isolate::GetCurrent())) {}
 
 ErrorEvent::ErrorEvent(ScriptState* script_state,
@@ -61,7 +62,7 @@
       world_(&script_state->World()) {
   if (initializer->hasMessage())
     sanitized_message_ = initializer->message();
-  location_ = SourceLocation::Create(
+  location_ = std::make_unique<SourceLocation>(
       initializer->hasFilename() ? initializer->filename() : String(),
       initializer->hasLineno() ? initializer->lineno() : 0,
       initializer->hasColno() ? initializer->colno() : 0, nullptr);
diff --git a/third_party/blink/renderer/core/exported/web_associated_url_loader_impl_test.cc b/third_party/blink/renderer/core/exported/web_associated_url_loader_impl_test.cc
index c7fa93a4..09b09867 100644
--- a/third_party/blink/renderer/core/exported/web_associated_url_loader_impl_test.cc
+++ b/third_party/blink/renderer/core/exported/web_associated_url_loader_impl_test.cc
@@ -77,7 +77,7 @@
   KURL RegisterMockedUrl(const std::string& url_root,
                          const WTF::String& filename) {
     WebURLResponse response;
-    response.SetMIMEType("text/html");
+    response.SetMimeType("text/html");
     KURL url = ToKURL(url_root + filename.Utf8().data());
     Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
         url, response, test::CoreTestDataPath(filename.Utf8().data()));
@@ -226,7 +226,7 @@
 
     WebString header_name_string(WebString::FromUTF8(header_name));
     expected_response_ = WebURLResponse();
-    expected_response_.SetMIMEType("text/html");
+    expected_response_.SetMimeType("text/html");
     expected_response_.SetHttpStatusCode(200);
     expected_response_.AddHTTPHeaderField("Access-Control-Allow-Origin", "*");
     if (exposed) {
@@ -280,7 +280,7 @@
   request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit);
 
   expected_response_ = WebURLResponse();
-  expected_response_.SetMIMEType("text/html");
+  expected_response_.SetMimeType("text/html");
   expected_response_.SetHttpStatusCode(200);
   Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
       url, expected_response_, frame_file_path_);
@@ -315,7 +315,7 @@
   request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit);
 
   expected_response_ = WebURLResponse();
-  expected_response_.SetMIMEType("text/html");
+  expected_response_.SetMimeType("text/html");
   expected_response_.SetHttpStatusCode(200);
   Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
       url, expected_response_, frame_file_path_);
@@ -340,7 +340,7 @@
   request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit);
 
   expected_response_ = WebURLResponse();
-  expected_response_.SetMIMEType("text/html");
+  expected_response_.SetMimeType("text/html");
   expected_response_.SetHttpStatusCode(200);
   expected_response_.AddHTTPHeaderField("access-control-allow-origin", "*");
   Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
@@ -368,7 +368,7 @@
   request.SetFetchRequestMode(network::mojom::FetchRequestMode::kCors);
 
   expected_response_ = WebURLResponse();
-  expected_response_.SetMIMEType("text/html");
+  expected_response_.SetMimeType("text/html");
   expected_response_.SetHttpStatusCode(200);
   expected_response_.AddHTTPHeaderField("access-control-allow-origin", "*");
   Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
@@ -398,7 +398,7 @@
   request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit);
 
   expected_response_ = WebURLResponse();
-  expected_response_.SetMIMEType("text/html");
+  expected_response_.SetMimeType("text/html");
   expected_response_.SetHttpStatusCode(0);
   expected_response_.AddHTTPHeaderField("access-control-allow-origin", "*");
   Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
@@ -428,7 +428,7 @@
   request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit);
 
   expected_redirect_response_ = WebURLResponse();
-  expected_redirect_response_.SetMIMEType("text/html");
+  expected_redirect_response_.SetMimeType("text/html");
   expected_redirect_response_.SetHttpStatusCode(301);
   expected_redirect_response_.SetHTTPHeaderField("Location", redirect);
   Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
@@ -437,7 +437,7 @@
   expected_new_url_ = WebURL(redirect_url);
 
   expected_response_ = WebURLResponse();
-  expected_response_.SetMIMEType("text/html");
+  expected_response_.SetMimeType("text/html");
   expected_response_.SetHttpStatusCode(200);
   Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
       redirect_url, expected_response_, frame_file_path_);
@@ -464,7 +464,7 @@
   request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit);
 
   expected_redirect_response_ = WebURLResponse();
-  expected_redirect_response_.SetMIMEType("text/html");
+  expected_redirect_response_.SetMimeType("text/html");
   expected_redirect_response_.SetHttpStatusCode(301);
   expected_redirect_response_.SetHTTPHeaderField("Location", redirect);
   Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
@@ -473,7 +473,7 @@
   expected_new_url_ = WebURL(redirect_url);
 
   expected_response_ = WebURLResponse();
-  expected_response_.SetMIMEType("text/html");
+  expected_response_.SetMimeType("text/html");
   expected_response_.SetHttpStatusCode(200);
   Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
       redirect_url, expected_response_, frame_file_path_);
@@ -504,7 +504,7 @@
   request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit);
 
   expected_redirect_response_ = WebURLResponse();
-  expected_redirect_response_.SetMIMEType("text/html");
+  expected_redirect_response_.SetMimeType("text/html");
   expected_redirect_response_.SetHttpStatusCode(301);
   expected_redirect_response_.SetHTTPHeaderField("Location", redirect);
   Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
@@ -513,7 +513,7 @@
   expected_new_url_ = WebURL(redirect_url);
 
   expected_response_ = WebURLResponse();
-  expected_response_.SetMIMEType("text/html");
+  expected_response_.SetMimeType("text/html");
   expected_response_.SetHttpStatusCode(200);
   Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
       redirect_url, expected_response_, frame_file_path_);
@@ -551,7 +551,7 @@
   // Create a redirect response that allows the redirect to pass the access
   // control checks.
   expected_redirect_response_ = WebURLResponse();
-  expected_redirect_response_.SetMIMEType("text/html");
+  expected_redirect_response_.SetMimeType("text/html");
   expected_redirect_response_.SetHttpStatusCode(301);
   expected_redirect_response_.SetHTTPHeaderField("Location", redirect);
   expected_redirect_response_.AddHTTPHeaderField("access-control-allow-origin",
@@ -562,7 +562,7 @@
   expected_new_url_ = WebURL(redirect_url);
 
   expected_response_ = WebURLResponse();
-  expected_response_.SetMIMEType("text/html");
+  expected_response_.SetMimeType("text/html");
   expected_response_.SetHttpStatusCode(200);
   expected_response_.AddHTTPHeaderField("access-control-allow-origin", "*");
   Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
@@ -669,7 +669,7 @@
 
   WebString header_name_string(WebString::FromUTF8("non-whitelisted"));
   expected_response_ = WebURLResponse();
-  expected_response_.SetMIMEType("text/html");
+  expected_response_.SetMimeType("text/html");
   expected_response_.SetHttpStatusCode(200);
   expected_response_.AddHTTPHeaderField("Access-Control-Allow-Origin", "*");
   expected_response_.AddHTTPHeaderField(header_name_string, "foo");
@@ -699,7 +699,7 @@
   request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit);
 
   expected_response_ = WebURLResponse();
-  expected_response_.SetMIMEType("text/plain");
+  expected_response_.SetMimeType("text/plain");
   expected_response_.SetHttpStatusCode(200);
   Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
       url, expected_response_, frame_file_path_);
@@ -726,7 +726,7 @@
   request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit);
 
   expected_response_ = WebURLResponse();
-  expected_response_.SetMIMEType("text/plain");
+  expected_response_.SetMimeType("text/plain");
   expected_response_.SetHttpStatusCode(200);
   Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
       url, expected_response_, frame_file_path_);
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 6444501..516dba71 100644
--- a/third_party/blink/renderer/core/exported/web_frame_test.cc
+++ b/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -228,7 +228,7 @@
                                         const std::string& csp,
                                         bool report_only = false) {
     WebURLResponse response;
-    response.SetMIMEType("text/html");
+    response.SetMimeType("text/html");
     response.AddHTTPHeaderField(
         report_only ? WebString("Content-Security-Policy-Report-Only")
                     : WebString("Content-Security-Policy"),
@@ -7283,14 +7283,14 @@
   char redirect[] = "http://internal.test/first_party.html";
   WebURL redirect_url(ToKURL(redirect));
   WebURLResponse redirect_response;
-  redirect_response.SetMIMEType("text/html");
+  redirect_response.SetMimeType("text/html");
   redirect_response.SetHttpStatusCode(302);
   redirect_response.SetHTTPHeaderField("Location", redirect);
   Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
       test_url, redirect_response, file_path);
 
   WebURLResponse final_response;
-  final_response.SetMIMEType("text/html");
+  final_response.SetMimeType("text/html");
   Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(
       redirect_url, final_response, file_path);
 
diff --git a/third_party/blink/renderer/core/exported/web_navigation_params.cc b/third_party/blink/renderer/core/exported/web_navigation_params.cc
index 3c85a4c..d25110db 100644
--- a/third_party/blink/renderer/core/exported/web_navigation_params.cc
+++ b/third_party/blink/renderer/core/exported/web_navigation_params.cc
@@ -111,7 +111,7 @@
                                              WebString text_encoding,
                                              base::span<const char> data) {
   params->response = WebURLResponse(params->url);
-  params->response.SetMIMEType(mime_type);
+  params->response.SetMimeType(mime_type);
   params->response.SetTextEncodingName(text_encoding);
   FillBodyLoader(params, data);
 }
diff --git a/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc b/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc
index 6ee2ada0..005e3df 100644
--- a/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc
@@ -315,6 +315,10 @@
   GetFrame()->Owner()->DispatchLoad();
 }
 
+void WebRemoteFrameImpl::SetNeedsOcclusionTracking(bool needs_tracking) {
+  GetFrame()->View()->SetNeedsOcclusionTracking(needs_tracking);
+}
+
 void WebRemoteFrameImpl::DidStartLoading() {
   GetFrame()->SetIsLoading(true);
 }
diff --git a/third_party/blink/renderer/core/exported/web_remote_frame_impl.h b/third_party/blink/renderer/core/exported/web_remote_frame_impl.h
index 07063de..c2aeec9c 100644
--- a/third_party/blink/renderer/core/exported/web_remote_frame_impl.h
+++ b/third_party/blink/renderer/core/exported/web_remote_frame_impl.h
@@ -85,6 +85,7 @@
       const std::vector<unsigned>&) override;
   void ForwardResourceTimingToParent(const WebResourceTimingInfo&) override;
   void DispatchLoadEventForFrameOwner() override;
+  void SetNeedsOcclusionTracking(bool) override;
   void DidStartLoading() override;
   void DidStopLoading() override;
   bool IsIgnoredForHitTest() const override;
diff --git a/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc b/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc
index 33688e3..c6fa769 100644
--- a/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_shared_worker_impl.cc
@@ -426,9 +426,9 @@
   // TODO(nhiroki): Support module workers (https://crbug.com/680046).
   if (features::IsOffMainThreadSharedWorkerScriptFetchEnabled()) {
     // The script has not yet been fetched. Fetch it now.
-    GetWorkerThread()->ImportClassicScript(script_request_url_,
-                                           outside_settings_object,
-                                           v8_inspector::V8StackTraceId());
+    GetWorkerThread()->FetchAndRunClassicScript(script_request_url_,
+                                                outside_settings_object,
+                                                v8_inspector::V8StackTraceId());
     // We continue in WorkerGlobalScope::EvaluateClassicScript() on the worker
     // thread.
   } else {
diff --git a/third_party/blink/renderer/core/fetch/fetch_manager.cc b/third_party/blink/renderer/core/fetch/fetch_manager.cc
index 8b1e9d5..d2d936ec 100644
--- a/third_party/blink/renderer/core/fetch/fetch_manager.cc
+++ b/third_party/blink/renderer/core/fetch/fetch_manager.cc
@@ -425,7 +425,7 @@
     response_data->SetURLList(response.UrlListViaServiceWorker());
   }
 
-  response_data->SetMIMEType(response.MimeType());
+  response_data->SetMimeType(response.MimeType());
   response_data->SetResponseTime(response.ResponseTime());
 
   if (response.WasCached()) {
diff --git a/third_party/blink/renderer/core/fetch/fetch_request_data.cc b/third_party/blink/renderer/core/fetch/fetch_request_data.cc
index 4163b1d4..964c50d 100644
--- a/third_party/blink/renderer/core/fetch/fetch_request_data.cc
+++ b/third_party/blink/renderer/core/fetch/fetch_request_data.cc
@@ -48,7 +48,7 @@
   request->SetCredentials(web_request.CredentialsMode());
   request->SetCacheMode(web_request.CacheMode());
   request->SetRedirect(web_request.RedirectMode());
-  request->SetMIMEType(request->header_list_->ExtractMIMEType());
+  request->SetMimeType(request->header_list_->ExtractMIMEType());
   request->SetIntegrity(web_request.Integrity());
   request->SetPriority(
       static_cast<ResourceLoadPriority>(web_request.Priority()));
@@ -89,7 +89,7 @@
   request->SetCredentials(fetch_api_request.credentials_mode);
   request->SetCacheMode(fetch_api_request.cache_mode);
   request->SetRedirect(fetch_api_request.redirect_mode);
-  request->SetMIMEType(request->header_list_->ExtractMIMEType());
+  request->SetMimeType(request->header_list_->ExtractMIMEType());
   request->SetIntegrity(fetch_api_request.integrity);
   request->SetKeepalive(fetch_api_request.keepalive);
   request->SetIsHistoryNavigation(fetch_api_request.is_history_navigation);
diff --git a/third_party/blink/renderer/core/fetch/fetch_request_data.h b/third_party/blink/renderer/core/fetch/fetch_request_data.h
index 5dee7cc..6d147925 100644
--- a/third_party/blink/renderer/core/fetch/fetch_request_data.h
+++ b/third_party/blink/renderer/core/fetch/fetch_request_data.h
@@ -97,7 +97,7 @@
   BodyStreamBuffer* Buffer() const { return buffer_; }
   void SetBuffer(BodyStreamBuffer* buffer) { buffer_ = buffer; }
   String MimeType() const { return mime_type_; }
-  void SetMIMEType(const String& type) { mime_type_ = type; }
+  void SetMimeType(const String& type) { mime_type_ = type; }
   String Integrity() const { return integrity_; }
   void SetIntegrity(const String& integrity) { integrity_ = integrity; }
   ResourceLoadPriority Priority() const { return priority_; }
diff --git a/third_party/blink/renderer/core/fetch/fetch_response_data.h b/third_party/blink/renderer/core/fetch/fetch_response_data.h
index 246a404..3c0354f 100644
--- a/third_party/blink/renderer/core/fetch/fetch_response_data.h
+++ b/third_party/blink/renderer/core/fetch/fetch_response_data.h
@@ -93,7 +93,7 @@
   void SetStatusMessage(AtomicString status_message) {
     status_message_ = status_message;
   }
-  void SetMIMEType(const String& type) { mime_type_ = type; }
+  void SetMimeType(const String& type) { mime_type_ = type; }
   void SetResponseTime(Time response_time) { response_time_ = response_time; }
   void SetCacheStorageCacheName(const String& cache_storage_cache_name) {
     cache_storage_cache_name_ = cache_storage_cache_name;
diff --git a/third_party/blink/renderer/core/fetch/request.cc b/third_party/blink/renderer/core/fetch/request.cc
index b86e08c7..2d5b6c6 100644
--- a/third_party/blink/renderer/core/fetch/request.cc
+++ b/third_party/blink/renderer/core/fetch/request.cc
@@ -562,7 +562,7 @@
 
   // "Set |r|'s MIME type to the result of extracting a MIME type from |r|'s
   // request's header list."
-  r->request_->SetMIMEType(r->request_->HeaderList()->ExtractMIMEType());
+  r->request_->SetMimeType(r->request_->HeaderList()->ExtractMIMEType());
 
   // "If |input| is a Request object and |input|'s request's body is
   // non-null, run these substeps:"
diff --git a/third_party/blink/renderer/core/fetch/response.cc b/third_party/blink/renderer/core/fetch/response.cc
index f7d17d5..2debd16 100644
--- a/third_party/blink/renderer/core/fetch/response.cc
+++ b/third_party/blink/renderer/core/fetch/response.cc
@@ -103,7 +103,7 @@
   // construction.  We should plumb the value through the cache_storage
   // persistence layer and include the explicit mime type in FetchAPIResponse
   // to set here. See: crbug.com/938939
-  response->SetMIMEType(response->HeaderList()->ExtractMIMEType());
+  response->SetMimeType(response->HeaderList()->ExtractMIMEType());
 
   if (fetch_api_response.blob) {
     response->ReplaceBodyStreamBuffer(MakeGarbageCollected<BodyStreamBuffer>(
@@ -318,7 +318,7 @@
 
   // "9. Set |r|'s MIME type to the result of extracting a MIME type
   // from |r|'s response's header list."
-  r->response_->SetMIMEType(r->response_->HeaderList()->ExtractMIMEType());
+  r->response_->SetMimeType(r->response_->HeaderList()->ExtractMIMEType());
 
   // "10. Set |r|'s response’s HTTPS state to current settings object's"
   // HTTPS state."
diff --git a/third_party/blink/renderer/core/frame/frame.cc b/third_party/blink/renderer/core/frame/frame.cc
index 706e592..17a8160 100644
--- a/third_party/blink/renderer/core/frame/frame.cc
+++ b/third_party/blink/renderer/core/frame/frame.cc
@@ -118,6 +118,8 @@
   if (owner_->ContentFrame() == this)
     owner_->ClearContentFrame();
 
+  owner_->SetNeedsOcclusionTracking(false);
+
   owner_ = nullptr;
 }
 
diff --git a/third_party/blink/renderer/core/frame/frame_owner.h b/third_party/blink/renderer/core/frame/frame_owner.h
index e3c2435..6e9974d 100644
--- a/third_party/blink/renderer/core/frame/frame_owner.h
+++ b/third_party/blink/renderer/core/frame/frame_owner.h
@@ -56,6 +56,10 @@
   // relevant for SVG documents that are embedded via <object> or <embed>.
   virtual void IntrinsicSizingInfoChanged() = 0;
 
+  // Indicates that a child frame requires its parent frame to track whether the
+  // child frame is occluded or has visual effects applied.
+  virtual void SetNeedsOcclusionTracking(bool) = 0;
+
   // Returns the 'name' content attribute value of the browsing context
   // container.
   // https://html.spec.whatwg.org/C/#browsing-context-container
@@ -98,6 +102,7 @@
   bool CanRenderFallbackContent() const override { return false; }
   void RenderFallbackContent(Frame*) override {}
   void IntrinsicSizingInfoChanged() override {}
+  void SetNeedsOcclusionTracking(bool) override {}
   AtomicString BrowsingContextContainerName() const override {
     return AtomicString();
   }
diff --git a/third_party/blink/renderer/core/frame/frame_serializer_test.cc b/third_party/blink/renderer/core/frame/frame_serializer_test.cc
index 8a513ed..922200b 100644
--- a/third_party/blink/renderer/core/frame/frame_serializer_test.cc
+++ b/third_party/blink/renderer/core/frame/frame_serializer_test.cc
@@ -96,7 +96,7 @@
     ResourceError error = ResourceError::Failure(NullURL());
 
     WebURLResponse response;
-    response.SetMIMEType("text/html");
+    response.SetMimeType("text/html");
     response.SetHttpStatusCode(status_code);
 
     platform_->GetURLLoaderMockFactory()->RegisterErrorURL(
diff --git a/third_party/blink/renderer/core/frame/frame_view.h b/third_party/blink/renderer/core/frame/frame_view.h
index c23ce6bd..18d4cf9e 100644
--- a/third_party/blink/renderer/core/frame/frame_view.h
+++ b/third_party/blink/renderer/core/frame/frame_view.h
@@ -19,7 +19,7 @@
   // parent_flags is the result of calling GetIntersectionObservationFlags on
   // the LocalFrameView parent of this FrameView (if any). It contains dirty
   // bits based on whether geometry may have changed in the parent frame.
-  virtual void UpdateViewportIntersectionsForSubtree(unsigned parent_flags) = 0;
+  virtual bool UpdateViewportIntersectionsForSubtree(unsigned parent_flags) = 0;
 
   virtual bool GetIntrinsicSizingInfo(IntrinsicSizingInfo&) const = 0;
   virtual bool HasIntrinsicSizingInfo() const = 0;
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index 0b706dd..a440944a 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -1470,11 +1470,11 @@
 
 void LocalFrame::SetViewportIntersectionFromParent(
     const IntRect& viewport_intersection,
-    bool occluded_or_obscured) {
+    FrameOcclusionState occlusion_state) {
   if (remote_viewport_intersection_ != viewport_intersection ||
-      occluded_or_obscured_by_ancestor_ != occluded_or_obscured) {
+      occlusion_state_ != occlusion_state) {
     remote_viewport_intersection_ = viewport_intersection;
-    occluded_or_obscured_by_ancestor_ = occluded_or_obscured;
+    occlusion_state_ = occlusion_state;
     if (View()) {
       View()->SetIntersectionObservationState(LocalFrameView::kRequired);
       View()->ScheduleAnimation();
@@ -1482,6 +1482,14 @@
   }
 }
 
+FrameOcclusionState LocalFrame::GetOcclusionState() const {
+  if (IsMainFrame())
+    return kGuaranteedNotOccluded;
+  if (IsLocalRoot())
+    return occlusion_state_;
+  return LocalFrameRoot().GetOcclusionState();
+}
+
 void LocalFrame::ForceSynchronousDocumentInstall(
     const AtomicString& mime_type,
     scoped_refptr<SharedBuffer> data) {
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h
index 385669d1..32da97af 100644
--- a/third_party/blink/renderer/core/frame/local_frame.h
+++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -33,6 +33,7 @@
 
 #include "base/macros.h"
 #include "mojo/public/cpp/bindings/strong_binding_set.h"
+#include "third_party/blink/public/common/frame/occlusion_state.h"
 #include "third_party/blink/public/mojom/ad_tagging/ad_frame.mojom-blink.h"
 #include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink.h"
 #include "third_party/blink/public/mojom/loader/pause_subresource_loading_handle.mojom-blink.h"
@@ -362,13 +363,11 @@
   // Called on a view for a LocalFrame with a RemoteFrame parent. This makes
   // viewport intersection and occlusion/obscuration available that accounts for
   // remote ancestor frames and their respective scroll positions, clips, etc.
-  void SetViewportIntersectionFromParent(const IntRect&, bool);
+  void SetViewportIntersectionFromParent(const IntRect&, FrameOcclusionState);
   IntRect RemoteViewportIntersection() const {
     return remote_viewport_intersection_;
   }
-  bool MayBeOccludedOrObscuredByRemoteAncestor() const {
-    return occluded_or_obscured_by_ancestor_;
-  }
+  FrameOcclusionState GetOcclusionState() const;
 
   // Replaces the initial empty document with a Document suitable for
   // |mime_type| and populated with the contents of |data|. Only intended for
@@ -557,7 +556,7 @@
   mutable mojom::blink::ReportingServiceProxyPtr reporting_service_;
 
   IntRect remote_viewport_intersection_;
-  bool occluded_or_obscured_by_ancestor_ = false;
+  FrameOcclusionState occlusion_state_ = kUnknownOcclusionState;
   std::unique_ptr<FrameResourceCoordinator> frame_resource_coordinator_;
 
   // Per-frame URLLoader factory.
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc
index eac5b899..665feae 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -1070,7 +1070,9 @@
                "LocalFrameView::UpdateViewportIntersectionsForSubtree");
   SCOPED_UMA_AND_UKM_TIMER(EnsureUkmAggregator(),
                            LocalFrameUkmAggregator::kIntersectionObservation);
-  UpdateViewportIntersectionsForSubtree(0);
+  bool needs_occlusion_tracking = UpdateViewportIntersectionsForSubtree(0);
+  if (FrameOwner* owner = frame_->Owner())
+    owner->SetNeedsOcclusionTracking(needs_occlusion_tracking);
 #if DCHECK_IS_ON()
   DCHECK(was_dirty || !NeedsLayout());
 #endif
@@ -3878,7 +3880,7 @@
     CollectAnnotatedRegions(*curr, regions);
 }
 
-void LocalFrameView::UpdateViewportIntersectionsForSubtree(
+bool LocalFrameView::UpdateViewportIntersectionsForSubtree(
     unsigned parent_flags) {
   // TODO(dcheng): Since LocalFrameView tree updates are deferred, FrameViews
   // might still be in the LocalFrameView hierarchy even though the associated
@@ -3886,33 +3888,37 @@
   // in lifecycle updates are still needed when there are no more deferred
   // LocalFrameView updates: https://crbug.com/561683
   if (!GetFrame().GetDocument()->IsActive())
-    return;
+    return false;
 
   unsigned flags = GetIntersectionObservationFlags(parent_flags);
+  bool needs_occlusion_tracking = false;
 
   if (!NeedsLayout()) {
     // Notify javascript IntersectionObservers
-    if (GetFrame().GetDocument()->GetIntersectionObserverController()) {
-      GetFrame()
-          .GetDocument()
-          ->GetIntersectionObserverController()
-          ->ComputeTrackedIntersectionObservations(flags);
+    if (IntersectionObserverController* controller =
+            GetFrame().GetDocument()->GetIntersectionObserverController()) {
+      needs_occlusion_tracking |=
+          controller->ComputeTrackedIntersectionObservations(flags);
     }
     intersection_observation_state_ = kNotNeeded;
   }
 
   for (Frame* child = frame_->Tree().FirstChild(); child;
        child = child->Tree().NextSibling()) {
-    child->View()->UpdateViewportIntersectionsForSubtree(flags);
+    needs_occlusion_tracking |=
+        child->View()->UpdateViewportIntersectionsForSubtree(flags);
   }
 
   for (HTMLPortalElement* portal :
        DocumentPortals::From(*frame_->GetDocument()).GetPortals()) {
     if (portal->ContentFrame()) {
-      portal->ContentFrame()->View()->UpdateViewportIntersectionsForSubtree(
-          flags);
+      needs_occlusion_tracking |=
+          portal->ContentFrame()->View()->UpdateViewportIntersectionsForSubtree(
+              flags);
     }
   }
+
+  return needs_occlusion_tracking;
 }
 
 void LocalFrameView::DeliverSynchronousIntersectionObservations() {
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.h b/third_party/blink/renderer/core/frame/local_frame_view.h
index 92c3df1..b19fddc 100644
--- a/third_party/blink/renderer/core/frame/local_frame_view.h
+++ b/third_party/blink/renderer/core/frame/local_frame_view.h
@@ -864,7 +864,7 @@
   template <typename Function>
   void ForAllNonThrottledLocalFrameViews(const Function&);
 
-  void UpdateViewportIntersectionsForSubtree(unsigned parent_flags) override;
+  bool UpdateViewportIntersectionsForSubtree(unsigned parent_flags) override;
   void DeliverSynchronousIntersectionObservations();
 
   void UpdateThrottlingStatusForSubtree();
diff --git a/third_party/blink/renderer/core/frame/mhtml_loading_test.cc b/third_party/blink/renderer/core/frame/mhtml_loading_test.cc
index 366c161..da856d3 100644
--- a/third_party/blink/renderer/core/frame/mhtml_loading_test.cc
+++ b/third_party/blink/renderer/core/frame/mhtml_loading_test.cc
@@ -69,7 +69,7 @@
     auto params = std::make_unique<WebNavigationParams>();
     params->url = url;
     params->response = WebURLResponse(url);
-    params->response.SetMIMEType("multipart/related");
+    params->response.SetMimeType("multipart/related");
     params->response.SetHttpStatusCode(200);
     params->response.SetExpectedContentLength(buffer->size());
     auto body_loader = std::make_unique<StaticDataNavigationBodyLoader>();
diff --git a/third_party/blink/renderer/core/frame/remote_frame_client.h b/third_party/blink/renderer/core/frame/remote_frame_client.h
index dd07bbd..bdc360b 100644
--- a/third_party/blink/renderer/core/frame/remote_frame_client.h
+++ b/third_party/blink/renderer/core/frame/remote_frame_client.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_REMOTE_FRAME_CLIENT_H_
 
 #include "cc/paint/paint_canvas.h"
+#include "third_party/blink/public/common/frame/occlusion_state.h"
 #include "third_party/blink/public/mojom/blob/blob_url_store.mojom-blink.h"
 #include "third_party/blink/public/platform/web_focus_type.h"
 #include "third_party/blink/public/web/web_frame_load_type.h"
@@ -54,7 +55,7 @@
 
   virtual void UpdateRemoteViewportIntersection(
       const IntRect& viewport_intersection,
-      bool occluded_or_obscured) = 0;
+      FrameOcclusionState occlusion_state) = 0;
 
   virtual void AdvanceFocus(WebFocusType, LocalFrame* source) = 0;
 
diff --git a/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc b/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc
index 156dc6b..fc31e19 100644
--- a/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc
+++ b/third_party/blink/renderer/core/frame/remote_frame_client_impl.cc
@@ -155,9 +155,9 @@
 
 void RemoteFrameClientImpl::UpdateRemoteViewportIntersection(
     const IntRect& viewport_intersection,
-    bool occluded_or_obscured) {
+    FrameOcclusionState occlusion_state) {
   web_frame_->Client()->UpdateRemoteViewportIntersection(viewport_intersection,
-                                                         occluded_or_obscured);
+                                                         occlusion_state);
 }
 
 void RemoteFrameClientImpl::AdvanceFocus(WebFocusType type,
diff --git a/third_party/blink/renderer/core/frame/remote_frame_client_impl.h b/third_party/blink/renderer/core/frame/remote_frame_client_impl.h
index 92d3aa9..1a3f706 100644
--- a/third_party/blink/renderer/core/frame/remote_frame_client_impl.h
+++ b/third_party/blink/renderer/core/frame/remote_frame_client_impl.h
@@ -48,7 +48,8 @@
                           bool has_user_gesture) const override;
   void FrameRectsChanged(const IntRect& local_frame_rect,
                          const IntRect& screen_space_rect) override;
-  void UpdateRemoteViewportIntersection(const IntRect&, bool) override;
+  void UpdateRemoteViewportIntersection(const IntRect&,
+                                        FrameOcclusionState) override;
   void AdvanceFocus(WebFocusType, LocalFrame*) override;
   void VisibilityChanged(blink::mojom::FrameVisibility) override;
   void SetIsInert(bool) override;
diff --git a/third_party/blink/renderer/core/frame/remote_frame_owner.cc b/third_party/blink/renderer/core/frame/remote_frame_owner.cc
index e2bcaba..b35efa69 100644
--- a/third_party/blink/renderer/core/frame/remote_frame_owner.cc
+++ b/third_party/blink/renderer/core/frame/remote_frame_owner.cc
@@ -31,6 +31,7 @@
       allow_fullscreen_(frame_owner_properties.allow_fullscreen),
       allow_payment_request_(frame_owner_properties.allow_payment_request),
       is_display_none_(frame_owner_properties.is_display_none),
+      needs_occlusion_tracking_(false),
       required_csp_(frame_owner_properties.required_csp),
       container_policy_(container_policy),
       frame_owner_element_type_(frame_owner_element_type) {}
@@ -92,6 +93,15 @@
       ->IntrinsicSizingInfoChanged(intrinsic_sizing_info);
 }
 
+void RemoteFrameOwner::SetNeedsOcclusionTracking(bool needs_tracking) {
+  if (needs_tracking == needs_occlusion_tracking_)
+    return;
+  needs_occlusion_tracking_ = needs_tracking;
+  WebLocalFrameImpl* web_frame =
+      WebLocalFrameImpl::FromFrame(To<LocalFrame>(*frame_));
+  web_frame->Client()->SetNeedsOcclusionTracking(needs_tracking);
+}
+
 bool RemoteFrameOwner::ShouldLazyLoadChildren() const {
   // Don't use lazy load for children inside an OOPIF, since there's a good
   // chance that the parent FrameOwner was previously deferred by lazy load
diff --git a/third_party/blink/renderer/core/frame/remote_frame_owner.h b/third_party/blink/renderer/core/frame/remote_frame_owner.h
index b9a721d..040cbe3d3 100644
--- a/third_party/blink/renderer/core/frame/remote_frame_owner.h
+++ b/third_party/blink/renderer/core/frame/remote_frame_owner.h
@@ -53,6 +53,7 @@
   }
   void RenderFallbackContent(Frame*) override;
   void IntrinsicSizingInfoChanged() override;
+  void SetNeedsOcclusionTracking(bool) override;
 
   AtomicString BrowsingContextContainerName() const override {
     return browsing_context_container_name_;
@@ -108,6 +109,7 @@
   bool allow_fullscreen_;
   bool allow_payment_request_;
   bool is_display_none_;
+  bool needs_occlusion_tracking_;
   WebString required_csp_;
   ParsedFeaturePolicy container_policy_;
   const FrameOwnerElementType frame_owner_element_type_;
diff --git a/third_party/blink/renderer/core/frame/remote_frame_view.cc b/third_party/blink/renderer/core/frame/remote_frame_view.cc
index e039f3c..ea41020 100644
--- a/third_party/blink/renderer/core/frame/remote_frame_view.cc
+++ b/third_party/blink/renderer/core/frame/remote_frame_view.cc
@@ -82,11 +82,11 @@
   return view;
 }
 
-void RemoteFrameView::UpdateViewportIntersectionsForSubtree(
+bool RemoteFrameView::UpdateViewportIntersectionsForSubtree(
     unsigned parent_flags) {
   if (!(parent_flags &
         IntersectionObservation::kImplicitRootObserversNeedUpdate)) {
-    return;
+    return needs_occlusion_tracking_;
   }
 
   // This should only run in child frames.
@@ -94,21 +94,25 @@
   DCHECK(owner_element);
   LayoutEmbeddedContent* owner = owner_element->GetLayoutEmbeddedContent();
   if (!owner)
-    return;
+    return needs_occlusion_tracking_;
   IntRect viewport_intersection;
-  bool occluded_or_obscured = false;
+  DocumentLifecycle::LifecycleState parent_lifecycle_state =
+      owner_element->GetDocument().Lifecycle().GetState();
+  FrameOcclusionState occlusion_state =
+      owner_element->GetDocument().GetFrame()->GetOcclusionState();
+  bool should_compute_occlusion =
+      needs_occlusion_tracking_ && occlusion_state == kGuaranteedNotOccluded &&
+      parent_lifecycle_state >= DocumentLifecycle::kPrePaintClean &&
+      RuntimeEnabledFeatures::IntersectionObserverV2Enabled();
 
   // If the parent LocalFrameView is throttled and out-of-date, then we can't
   // get any useful information.
-  DocumentLifecycle::LifecycleState parent_state =
-      owner_element->GetDocument().Lifecycle().GetState();
-  if (parent_state >= DocumentLifecycle::kLayoutClean) {
+  if (parent_lifecycle_state >= DocumentLifecycle::kLayoutClean) {
     unsigned geometry_flags =
         IntersectionGeometry::kShouldUseReplacedContentRect;
-    if (parent_state >= DocumentLifecycle::kPrePaintClean &&
-        RuntimeEnabledFeatures::IntersectionObserverV2Enabled()) {
+    if (should_compute_occlusion)
       geometry_flags |= IntersectionGeometry::kShouldComputeVisibility;
-    }
+
     IntersectionGeometry geometry(nullptr, *owner_element, {},
                                   {IntersectionObserver::kMinimumThreshold},
                                   geometry_flags);
@@ -129,7 +133,10 @@
     } else {
       viewport_intersection = EnclosingIntRect(intersection_rect);
     }
-    occluded_or_obscured = !geometry.IsVisible();
+    if (should_compute_occlusion && !geometry.IsVisible())
+      occlusion_state = kPossiblyOccluded;
+  } else if (occlusion_state == kGuaranteedNotOccluded) {
+    occlusion_state = kUnknownOcclusionState;
   }
 
   // TODO(szager): There are some redundant IPC's here; clean them up.
@@ -138,14 +145,26 @@
   UpdateRenderThrottlingStatus(!is_visible_for_throttling, subtree_throttled_);
 
   if (viewport_intersection == last_viewport_intersection_ &&
-      occluded_or_obscured == last_occluded_or_obscured_) {
-    return;
+      occlusion_state == last_occlusion_state_) {
+    return needs_occlusion_tracking_;
   }
 
   last_viewport_intersection_ = viewport_intersection;
-  last_occluded_or_obscured_ = occluded_or_obscured;
+  last_occlusion_state_ = occlusion_state;
   remote_frame_->Client()->UpdateRemoteViewportIntersection(
-      viewport_intersection, occluded_or_obscured);
+      viewport_intersection, occlusion_state);
+
+  return needs_occlusion_tracking_;
+}
+
+void RemoteFrameView::SetNeedsOcclusionTracking(bool needs_tracking) {
+  if (needs_occlusion_tracking_ == needs_tracking)
+    return;
+  needs_occlusion_tracking_ = needs_tracking;
+  if (needs_tracking) {
+    if (LocalFrameView* parent_view = ParentLocalRootFrameView())
+      parent_view->ScheduleAnimation();
+  }
 }
 
 IntRect RemoteFrameView::GetCompositingRect() {
diff --git a/third_party/blink/renderer/core/frame/remote_frame_view.h b/third_party/blink/renderer/core/frame/remote_frame_view.h
index c9980f10..a246b3b 100644
--- a/third_party/blink/renderer/core/frame/remote_frame_view.h
+++ b/third_party/blink/renderer/core/frame/remote_frame_view.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_REMOTE_FRAME_VIEW_H_
 
 #include "cc/paint/paint_canvas.h"
+#include "third_party/blink/public/common/frame/occlusion_state.h"
 #include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink.h"
 #include "third_party/blink/renderer/core/dom/document_lifecycle.h"
 #include "third_party/blink/renderer/core/frame/frame_view.h"
@@ -59,7 +60,9 @@
   void Show() override;
   void SetParentVisible(bool) override;
 
-  void UpdateViewportIntersectionsForSubtree(unsigned parent_flags) override;
+  bool UpdateViewportIntersectionsForSubtree(unsigned parent_flags) override;
+  void SetNeedsOcclusionTracking(bool);
+  bool NeedsOcclusionTracking() const { return needs_occlusion_tracking_; }
 
   bool GetIntrinsicSizingInfo(IntrinsicSizingInfo&) const override;
 
@@ -97,7 +100,7 @@
   Member<RemoteFrame> remote_frame_;
   bool is_attached_;
   IntRect last_viewport_intersection_;
-  bool last_occluded_or_obscured_ = false;
+  FrameOcclusionState last_occlusion_state_ = kUnknownOcclusionState;
   IntRect frame_rect_;
   bool self_visible_;
   bool parent_visible_;
@@ -110,6 +113,7 @@
   bool hidden_for_throttling_ = false;
   IntrinsicSizingInfo intrinsic_sizing_info_;
   bool has_intrinsic_sizing_info_ = false;
+  bool needs_occlusion_tracking_ = false;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
index d11eed3..70ccd91 100644
--- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
@@ -610,14 +610,14 @@
 
 void WebFrameWidgetImpl::SetRemoteViewportIntersection(
     const WebRect& viewport_intersection,
-    bool occluded_or_obscured) {
+    FrameOcclusionState occlusion_state) {
   // Remote viewports are only applicable to local frames with remote ancestors.
   DCHECK(LocalRootImpl()->Parent() &&
          LocalRootImpl()->Parent()->IsWebRemoteFrame() &&
          LocalRootImpl()->GetFrame());
 
   LocalRootImpl()->GetFrame()->SetViewportIntersectionFromParent(
-      viewport_intersection, occluded_or_obscured);
+      viewport_intersection, occlusion_state);
 }
 
 void WebFrameWidgetImpl::SetIsInert(bool inert) {
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.h b/third_party/blink/renderer/core/frame/web_frame_widget_impl.h
index 9ade4b2b..d4992a6 100644
--- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.h
+++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.h
@@ -105,7 +105,8 @@
   void SetFocus(bool enable) override;
   bool SelectionBounds(WebRect& anchor, WebRect& focus) const override;
   bool IsAcceleratedCompositingActive() const override;
-  void SetRemoteViewportIntersection(const WebRect&, bool) override;
+  void SetRemoteViewportIntersection(const WebRect&,
+                                     FrameOcclusionState) override;
   void SetIsInert(bool) override;
   void SetInheritedEffectiveTouchAction(TouchAction) override;
   void UpdateRenderThrottlingStatus(bool is_throttled,
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
index fc72259..66ef809 100644
--- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -2129,9 +2129,10 @@
       violation.source_location.url, violation.source_location.line_number,
       violation.source_location.column_number));
 
-  std::unique_ptr<SourceLocation> source_location = SourceLocation::Create(
-      violation.source_location.url, violation.source_location.line_number,
-      violation.source_location.column_number, nullptr);
+  std::unique_ptr<SourceLocation> source_location =
+      std::make_unique<SourceLocation>(
+          violation.source_location.url, violation.source_location.line_number,
+          violation.source_location.column_number, nullptr);
 
   DCHECK(GetFrame() && GetFrame()->GetDocument());
   Document* document = GetFrame()->GetDocument();
@@ -2204,9 +2205,9 @@
   DCHECK(GetFrame());
   std::unique_ptr<SourceLocation> source;
   if (!source_location.url.IsNull()) {
-    source =
-        SourceLocation::Create(source_location.url, source_location.line_number,
-                               source_location.column_number, nullptr);
+    source = std::make_unique<SourceLocation>(
+        source_location.url, source_location.line_number,
+        source_location.column_number, nullptr);
   }
   MixedContentChecker::MixedContentFound(
       GetFrame(), main_resource_url, mixed_content_url, request_context,
@@ -2273,7 +2274,7 @@
 
   GetFrame()->DomWindow()->DispatchMessageEventWithOriginCheck(
       intended_target_origin.Get(), event,
-      SourceLocation::Create(String(), 0, 0, nullptr));
+      std::make_unique<SourceLocation>(String(), 0, 0, nullptr));
 }
 
 WebNode WebLocalFrameImpl::ContextMenuNode() const {
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 40a0fd0e..b733a12 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
@@ -104,6 +104,7 @@
   bool CanRenderFallbackContent() const override { return false; }
   void RenderFallbackContent(Frame*) override {}
   void IntrinsicSizingInfoChanged() override {}
+  void SetNeedsOcclusionTracking(bool) override {}
   AtomicString BrowsingContextContainerName() const override {
     return getAttribute(html_names::kNameAttr);
   }
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 027577f..8f9737f 100644
--- a/third_party/blink/renderer/core/html/html_link_element.idl
+++ b/third_party/blink/renderer/core/html/html_link_element.idl
@@ -36,8 +36,8 @@
     [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, MeasureAs=PriorityHints, OriginTrialEnabled=PriorityHints, Reflect, ReflectOnly=("low", "auto", "high"), ReflectMissing="auto", ReflectInvalid="auto"] attribute DOMString importance;
-    [RuntimeEnabled=PreloadImageSrcSet, CEReactions, Reflect] attribute DOMString imageSrcset;
-    [RuntimeEnabled=PreloadImageSrcSet, CEReactions, Reflect] attribute DOMString imageSizes;
+    [CEReactions, Reflect] attribute DOMString imageSrcset;
+    [CEReactions, Reflect] attribute DOMString imageSizes;
 
     // obsolete members
     // https://html.spec.whatwg.org/C/#HTMLLinkElement-partial
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 9cf66a6..f6564ce 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
@@ -193,8 +193,7 @@
 
   void PostProcessAfterAttributes() {
     if (Match(tag_impl_, kImgTag) ||
-        (link_is_preload_ && as_attribute_value_ == "image" &&
-         RuntimeEnabledFeatures::PreloadImageSrcSetEnabled()))
+        (link_is_preload_ && as_attribute_value_ == "image"))
       SetUrlFromImageAttributes();
   }
 
diff --git a/third_party/blink/renderer/core/inspector/console_message.cc b/third_party/blink/renderer/core/inspector/console_message.cc
index e7843eaf..24674619 100644
--- a/third_party/blink/renderer/core/inspector/console_message.cc
+++ b/third_party/blink/renderer/core/inspector/console_message.cc
@@ -71,8 +71,8 @@
 
   ConsoleMessage* console_message = ConsoleMessage::Create(
       message_source, message.level, message.text,
-      SourceLocation::Create(message.url, message.line_number,
-                             message.column_number, nullptr));
+      std::make_unique<SourceLocation>(message.url, message.line_number,
+                                       message.column_number, nullptr));
 
   if (local_frame) {
     Vector<DOMNodeId> nodes;
diff --git a/third_party/blink/renderer/core/inspector/main_thread_debugger.cc b/third_party/blink/renderer/core/inspector/main_thread_debugger.cc
index 763e05c9..f8de980 100644
--- a/third_party/blink/renderer/core/inspector/main_thread_debugger.cc
+++ b/third_party/blink/renderer/core/inspector/main_thread_debugger.cc
@@ -321,9 +321,9 @@
     return;
   // TODO(dgozman): we can save a copy of message and url here by making
   // FrameConsole work with StringView.
-  std::unique_ptr<SourceLocation> location =
-      SourceLocation::Create(ToCoreString(url), line_number, column_number,
-                             stack_trace ? stack_trace->clone() : nullptr, 0);
+  std::unique_ptr<SourceLocation> location = std::make_unique<SourceLocation>(
+      ToCoreString(url), line_number, column_number,
+      stack_trace ? stack_trace->clone() : nullptr, 0);
   frame->Console().ReportMessageToClient(kConsoleAPIMessageSource,
                                          V8MessageLevelToMessageLevel(level),
                                          ToCoreString(message), location.get());
diff --git a/third_party/blink/renderer/core/inspector/worker_thread_debugger.cc b/third_party/blink/renderer/core/inspector/worker_thread_debugger.cc
index 7e362aa..48d8489 100644
--- a/third_party/blink/renderer/core/inspector/worker_thread_debugger.cc
+++ b/third_party/blink/renderer/core/inspector/worker_thread_debugger.cc
@@ -241,9 +241,9 @@
   if (!worker_threads_.Contains(context_group_id))
     return;
   WorkerThread* worker_thread = worker_threads_.at(context_group_id);
-  std::unique_ptr<SourceLocation> location =
-      SourceLocation::Create(ToCoreString(url), line_number, column_number,
-                             stack_trace ? stack_trace->clone() : nullptr, 0);
+  std::unique_ptr<SourceLocation> location = std::make_unique<SourceLocation>(
+      ToCoreString(url), line_number, column_number,
+      stack_trace ? stack_trace->clone() : nullptr, 0);
   worker_thread->GetWorkerReportingProxy().ReportConsoleMessage(
       kConsoleAPIMessageSource, V8MessageLevelToMessageLevel(level),
       ToCoreString(message), location.get());
diff --git a/third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.cc b/third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.cc
index 67692b7..94586c75 100644
--- a/third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.cc
+++ b/third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.cc
@@ -32,11 +32,23 @@
   intersection_observations_.erase(&observer);
 }
 
-void ElementIntersectionObserverData::ComputeObservations(unsigned flags) {
+bool ElementIntersectionObserverData::ComputeObservations(unsigned flags) {
+  bool needs_occlusion_tracking = false;
   HeapVector<Member<IntersectionObservation>> observations_to_process;
   CopyValuesToVector(intersection_observations_, observations_to_process);
-  for (auto& observation : observations_to_process)
+  for (auto& observation : observations_to_process) {
+    needs_occlusion_tracking |= observation->Observer()->trackVisibility();
     observation->Compute(flags);
+  }
+  return needs_occlusion_tracking;
+}
+
+bool ElementIntersectionObserverData::NeedsOcclusionTracking() const {
+  for (auto& entry : intersection_observations_) {
+    if (entry.key->trackVisibility())
+      return true;
+  }
+  return false;
 }
 
 void ElementIntersectionObserverData::Trace(blink::Visitor* visitor) {
diff --git a/third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.h b/third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.h
index 342af25..5b35944 100644
--- a/third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.h
+++ b/third_party/blink/renderer/core/intersection_observer/element_intersection_observer_data.h
@@ -25,7 +25,8 @@
   void AddObservation(IntersectionObservation&);
   void RemoveObservation(IntersectionObserver&);
   bool HasObservations() const { return !intersection_observations_.IsEmpty(); }
-  void ComputeObservations(unsigned flags);
+  bool ComputeObservations(unsigned flags);
+  bool NeedsOcclusionTracking() const;
 
   void Trace(blink::Visitor*);
   const char* NameInHeapSnapshot() const override {
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc b/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc
index 1bc8013..86d4bc7f 100644
--- a/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc
+++ b/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc
@@ -65,10 +65,8 @@
 
 bool ComputeIsVisible(LayoutObject* target, const LayoutRect& rect) {
   DCHECK(RuntimeEnabledFeatures::IntersectionObserverV2Enabled());
-  if (target->GetDocument()
-          .GetFrame()
-          ->LocalFrameRoot()
-          .MayBeOccludedOrObscuredByRemoteAncestor()) {
+  if (target->GetDocument().GetFrame()->LocalFrameRoot().GetOcclusionState() !=
+      kGuaranteedNotOccluded) {
     return false;
   }
   if (target->HasDistortingVisualEffects())
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc b/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc
index f83bf49c..029a4af2 100644
--- a/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc
+++ b/third_party/blink/renderer/core/intersection_observer/intersection_observation.cc
@@ -50,6 +50,15 @@
     // Compute() method will be called again after the delay period has passed.
     return;
   }
+  if (Observer()->trackVisibility()) {
+    FrameOcclusionState occlusion_state =
+        target_->GetDocument().GetFrame()->GetOcclusionState();
+    // If we're tracking visibility, and we don't have occlusion information
+    // from our parent frame, then postpone computing intersections until a
+    // later lifecycle when the occlusion information is known.
+    if (occlusion_state == kUnknownOcclusionState)
+      return;
+  }
   last_run_time_ = timestamp;
   needs_update_ = 0;
   Vector<Length> root_margin(4);
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc b/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc
index 821f9fb..28df78b 100644
--- a/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc
+++ b/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc
@@ -300,7 +300,7 @@
   if (target->isConnected()) {
     target->GetDocument()
         .EnsureIntersectionObserverController()
-        .AddTrackedTarget(*target);
+        .AddTrackedTarget(*target, track_visibility_);
     if (LocalFrameView* frame_view = target_frame->View()) {
       // The IntersectionObsever spec requires that at least one observation
       // be recorded after observe() is called, even if the frame is throttled.
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.cc b/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.cc
index df11be7..21d0856 100644
--- a/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.cc
+++ b/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.cc
@@ -7,6 +7,7 @@
 #include "third_party/blink/public/platform/task_type.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/element.h"
+#include "third_party/blink/renderer/core/frame/frame_owner.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/intersection_observer/intersection_observation.h"
@@ -71,24 +72,43 @@
   intersection_observers_being_invoked_.clear();
 }
 
-void IntersectionObserverController::ComputeTrackedIntersectionObservations(
+bool IntersectionObserverController::ComputeTrackedIntersectionObservations(
     unsigned flags) {
+  bool needs_occlusion_tracking = false;
   if (Document* document = To<Document>(GetExecutionContext())) {
     TRACE_EVENT0("blink",
                  "IntersectionObserverController::"
                  "computeTrackedIntersectionObservations");
     HeapVector<Member<Element>> elements_to_process;
     CopyToVector(tracked_observation_targets_, elements_to_process);
-    for (auto& element : elements_to_process)
-      element->ComputeIntersectionObservations(flags);
+    for (auto& element : elements_to_process) {
+      needs_occlusion_tracking |=
+          element->ComputeIntersectionObservations(flags);
+    }
+  }
+  return needs_occlusion_tracking;
+}
+
+void IntersectionObserverController::AddTrackedTarget(Element& target,
+                                                      bool track_occlusion) {
+  tracked_observation_targets_.insert(&target);
+  if (!track_occlusion)
+    return;
+  if (LocalFrameView* frame_view = target.GetDocument().View()) {
+    if (FrameOwner* frame_owner = frame_view->GetFrame().Owner()) {
+      // Set this bit as early as possible, rather than waiting for a lifecycle
+      // update to recompute it.
+      frame_owner->SetNeedsOcclusionTracking(true);
+    }
   }
 }
 
-void IntersectionObserverController::AddTrackedTarget(Element& target) {
-  tracked_observation_targets_.insert(&target);
-}
-
 void IntersectionObserverController::RemoveTrackedTarget(Element& target) {
+  // Note that we don't try to opportunistically turn off the 'needs occlusion
+  // tracking' bit here, like the way we turn it on in AddTrackedTarget. The
+  // bit will get recomputed on the next lifecycle update; there's no
+  // compelling reason to do it here, so we avoid the iteration through targets
+  // and observations here.
   tracked_observation_targets_.erase(&target);
 }
 
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.h b/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.h
index 9abfda8..2c7d51c 100644
--- a/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.h
+++ b/third_party/blink/renderer/core/intersection_observer/intersection_observer_controller.h
@@ -40,9 +40,13 @@
 
   // The flags argument is composed of values from
   // IntersectionObservation::ComputeFlags. They are dirty bits that control
-  // whether an IntersectionObserver needs to do any work.
-  void ComputeTrackedIntersectionObservations(unsigned flags);
-  void AddTrackedTarget(Element&);
+  // whether an IntersectionObserver needs to do any work. The return value
+  // communicates whether observer->trackVisibility() is true for any tracked
+  // observer.
+  bool ComputeTrackedIntersectionObservations(unsigned flags);
+  // The second argument indicates whether the Element is being tracked by any
+  // observers for which observer->trackVisibility() is true.
+  void AddTrackedTarget(Element&, bool);
   void RemoveTrackedTarget(Element&);
 
   void Trace(blink::Visitor*) override;
diff --git a/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.cc b/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.cc
index 4ec1641..5920b3d 100644
--- a/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.cc
+++ b/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.cc
@@ -33,8 +33,7 @@
       frame, std::move(creation_params), reporting_proxy,
       pending_layout_registry);
   // TODO(bashi): Handle a case where the script controller fails to initialize.
-  global_scope->ScriptController()->InitializeContext(global_scope->Name(),
-                                                      NullURL());
+  global_scope->ScriptController()->Initialize(NullURL());
   MainThreadDebugger::Instance()->ContextCreated(
       global_scope->ScriptController()->GetScriptState(),
       global_scope->GetFrame(), global_scope->DocumentSecurityOrigin());
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc
index 7ed7118c..fb76cb1 100644
--- a/third_party/blink/renderer/core/loader/document_loader.cc
+++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -435,8 +435,8 @@
   }
   WebHistoryCommitType commit_type = LoadTypeToCommitType(type);
   frame_->GetFrameScheduler()->DidCommitProvisionalLoad(
-      commit_type == kWebHistoryInertCommit, type == WebFrameLoadType::kReload,
-      frame_->IsLocalRoot());
+      commit_type == kWebHistoryInertCommit,
+      FrameScheduler::NavigationType::kSameDocument);
 
   GetLocalFrameClient().DidFinishSameDocumentNavigation(
       history_item_.Get(), commit_type, initiating_document);
@@ -1313,7 +1313,9 @@
   WebHistoryCommitType commit_type = LoadTypeToCommitType(load_type_);
   frame_->GetFrameScheduler()->DidCommitProvisionalLoad(
       commit_type == kWebHistoryInertCommit,
-      load_type_ == WebFrameLoadType::kReload, frame_->IsLocalRoot());
+      load_type_ == WebFrameLoadType::kReload
+          ? FrameScheduler::NavigationType::kReload
+          : FrameScheduler::NavigationType::kOther);
   // When a new navigation commits in the frame, subresource loading should be
   // resumed.
   frame_->ResumeSubresourceLoading();
diff --git a/third_party/blink/renderer/core/loader/document_loader_test.cc b/third_party/blink/renderer/core/loader/document_loader_test.cc
index ee83a089..194388a 100644
--- a/third_party/blink/renderer/core/loader/document_loader_test.cc
+++ b/third_party/blink/renderer/core/loader/document_loader_test.cc
@@ -98,7 +98,7 @@
     // WebURLLoaderTestDelegate overrides:
     bool FillNavigationParamsResponse(WebNavigationParams* params) override {
       params->response = WebURLResponse(params->url);
-      params->response.SetMIMEType("text/html");
+      params->response.SetMimeType("text/html");
       params->response.SetHttpStatusCode(200);
 
       std::string data("<html><body>foo</body></html>");
diff --git a/third_party/blink/renderer/core/loader/empty_clients.h b/third_party/blink/renderer/core/loader/empty_clients.h
index 1aa3ce1..24ae3b95 100644
--- a/third_party/blink/renderer/core/loader/empty_clients.h
+++ b/third_party/blink/renderer/core/loader/empty_clients.h
@@ -452,8 +452,9 @@
                           bool has_user_gesture) const override {}
   void FrameRectsChanged(const IntRect& local_frame_rect,
                          const IntRect& transformed_frame_rect) override {}
-  void UpdateRemoteViewportIntersection(const IntRect& viewport_intersection,
-                                        bool occluded_or_obscured) override {}
+  void UpdateRemoteViewportIntersection(
+      const IntRect& viewport_intersection,
+      FrameOcclusionState occlusion_state) override {}
   void AdvanceFocus(WebFocusType, LocalFrame* source) override {}
   void VisibilityChanged(blink::mojom::FrameVisibility) override {}
   void SetIsInert(bool) override {}
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_script_loader_test.cc b/third_party/blink/renderer/core/loader/modulescript/module_script_loader_test.cc
index 2f2b8cb1..ba3b722 100644
--- a/third_party/blink/renderer/core/loader/modulescript/module_script_loader_test.cc
+++ b/third_party/blink/renderer/core/loader/modulescript/module_script_loader_test.cc
@@ -194,8 +194,7 @@
       MakeGarbageCollected<WorkletModuleResponsesMap>());
   global_scope_ = MakeGarbageCollected<WorkletGlobalScope>(
       std::move(creation_params), *reporting_proxy_, &GetFrame());
-  ASSERT_TRUE(global_scope_->ScriptController()->InitializeContext(
-      "Dummy Context", NullURL()));
+  ASSERT_TRUE(global_scope_->ScriptController()->Initialize(NullURL()));
   modulator_ = MakeGarbageCollected<ModuleScriptLoaderTestModulator>(
       global_scope_->ScriptController()->GetScriptState());
 }
diff --git a/third_party/blink/renderer/core/loader/preload_helper.cc b/third_party/blink/renderer/core/loader/preload_helper.cc
index ae7fe2e..b42ed8d 100644
--- a/third_party/blink/renderer/core/loader/preload_helper.cc
+++ b/third_party/blink/renderer/core/loader/preload_helper.cc
@@ -208,8 +208,7 @@
 
   MediaValues* media_values = nullptr;
   KURL url;
-  if (resource_type == ResourceType::kImage && !params.image_srcset.IsEmpty() &&
-      RuntimeEnabledFeatures::PreloadImageSrcSetEnabled()) {
+  if (resource_type == ResourceType::kImage && !params.image_srcset.IsEmpty()) {
     UseCounter::Count(document, WebFeature::kLinkRelPreloadImageSrcset);
     media_values = CreateMediaValues(document, viewport_description);
     float source_size =
diff --git a/third_party/blink/renderer/core/loader/threadable_loader.cc b/third_party/blink/renderer/core/loader/threadable_loader.cc
index 0c7fa5d..9eeb33e7 100644
--- a/third_party/blink/renderer/core/loader/threadable_loader.cc
+++ b/third_party/blink/renderer/core/loader/threadable_loader.cc
@@ -949,13 +949,7 @@
 
   checker_.NotifyFinished(resource);
 
-  // Don't throw an exception for failed sync local file loads.
-  // TODO(japhet): This logic has been moved around but unchanged since 2007.
-  // Tested by fast/xmlhttprequest/xmlhttprequest-missing-file-exception.html
-  // Do we still need this?
-  bool is_sync_to_local_file = resource->Url().IsLocalFile() && !async_;
-
-  if (resource->ErrorOccurred() && !is_sync_to_local_file) {
+  if (resource->ErrorOccurred()) {
     DispatchDidFail(resource->GetResourceError());
     return;
   }
diff --git a/third_party/blink/renderer/core/page/page.cc b/third_party/blink/renderer/core/page/page.cc
index 6c65ef4..1c0b3f2 100644
--- a/third_party/blink/renderer/core/page/page.cc
+++ b/third_party/blink/renderer/core/page/page.cc
@@ -853,7 +853,7 @@
   if (LocalFrame* local_frame = DeprecatedLocalMainFrame()) {
     ConsoleMessage* message = ConsoleMessage::Create(
         kOtherMessageSource, mojom::ConsoleMessageLevel::kWarning, text,
-        SourceLocation::Create(String(), 0, 0, nullptr));
+        std::make_unique<SourceLocation>(String(), 0, 0, nullptr));
     local_frame->GetDocument()->AddConsoleMessage(message);
   }
 }
diff --git a/third_party/blink/renderer/core/script/script_loader.cc b/third_party/blink/renderer/core/script/script_loader.cc
index bbb713f..bbfbe50 100644
--- a/third_party/blink/renderer/core/script/script_loader.cc
+++ b/third_party/blink/renderer/core/script/script_loader.cc
@@ -198,6 +198,8 @@
     return ShouldFireErrorEvent::kShouldFire;
   }
 
+  UseCounter::Count(*context_document, WebFeature::kImportMap);
+
   KURL base_url = element_document.BaseURL();
   ImportMap* import_map = ImportMap::Create(
       *modulator, element.TextFromChildren(), base_url, element_document);
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc
index 83a7394..478b5af 100644
--- a/third_party/blink/renderer/core/testing/internals.cc
+++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -3479,6 +3479,17 @@
   IntersectionObserver::SetThrottleDelayEnabledForTesting(false);
 }
 
+bool Internals::isSiteIsolated(HTMLIFrameElement* iframe) const {
+  return iframe->ContentFrame() && iframe->ContentFrame()->IsRemoteFrame();
+}
+
+bool Internals::isTrackingOcclusionForIFrame(HTMLIFrameElement* iframe) const {
+  if (!iframe->ContentFrame() || !iframe->ContentFrame()->IsRemoteFrame())
+    return false;
+  RemoteFrame* remote_frame = To<RemoteFrame>(iframe->ContentFrame());
+  return remote_frame->View()->NeedsOcclusionTracking();
+}
+
 void Internals::addEmbedderCustomElementName(const AtomicString& name,
                                              ExceptionState& exception_state) {
   CustomElement::AddEmbedderCustomElementNameForTesting(name, exception_state);
diff --git a/third_party/blink/renderer/core/testing/internals.h b/third_party/blink/renderer/core/testing/internals.h
index 2978b87..b4205ee5 100644
--- a/third_party/blink/renderer/core/testing/internals.h
+++ b/third_party/blink/renderer/core/testing/internals.h
@@ -56,6 +56,7 @@
 class ExceptionState;
 class ExecutionContext;
 class GCObservation;
+class HTMLIFrameElement;
 class HTMLInputElement;
 class HTMLMediaElement;
 class HTMLSelectElement;
@@ -590,6 +591,8 @@
   unsigned LifecycleUpdateCount() const;
 
   void DisableIntersectionObserverThrottleDelay() const;
+  bool isSiteIsolated(HTMLIFrameElement* iframe) const;
+  bool isTrackingOcclusionForIFrame(HTMLIFrameElement* iframe) const;
 
   void addEmbedderCustomElementName(const AtomicString& name, ExceptionState&);
 
diff --git a/third_party/blink/renderer/core/testing/internals.idl b/third_party/blink/renderer/core/testing/internals.idl
index 6c2376e..12c9a76 100644
--- a/third_party/blink/renderer/core/testing/internals.idl
+++ b/third_party/blink/renderer/core/testing/internals.idl
@@ -410,6 +410,14 @@
     // to be generated.
     void DisableIntersectionObserverThrottleDelay();
 
+    // Reports whether an iframe's browsing context runs in a separate process
+    bool isSiteIsolated(HTMLIFrameElement iframe);
+
+    // Reports whether a parent document is propagating occlusion information
+    // down to a child frame, for the purpose of servicing IntersectionObserver
+    // instances that track visibility.
+    bool isTrackingOcclusionForIFrame(HTMLIFrameElement iframe);
+
     // Declare that the given |name| is in use by the embedder via the custom
     // element mechanism.
     [RaisesException] void addEmbedderCustomElementName(DOMString name);
diff --git a/third_party/blink/renderer/core/testing/sim/sim_network.cc b/third_party/blink/renderer/core/testing/sim/sim_network.cc
index 12119ee4..d09117f 100644
--- a/third_party/blink/renderer/core/testing/sim/sim_network.cc
+++ b/third_party/blink/renderer/core/testing/sim/sim_network.cc
@@ -94,7 +94,7 @@
 void SimNetwork::AddRequest(SimRequestBase& request) {
   requests_.insert(request.url_.GetString(), &request);
   WebURLResponse response(request.url_);
-  response.SetMIMEType(request.mime_type_);
+  response.SetMimeType(request.mime_type_);
 
   if (request.redirect_url_.IsEmpty()) {
     response.SetHttpStatusCode(200);
@@ -116,7 +116,7 @@
   auto it = requests_.find(params->url.GetString());
   SimRequestBase* request = it->value;
   params->response = WebURLResponse(params->url);
-  params->response.SetMIMEType(request->mime_type_);
+  params->response.SetMimeType(request->mime_type_);
   params->response.SetHttpStatusCode(200);
   auto body_loader = std::make_unique<StaticDataNavigationBodyLoader>();
   request->UsedForNavigation(body_loader.get());
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc
index f6b7662..66fef1c 100644
--- a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc
+++ b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc
@@ -31,6 +31,8 @@
 #include "third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h"
 
 #include <memory>
+#include "base/feature_list.h"
+#include "third_party/blink/public/common/features.h"
 #include "third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h"
 #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
 #include "third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h"
@@ -39,15 +41,18 @@
 #include "third_party/blink/renderer/core/inspector/worker_thread_debugger.h"
 #include "third_party/blink/renderer/core/messaging/post_message_options.h"
 #include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h"
+#include "third_party/blink/renderer/core/probe/core_probes.h"
 #include "third_party/blink/renderer/core/script/modulator.h"
 #include "third_party/blink/renderer/core/workers/dedicated_worker_object_proxy.h"
 #include "third_party/blink/renderer/core/workers/dedicated_worker_thread.h"
 #include "third_party/blink/renderer/core/workers/global_scope_creation_params.h"
+#include "third_party/blink/renderer/core/workers/worker_classic_script_loader.h"
 #include "third_party/blink/renderer/core/workers/worker_clients.h"
 #include "third_party/blink/renderer/core/workers/worker_module_tree_client.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/script_state.h"
 #include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h"
+#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
 
 namespace blink {
 
@@ -64,7 +69,40 @@
 }
 
 // https://html.spec.whatwg.org/C/#worker-processing-model
-void DedicatedWorkerGlobalScope::ImportModuleScript(
+void DedicatedWorkerGlobalScope::FetchAndRunClassicScript(
+    const KURL& script_url,
+    const FetchClientSettingsObjectSnapshot& outside_settings_object,
+    const v8_inspector::V8StackTraceId& stack_id) {
+  DCHECK(base::FeatureList::IsEnabled(
+      features::kOffMainThreadDedicatedWorkerScriptFetch));
+  DCHECK(!IsContextPaused());
+
+  // Step 12. "Fetch a classic worker script given url, outside settings,
+  // destination, and inside settings."
+  auto destination = mojom::RequestContextType::WORKER;
+
+  // Step 12.1. "Set request's reserved client to inside settings."
+  // The browesr process takes care of this.
+
+  // Step 12.2. "Fetch request, and asynchronously wait to run the remaining
+  // steps as part of fetch's process response for the response response."
+  WorkerClassicScriptLoader* classic_script_loader =
+      MakeGarbageCollected<WorkerClassicScriptLoader>();
+  classic_script_loader->LoadTopLevelScriptAsynchronously(
+      *this, CreateOutsideSettingsFetcher(outside_settings_object), script_url,
+      destination, network::mojom::FetchRequestMode::kSameOrigin,
+      network::mojom::FetchCredentialsMode::kSameOrigin,
+      GetSecurityContext().AddressSpace(),
+      WTF::Bind(&DedicatedWorkerGlobalScope::DidReceiveResponseForClassicScript,
+                WrapWeakPersistent(this),
+                WrapPersistent(classic_script_loader)),
+      WTF::Bind(&DedicatedWorkerGlobalScope::DidFetchClassicScript,
+                WrapWeakPersistent(this), WrapPersistent(classic_script_loader),
+                stack_id));
+}
+
+// https://html.spec.whatwg.org/C/#worker-processing-model
+void DedicatedWorkerGlobalScope::FetchAndRunModuleScript(
     const KURL& module_url_record,
     const FetchClientSettingsObjectSnapshot& outside_settings_object,
     network::mojom::FetchCredentialsMode credentials_mode) {
@@ -125,6 +163,63 @@
       std::move(transferable_message));
 }
 
+void DedicatedWorkerGlobalScope::DidReceiveResponseForClassicScript(
+    WorkerClassicScriptLoader* classic_script_loader) {
+  DCHECK(IsContextThread());
+  DCHECK(base::FeatureList::IsEnabled(
+      features::kOffMainThreadDedicatedWorkerScriptFetch));
+  probe::DidReceiveScriptResponse(this, classic_script_loader->Identifier());
+}
+
+// https://html.spec.whatwg.org/C/#worker-processing-model
+void DedicatedWorkerGlobalScope::DidFetchClassicScript(
+    WorkerClassicScriptLoader* classic_script_loader,
+    const v8_inspector::V8StackTraceId& stack_id) {
+  DCHECK(IsContextThread());
+  DCHECK(base::FeatureList::IsEnabled(
+      features::kOffMainThreadDedicatedWorkerScriptFetch));
+
+  // Step 12. "If the algorithm asynchronously completes with null, then:"
+  if (classic_script_loader->Failed()) {
+    // Step 12.1. "Queue a task to fire an event named error at worker."
+    // Step 12.2. "Run the environment discarding steps for inside settings."
+    // Step 12.3. "Return."
+    ReportingProxy().DidFailToFetchClassicScript();
+    return;
+  }
+  ReportingProxy().DidFetchScript();
+  probe::ScriptImported(this, classic_script_loader->Identifier(),
+                        classic_script_loader->SourceText());
+
+  // Step 12.3. "Set worker global scope's url to response's url."
+  InitializeURL(classic_script_loader->ResponseURL());
+
+  // Step 12.4. "Set worker global scope's HTTPS state to response's HTTPS
+  // state."
+  // This is done in the constructor of WorkerGlobalScope.
+
+  // Step 12.5. "Set worker global scope's referrer policy to the result of
+  // parsing the `Referrer-Policy` header of response."
+  auto referrer_policy = network::mojom::ReferrerPolicy::kDefault;
+  if (!classic_script_loader->GetReferrerPolicy().IsNull()) {
+    SecurityPolicy::ReferrerPolicyFromHeaderValue(
+        classic_script_loader->GetReferrerPolicy(),
+        kDoNotSupportReferrerPolicyLegacyKeywords, &referrer_policy);
+    SetReferrerPolicy(referrer_policy);
+  }
+
+  // Step 12.6. "Execute the Initialize a global object's CSP list algorithm
+  // on worker global scope and response. [CSP]"
+  // This is done in the constructor of WorkerGlobalScope.
+  DCHECK_EQ(GlobalScopeCSPApplyMode::kUseCreationParamsCSP, GetCSPApplyMode());
+
+  // Step 12.7. "Asynchronously complete the perform the fetch steps with
+  // response."
+  EvaluateClassicScript(
+      classic_script_loader->ResponseURL(), classic_script_loader->SourceText(),
+      classic_script_loader->ReleaseCachedMetadata(), stack_id);
+}
+
 DedicatedWorkerObjectProxy& DedicatedWorkerGlobalScope::WorkerObjectProxy()
     const {
   return static_cast<DedicatedWorkerThread*>(GetThread())->WorkerObjectProxy();
@@ -134,9 +229,4 @@
   WorkerGlobalScope::Trace(visitor);
 }
 
-mojom::RequestContextType
-DedicatedWorkerGlobalScope::GetDestinationForMainScript() {
-  return mojom::RequestContextType::WORKER;
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h
index 145a219..bc509ed2 100644
--- a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h
+++ b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h
@@ -44,6 +44,7 @@
 class DedicatedWorkerThread;
 class PostMessageOptions;
 class ScriptState;
+class WorkerClassicScriptLoader;
 struct GlobalScopeCreationParams;
 
 class CORE_EXPORT DedicatedWorkerGlobalScope final : public WorkerGlobalScope {
@@ -63,7 +64,11 @@
   const AtomicString& InterfaceName() const override;
 
   // Implements WorkerGlobalScope.
-  void ImportModuleScript(
+  void FetchAndRunClassicScript(
+      const KURL& script_url,
+      const FetchClientSettingsObjectSnapshot& outside_settings_object,
+      const v8_inspector::V8StackTraceId& stack_id) override;
+  void FetchAndRunModuleScript(
       const KURL& module_url_record,
       const FetchClientSettingsObjectSnapshot& outside_settings_object,
       network::mojom::FetchCredentialsMode) override;
@@ -85,9 +90,12 @@
   void Trace(blink::Visitor*) override;
 
  private:
-  DedicatedWorkerObjectProxy& WorkerObjectProxy() const;
+  void DidReceiveResponseForClassicScript(
+      WorkerClassicScriptLoader* classic_script_loader);
+  void DidFetchClassicScript(WorkerClassicScriptLoader* classic_script_loader,
+                             const v8_inspector::V8StackTraceId& stack_id);
 
-  mojom::RequestContextType GetDestinationForMainScript() override;
+  DedicatedWorkerObjectProxy& WorkerObjectProxy() const;
 };
 
 template <>
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc b/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc
index fcd442b..bf20ac2d 100644
--- a/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc
+++ b/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc
@@ -65,7 +65,7 @@
     // destination, and inside settings."
     switch (off_main_thread_fetch_option) {
       case OffMainThreadWorkerScriptFetchOption::kEnabled:
-        GetWorkerThread()->ImportClassicScript(
+        GetWorkerThread()->FetchAndRunClassicScript(
             script_url, outside_settings_object, stack_id);
         break;
       case OffMainThreadWorkerScriptFetchOption::kDisabled:
@@ -84,8 +84,8 @@
     bool result = Request::ParseCredentialsMode(options->credentials(),
                                                 &credentials_mode);
     DCHECK(result);
-    GetWorkerThread()->ImportModuleScript(script_url, outside_settings_object,
-                                          credentials_mode);
+    GetWorkerThread()->FetchAndRunModuleScript(
+        script_url, outside_settings_object, credentials_mode);
   } else {
     NOTREACHED();
   }
diff --git a/third_party/blink/renderer/core/workers/experimental/thread_pool_thread.cc b/third_party/blink/renderer/core/workers/experimental/thread_pool_thread.cc
index 52e9b76..1b7a00c5 100644
--- a/third_party/blink/renderer/core/workers/experimental/thread_pool_thread.cc
+++ b/third_party/blink/renderer/core/workers/experimental/thread_pool_thread.cc
@@ -36,7 +36,13 @@
   }
 
   // WorkerGlobalScope
-  void ImportModuleScript(
+  void FetchAndRunClassicScript(
+      const KURL& script_url,
+      const FetchClientSettingsObjectSnapshot& outside_settings_object,
+      const v8_inspector::V8StackTraceId& stack_id) override {
+    NOTREACHED();
+  }
+  void FetchAndRunModuleScript(
       const KURL& module_url_record,
       const FetchClientSettingsObjectSnapshot& outside_settings_object,
       network::mojom::FetchCredentialsMode) override {
@@ -45,11 +51,6 @@
   }
 
   void ExceptionThrown(ErrorEvent*) override {}
-
-  mojom::RequestContextType GetDestinationForMainScript() override {
-    // TODO(nhiroki): Return an appropriate destination.
-    return mojom::RequestContextType::WORKER;
-  }
 };
 
 }  // anonymous namespace
diff --git a/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc b/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc
index 1ed6ef7..a3b1201 100644
--- a/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc
+++ b/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc
@@ -31,12 +31,19 @@
 #include "third_party/blink/renderer/core/workers/shared_worker_global_scope.h"
 
 #include <memory>
+#include "base/feature_list.h"
+#include "third_party/blink/public/common/features.h"
 #include "third_party/blink/renderer/bindings/core/v8/source_location.h"
 #include "third_party/blink/renderer/core/events/message_event.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/inspector/console_message.h"
 #include "third_party/blink/renderer/core/inspector/worker_thread_debugger.h"
+#include "third_party/blink/renderer/core/probe/core_probes.h"
 #include "third_party/blink/renderer/core/workers/shared_worker_thread.h"
+#include "third_party/blink/renderer/core/workers/worker_classic_script_loader.h"
+#include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h"
+#include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h"
+#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
 #include "third_party/blink/renderer/platform/wtf/time.h"
 
 namespace blink {
@@ -54,7 +61,39 @@
 }
 
 // https://html.spec.whatwg.org/C/#worker-processing-model
-void SharedWorkerGlobalScope::ImportModuleScript(
+void SharedWorkerGlobalScope::FetchAndRunClassicScript(
+    const KURL& script_url,
+    const FetchClientSettingsObjectSnapshot& outside_settings_object,
+    const v8_inspector::V8StackTraceId& stack_id) {
+  DCHECK(features::IsOffMainThreadSharedWorkerScriptFetchEnabled());
+  DCHECK(!IsContextPaused());
+
+  // Step 12. "Fetch a classic worker script given url, outside settings,
+  // destination, and inside settings."
+  auto destination = mojom::RequestContextType::SHARED_WORKER;
+
+  // Step 12.1. "Set request's reserved client to inside settings."
+  // The browesr process takes care of this.
+
+  // Step 12.2. "Fetch request, and asynchronously wait to run the remaining
+  // steps as part of fetch's process response for the response response."
+  WorkerClassicScriptLoader* classic_script_loader =
+      MakeGarbageCollected<WorkerClassicScriptLoader>();
+  classic_script_loader->LoadTopLevelScriptAsynchronously(
+      *this, CreateOutsideSettingsFetcher(outside_settings_object), script_url,
+      destination, network::mojom::FetchRequestMode::kSameOrigin,
+      network::mojom::FetchCredentialsMode::kSameOrigin,
+      GetSecurityContext().AddressSpace(),
+      WTF::Bind(&SharedWorkerGlobalScope::DidReceiveResponseForClassicScript,
+                WrapWeakPersistent(this),
+                WrapPersistent(classic_script_loader)),
+      WTF::Bind(&SharedWorkerGlobalScope::DidFetchClassicScript,
+                WrapWeakPersistent(this), WrapPersistent(classic_script_loader),
+                stack_id));
+}
+
+// https://html.spec.whatwg.org/C/#worker-processing-model
+void SharedWorkerGlobalScope::FetchAndRunModuleScript(
     const KURL& module_url_record,
     const FetchClientSettingsObjectSnapshot& outside_settings_object,
     network::mojom::FetchCredentialsMode credentials_mode) {
@@ -85,6 +124,68 @@
   DispatchEvent(*event);
 }
 
+void SharedWorkerGlobalScope::DidReceiveResponseForClassicScript(
+    WorkerClassicScriptLoader* classic_script_loader) {
+  DCHECK(IsContextThread());
+  DCHECK(features::IsOffMainThreadSharedWorkerScriptFetchEnabled());
+  probe::DidReceiveScriptResponse(this, classic_script_loader->Identifier());
+}
+
+// https://html.spec.whatwg.org/C/#worker-processing-model
+void SharedWorkerGlobalScope::DidFetchClassicScript(
+    WorkerClassicScriptLoader* classic_script_loader,
+    const v8_inspector::V8StackTraceId& stack_id) {
+  DCHECK(IsContextThread());
+  DCHECK(features::IsOffMainThreadSharedWorkerScriptFetchEnabled());
+
+  // Step 12. "If the algorithm asynchronously completes with null, then:"
+  if (classic_script_loader->Failed()) {
+    // Step 12.1. "Queue a task to fire an event named error at worker."
+    // Step 12.2. "Run the environment discarding steps for inside settings."
+    // Step 12.3. "Return."
+    ReportingProxy().DidFailToFetchClassicScript();
+    return;
+  }
+  ReportingProxy().DidFetchScript();
+  probe::ScriptImported(this, classic_script_loader->Identifier(),
+                        classic_script_loader->SourceText());
+
+  // Step 12.3. "Set worker global scope's url to response's url."
+  InitializeURL(classic_script_loader->ResponseURL());
+
+  // Step 12.4. "Set worker global scope's HTTPS state to response's HTTPS
+  // state."
+  // This is done in the constructor of WorkerGlobalScope.
+
+  // Step 12.5. "Set worker global scope's referrer policy to the result of
+  // parsing the `Referrer-Policy` header of response."
+  auto referrer_policy = network::mojom::ReferrerPolicy::kDefault;
+  if (!classic_script_loader->GetReferrerPolicy().IsNull()) {
+    SecurityPolicy::ReferrerPolicyFromHeaderValue(
+        classic_script_loader->GetReferrerPolicy(),
+        kDoNotSupportReferrerPolicyLegacyKeywords, &referrer_policy);
+    SetReferrerPolicy(referrer_policy);
+  }
+
+  // Step 12.6. "Execute the Initialize a global object's CSP list algorithm
+  // on worker global scope and response. [CSP]"
+  DCHECK_EQ(GlobalScopeCSPApplyMode::kUseResponseCSP, GetCSPApplyMode());
+  if (classic_script_loader->GetContentSecurityPolicy()) {
+    InitContentSecurityPolicyFromVector(
+        classic_script_loader->GetContentSecurityPolicy()->Headers());
+  } else {
+    // Initialize CSP with an empty list.
+    InitContentSecurityPolicyFromVector(Vector<CSPHeaderAndType>());
+  }
+  BindContentSecurityPolicyToExecutionContext();
+
+  // Step 12.7. "Asynchronously complete the perform the fetch steps with
+  // response."
+  EvaluateClassicScript(
+      classic_script_loader->ResponseURL(), classic_script_loader->SourceText(),
+      classic_script_loader->ReleaseCachedMetadata(), stack_id);
+}
+
 void SharedWorkerGlobalScope::ExceptionThrown(ErrorEvent* event) {
   WorkerGlobalScope::ExceptionThrown(event);
   if (WorkerThreadDebugger* debugger =
@@ -96,9 +197,4 @@
   WorkerGlobalScope::Trace(visitor);
 }
 
-mojom::RequestContextType
-SharedWorkerGlobalScope::GetDestinationForMainScript() {
-  return mojom::RequestContextType::SHARED_WORKER;
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/workers/shared_worker_global_scope.h b/third_party/blink/renderer/core/workers/shared_worker_global_scope.h
index 9719cd9f..3aafb42 100644
--- a/third_party/blink/renderer/core/workers/shared_worker_global_scope.h
+++ b/third_party/blink/renderer/core/workers/shared_worker_global_scope.h
@@ -41,6 +41,7 @@
 namespace blink {
 
 class SharedWorkerThread;
+class WorkerClassicScriptLoader;
 
 class CORE_EXPORT SharedWorkerGlobalScope final : public WorkerGlobalScope {
   DEFINE_WRAPPERTYPEINFO();
@@ -57,7 +58,11 @@
   const AtomicString& InterfaceName() const override;
 
   // WorkerGlobalScope
-  void ImportModuleScript(
+  void FetchAndRunClassicScript(
+      const KURL& script_url,
+      const FetchClientSettingsObjectSnapshot& outside_settings_object,
+      const v8_inspector::V8StackTraceId& stack_id) override;
+  void FetchAndRunModuleScript(
       const KURL& module_url_record,
       const FetchClientSettingsObjectSnapshot& outside_settings_object,
       network::mojom::FetchCredentialsMode) override;
@@ -71,8 +76,12 @@
   void Trace(blink::Visitor*) override;
 
  private:
+  void DidReceiveResponseForClassicScript(
+      WorkerClassicScriptLoader* classic_script_loader);
+  void DidFetchClassicScript(WorkerClassicScriptLoader* classic_script_loader,
+                             const v8_inspector::V8StackTraceId& stack_id);
+
   void ExceptionThrown(ErrorEvent*) override;
-  mojom::RequestContextType GetDestinationForMainScript() override;
 };
 
 template <>
diff --git a/third_party/blink/renderer/core/workers/worker_global_scope.cc b/third_party/blink/renderer/core/workers/worker_global_scope.cc
index c84e9bd0..9bcb82a 100644
--- a/third_party/blink/renderer/core/workers/worker_global_scope.cc
+++ b/third_party/blink/renderer/core/workers/worker_global_scope.cc
@@ -27,9 +27,7 @@
 
 #include "third_party/blink/renderer/core/workers/worker_global_scope.h"
 
-#include "base/feature_list.h"
 #include "base/memory/scoped_refptr.h"
-#include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/web_url_request.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_source_code.h"
@@ -377,121 +375,6 @@
     debugger->ExternalAsyncTaskFinished(stack_id);
 }
 
-// https://html.spec.whatwg.org/C/#worker-processing-model
-void WorkerGlobalScope::ImportClassicScript(
-    const KURL& script_url,
-    const FetchClientSettingsObjectSnapshot& outside_settings_object,
-    const v8_inspector::V8StackTraceId& stack_id) {
-  DCHECK(base::FeatureList::IsEnabled(
-             features::kOffMainThreadDedicatedWorkerScriptFetch) ||
-         base::FeatureList::IsEnabled(
-             features::kOffMainThreadServiceWorkerScriptFetch) ||
-         features::IsOffMainThreadSharedWorkerScriptFetchEnabled());
-  DCHECK(!IsContextPaused());
-
-  // Step 12. "Fetch a classic worker script given url, outside settings,
-  // destination, and inside settings."
-  mojom::RequestContextType destination = GetDestinationForMainScript();
-  DCHECK(destination == mojom::RequestContextType::WORKER ||
-         destination == mojom::RequestContextType::SERVICE_WORKER ||
-         destination == mojom::RequestContextType::SHARED_WORKER)
-      << "A wrong destination (" << destination << ") is specified.";
-
-  // Step 12.1. "Set request's reserved client to inside settings."
-  // The browesr process takes care of this.
-
-  // Step 12.2. "Fetch request, and asynchronously wait to run the remaining
-  // steps as part of fetch's process response for the response response."
-  ExecutionContext* execution_context = GetExecutionContext();
-  WorkerClassicScriptLoader* classic_script_loader =
-      MakeGarbageCollected<WorkerClassicScriptLoader>();
-  classic_script_loader->LoadTopLevelScriptAsynchronously(
-      *execution_context, CreateOutsideSettingsFetcher(outside_settings_object),
-      script_url, destination, network::mojom::FetchRequestMode::kSameOrigin,
-      network::mojom::FetchCredentialsMode::kSameOrigin,
-      GetSecurityContext().AddressSpace(),
-      WTF::Bind(&WorkerGlobalScope::DidReceiveResponseForClassicScript,
-                WrapWeakPersistent(this),
-                WrapPersistent(classic_script_loader)),
-      WTF::Bind(&WorkerGlobalScope::DidImportClassicScript,
-                WrapWeakPersistent(this), WrapPersistent(classic_script_loader),
-                stack_id));
-}
-
-void WorkerGlobalScope::DidReceiveResponseForClassicScript(
-    WorkerClassicScriptLoader* classic_script_loader) {
-  DCHECK(IsContextThread());
-  DCHECK(base::FeatureList::IsEnabled(
-             features::kOffMainThreadDedicatedWorkerScriptFetch) ||
-         base::FeatureList::IsEnabled(
-             features::kOffMainThreadServiceWorkerScriptFetch) ||
-         features::IsOffMainThreadSharedWorkerScriptFetchEnabled());
-  probe::DidReceiveScriptResponse(this, classic_script_loader->Identifier());
-}
-
-// https://html.spec.whatwg.org/C/#worker-processing-model
-void WorkerGlobalScope::DidImportClassicScript(
-    WorkerClassicScriptLoader* classic_script_loader,
-    const v8_inspector::V8StackTraceId& stack_id) {
-  DCHECK(IsContextThread());
-  DCHECK(base::FeatureList::IsEnabled(
-             features::kOffMainThreadDedicatedWorkerScriptFetch) ||
-         base::FeatureList::IsEnabled(
-             features::kOffMainThreadServiceWorkerScriptFetch) ||
-         features::IsOffMainThreadSharedWorkerScriptFetchEnabled());
-
-  // Step 12. "If the algorithm asynchronously completes with null, then:"
-  if (classic_script_loader->Failed()) {
-    // Step 12.1. "Queue a task to fire an event named error at worker."
-    // Step 12.2. "Run the environment discarding steps for inside settings."
-    // Step 12.3. "Return."
-    ReportingProxy().DidFailToFetchClassicScript();
-    return;
-  }
-  ReportingProxy().DidFetchScript();
-  probe::ScriptImported(this, classic_script_loader->Identifier(),
-                        classic_script_loader->SourceText());
-
-  // Step 12.3. "Set worker global scope's url to response's url."
-  InitializeURL(classic_script_loader->ResponseURL());
-
-  // Step 12.4. "Set worker global scope's HTTPS state to response's HTTPS
-  // state."
-  // This is done in the constructor of WorkerGlobalScope.
-
-  // Step 12.5. "Set worker global scope's referrer policy to the result of
-  // parsing the `Referrer-Policy` header of response."
-  network::mojom::ReferrerPolicy referrer_policy =
-      network::mojom::ReferrerPolicy::kDefault;
-  if (!classic_script_loader->GetReferrerPolicy().IsNull()) {
-    SecurityPolicy::ReferrerPolicyFromHeaderValue(
-        classic_script_loader->GetReferrerPolicy(),
-        kDoNotSupportReferrerPolicyLegacyKeywords, &referrer_policy);
-    SetReferrerPolicy(referrer_policy);
-  }
-
-  // Step 12.6. "Execute the Initialize a global object's CSP list algorithm
-  // on worker global scope and response. [CSP]"
-  // When |csp_apply_mode_| is kUseCreationParams, this is done in the
-  // constructor.
-  if (csp_apply_mode_ == GlobalScopeCSPApplyMode::kUseResponseCSP) {
-    if (classic_script_loader->GetContentSecurityPolicy()) {
-      InitContentSecurityPolicyFromVector(
-          classic_script_loader->GetContentSecurityPolicy()->Headers());
-    } else {
-      // Initialize CSP with an empty list.
-      InitContentSecurityPolicyFromVector(Vector<CSPHeaderAndType>());
-    }
-    BindContentSecurityPolicyToExecutionContext();
-  }
-
-  // Step 12.7. "Asynchronously complete the perform the fetch steps with
-  // response."
-  EvaluateClassicScript(
-      classic_script_loader->ResponseURL(), classic_script_loader->SourceText(),
-      classic_script_loader->ReleaseCachedMetadata(), stack_id);
-}
-
 void WorkerGlobalScope::ReceiveMessage(BlinkTransferableMessage message) {
   DCHECK(!IsContextPaused());
   MessagePortArray* ports =
diff --git a/third_party/blink/renderer/core/workers/worker_global_scope.h b/third_party/blink/renderer/core/workers/worker_global_scope.h
index 86885bf..a3ed6e03 100644
--- a/third_party/blink/renderer/core/workers/worker_global_scope.h
+++ b/third_party/blink/renderer/core/workers/worker_global_scope.h
@@ -60,7 +60,6 @@
 class FontFaceSet;
 class OffscreenFontSelector;
 class V8VoidFunction;
-class WorkerClassicScriptLoader;
 class StringOrTrustedScriptURL;
 class TrustedTypePolicyFactory;
 class WorkerLocation;
@@ -149,12 +148,15 @@
                              String source_code,
                              std::unique_ptr<Vector<uint8_t>> cached_meta_data,
                              const v8_inspector::V8StackTraceId& stack_id);
-  void ImportClassicScript(
+
+  // Fetches and evaluates the top-level classic script.
+  virtual void FetchAndRunClassicScript(
       const KURL& script_url,
       const FetchClientSettingsObjectSnapshot& outside_settings_object,
-      const v8_inspector::V8StackTraceId& stack_id);
-  // Imports the top-level module script for |module_url_record|.
-  virtual void ImportModuleScript(
+      const v8_inspector::V8StackTraceId& stack_id) = 0;
+
+  // Fetches and evaluates the top-level module script.
+  virtual void FetchAndRunModuleScript(
       const KURL& module_url_record,
       const FetchClientSettingsObjectSnapshot& outside_settings_object,
       network::mojom::FetchCredentialsMode) = 0;
@@ -205,11 +207,6 @@
  private:
   void SetWorkerSettings(std::unique_ptr<WorkerSettings>);
 
-  void DidReceiveResponseForClassicScript(
-      WorkerClassicScriptLoader* classic_script_loader);
-  void DidImportClassicScript(WorkerClassicScriptLoader* classic_script_loader,
-                              const v8_inspector::V8StackTraceId& stack_id);
-
   // Used for importScripts().
   void ImportScriptsInternal(const Vector<String>& urls, ExceptionState&);
   bool FetchClassicImportedScript(
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 4ee3fc0..bf931f0 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
@@ -147,8 +147,6 @@
   void TasksWerePaused() override;
   void TasksWereUnpaused() override;
 
-  virtual mojom::RequestContextType GetDestinationForMainScript() = 0;
-
  private:
   void InitializeWebFetchContextIfNeeded();
   ResourceFetcher* CreateFetcherInternal(const FetchClientSettingsObject&,
diff --git a/third_party/blink/renderer/core/workers/worker_thread.cc b/third_party/blink/renderer/core/workers/worker_thread.cc
index e55b9984..96dacc97 100644
--- a/third_party/blink/renderer/core/workers/worker_thread.cc
+++ b/third_party/blink/renderer/core/workers/worker_thread.cc
@@ -165,27 +165,27 @@
                       WTF::Passed(std::move(cached_meta_data)), stack_id));
 }
 
-void WorkerThread::ImportClassicScript(
+void WorkerThread::FetchAndRunClassicScript(
     const KURL& script_url,
     const FetchClientSettingsObjectSnapshot& outside_settings_object,
     const v8_inspector::V8StackTraceId& stack_id) {
   DCHECK_CALLED_ON_VALID_THREAD(parent_thread_checker_);
   PostCrossThreadTask(
       *GetTaskRunner(TaskType::kDOMManipulation), FROM_HERE,
-      CrossThreadBind(&WorkerThread::ImportClassicScriptOnWorkerThread,
+      CrossThreadBind(&WorkerThread::FetchAndRunClassicScriptOnWorkerThread,
                       CrossThreadUnretained(this), script_url,
                       WTF::Passed(outside_settings_object.CopyData()),
                       stack_id));
 }
 
-void WorkerThread::ImportModuleScript(
+void WorkerThread::FetchAndRunModuleScript(
     const KURL& script_url,
     const FetchClientSettingsObjectSnapshot& outside_settings_object,
     network::mojom::FetchCredentialsMode credentials_mode) {
   DCHECK_CALLED_ON_VALID_THREAD(parent_thread_checker_);
   PostCrossThreadTask(
       *GetTaskRunner(TaskType::kDOMManipulation), FROM_HERE,
-      CrossThreadBind(&WorkerThread::ImportModuleScriptOnWorkerThread,
+      CrossThreadBind(&WorkerThread::FetchAndRunModuleScriptOnWorkerThread,
                       CrossThreadUnretained(this), script_url,
                       WTF::Passed(outside_settings_object.CopyData()),
                       credentials_mode));
@@ -468,8 +468,7 @@
             WorkerThreadDebugger::From(GetIsolate()))
       debugger->WorkerThreadCreated(this);
 
-    if (GlobalScope()->ScriptController()->InitializeContext(
-            String(), url_for_debugger)) {
+    if (GlobalScope()->ScriptController()->Initialize(url_for_debugger)) {
       worker_reporting_proxy_.DidInitializeWorkerContext();
       v8::HandleScope handle_scope(GetIsolate());
       Platform::Current()->WorkerContextCreated(
@@ -519,20 +518,20 @@
                                       std::move(cached_meta_data), stack_id);
 }
 
-void WorkerThread::ImportClassicScriptOnWorkerThread(
+void WorkerThread::FetchAndRunClassicScriptOnWorkerThread(
     const KURL& script_url,
     std::unique_ptr<CrossThreadFetchClientSettingsObjectData>
         outside_settings_object,
     const v8_inspector::V8StackTraceId& stack_id) {
   To<WorkerGlobalScope>(GlobalScope())
-      ->ImportClassicScript(
+      ->FetchAndRunClassicScript(
           script_url,
           *MakeGarbageCollected<FetchClientSettingsObjectSnapshot>(
               std::move(outside_settings_object)),
           stack_id);
 }
 
-void WorkerThread::ImportModuleScriptOnWorkerThread(
+void WorkerThread::FetchAndRunModuleScriptOnWorkerThread(
     const KURL& script_url,
     std::unique_ptr<CrossThreadFetchClientSettingsObjectData>
         outside_settings_object,
@@ -541,7 +540,7 @@
   // TODO(nhiroki): Consider excluding this code path from WorkerThread like
   // Worklets.
   To<WorkerGlobalScope>(GlobalScope())
-      ->ImportModuleScript(
+      ->FetchAndRunModuleScript(
           script_url,
           *MakeGarbageCollected<FetchClientSettingsObjectSnapshot>(
               std::move(outside_settings_object)),
diff --git a/third_party/blink/renderer/core/workers/worker_thread.h b/third_party/blink/renderer/core/workers/worker_thread.h
index 5f41eea..c82c19d 100644
--- a/third_party/blink/renderer/core/workers/worker_thread.h
+++ b/third_party/blink/renderer/core/workers/worker_thread.h
@@ -113,16 +113,16 @@
                              std::unique_ptr<Vector<uint8_t>> cached_meta_data,
                              const v8_inspector::V8StackTraceId& stack_id);
 
-  // Posts a task to import a top-level classic script on the worker thread.
-  // Called on the main thread after Start().
-  void ImportClassicScript(
+  // Posts a task to fetch and run a top-level classic script on the worker
+  // thread. Called on the main thread after Start().
+  void FetchAndRunClassicScript(
       const KURL& script_url,
       const FetchClientSettingsObjectSnapshot& outside_settings_object,
       const v8_inspector::V8StackTraceId& stack_id);
 
-  // Posts a task to import a top-level module script on the worker thread.
-  // Called on the main thread after Start().
-  void ImportModuleScript(
+  // Posts a task to fetch and run a top-level module script on the worker
+  // thread. Called on the main thread after Start().
+  void FetchAndRunModuleScript(
       const KURL& script_url,
       const FetchClientSettingsObjectSnapshot& outside_settings_object,
       network::mojom::FetchCredentialsMode);
@@ -296,12 +296,12 @@
       String source_code,
       std::unique_ptr<Vector<uint8_t>> cached_meta_data,
       const v8_inspector::V8StackTraceId& stack_id);
-  void ImportClassicScriptOnWorkerThread(
+  void FetchAndRunClassicScriptOnWorkerThread(
       const KURL& script_url,
       std::unique_ptr<CrossThreadFetchClientSettingsObjectData>
           outside_settings_object,
       const v8_inspector::V8StackTraceId& stack_id);
-  void ImportModuleScriptOnWorkerThread(
+  void FetchAndRunModuleScriptOnWorkerThread(
       const KURL& script_url,
       std::unique_ptr<CrossThreadFetchClientSettingsObjectData>
           outside_settings_object,
diff --git a/third_party/blink/renderer/core/workers/worker_thread_test_helper.h b/third_party/blink/renderer/core/workers/worker_thread_test_helper.h
index 4e55738f..04a6cc29 100644
--- a/third_party/blink/renderer/core/workers/worker_thread_test_helper.h
+++ b/third_party/blink/renderer/core/workers/worker_thread_test_helper.h
@@ -57,7 +57,13 @@
   }
 
   // WorkerGlobalScope
-  void ImportModuleScript(
+  void FetchAndRunClassicScript(
+      const KURL& script_url,
+      const FetchClientSettingsObjectSnapshot& outside_settings_object,
+      const v8_inspector::V8StackTraceId& stack_id) override {
+    NOTREACHED();
+  }
+  void FetchAndRunModuleScript(
       const KURL& module_url_record,
       const FetchClientSettingsObjectSnapshot& outside_settings_object,
       network::mojom::FetchCredentialsMode) override {
@@ -65,10 +71,6 @@
   }
 
   void ExceptionThrown(ErrorEvent*) override {}
-
-  mojom::RequestContextType GetDestinationForMainScript() override {
-    return mojom::RequestContextType::WORKER;
-  }
 };
 
 class WorkerThreadForTest : public WorkerThread {
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 d201631b..437ce0b7 100644
--- a/third_party/blink/renderer/core/workers/worklet_global_scope.cc
+++ b/third_party/blink/renderer/core/workers/worklet_global_scope.cc
@@ -214,8 +214,12 @@
       MakeGarbageCollected<WorkletModuleTreeClient>(
           modulator, std::move(outside_settings_task_runner), pending_tasks);
 
-  FetchModuleScript(module_url_record, outside_settings_object,
-                    GetDestinationForMainScript(), credentials_mode,
+  // TODO(nhiroki): Pass an appropriate destination defined in each worklet
+  // spec (e.g., "paint worklet", "audio worklet") (https://crbug.com/843980,
+  // https://crbug.com/843982)
+  auto destination = mojom::RequestContextType::SCRIPT;
+  FetchModuleScript(module_url_record, outside_settings_object, destination,
+                    credentials_mode,
                     ModuleScriptCustomFetchType::kWorkletAddModule, client);
 }
 
@@ -243,13 +247,6 @@
   GetContentSecurityPolicy()->SetupSelf(*document_security_origin_);
 }
 
-mojom::RequestContextType WorkletGlobalScope::GetDestinationForMainScript() {
-  // TODO(nhiroki): Return an appropriate destination defined in each worklet
-  // spec (e.g., "paint worklet", "audio worklet") (https://crbug.com/843980,
-  // https://crbug.com/843982)
-  return mojom::RequestContextType::SCRIPT;
-}
-
 void WorkletGlobalScope::Trace(blink::Visitor* visitor) {
   visitor->Trace(frame_);
   WorkerOrWorkletGlobalScope::Trace(visitor);
diff --git a/third_party/blink/renderer/core/workers/worklet_global_scope.h b/third_party/blink/renderer/core/workers/worklet_global_scope.h
index 02a4aaf9..b152e47 100644
--- a/third_party/blink/renderer/core/workers/worklet_global_scope.h
+++ b/third_party/blink/renderer/core/workers/worklet_global_scope.h
@@ -157,8 +157,6 @@
 
   void BindContentSecurityPolicyToExecutionContext() override;
 
-  mojom::RequestContextType GetDestinationForMainScript() override;
-
   // The |url_| and |user_agent_| are inherited from the parent Document.
   const KURL url_;
   const String user_agent_;
diff --git a/third_party/blink/renderer/core/xml/xslt_processor_libxslt.cc b/third_party/blink/renderer/core/xml/xslt_processor_libxslt.cc
index 67caaaf2..0a9ab42 100644
--- a/third_party/blink/renderer/core/xml/xslt_processor_libxslt.cc
+++ b/third_party/blink/renderer/core/xml/xslt_processor_libxslt.cc
@@ -82,7 +82,7 @@
 
   console->AddMessage(ConsoleMessage::Create(
       kXMLMessageSource, level, error->message,
-      SourceLocation::Create(error->file, error->line, 0, nullptr)));
+      std::make_unique<SourceLocation>(error->file, error->line, 0, nullptr)));
 }
 
 // FIXME: There seems to be no way to control the ctxt pointer for loading here,
diff --git a/third_party/blink/renderer/devtools/front_end/network/NetworkLogView.js b/third_party/blink/renderer/devtools/front_end/network/NetworkLogView.js
index ad4cb56..b1475ae 100644
--- a/third_party/blink/renderer/devtools/front_end/network/NetworkLogView.js
+++ b/third_party/blink/renderer/devtools/front_end/network/NetworkLogView.js
@@ -138,7 +138,7 @@
     filterBar.filterButton().addEventListener(
         UI.ToolbarButton.Events.Click, this._dataGrid.scheduleUpdate.bind(this._dataGrid, true /* isFromUser */));
 
-    this._summaryBarElement = this.element.createChild('div', 'network-summary-bar');
+    this._summaryToolbar = new UI.Toolbar('network-summary-bar', this.element);
 
     new UI.DropTarget(
         this.element, [UI.DropTarget.Type.File], Common.UIString('Drop HAR files here'), this._handleDrop.bind(this));
@@ -758,53 +758,52 @@
       return;
     }
 
-    const summaryBar = this._summaryBarElement;
-    summaryBar.removeChildren();
-    const separator = '\u2002\u2758\u2002';
-    let text = '';
+    this._summaryToolbar.removeToolbarItems();
     /**
      * @param {string} chunk
+     * @param {string=} title
      * @return {!Element}
      */
-    function appendChunk(chunk) {
-      const span = summaryBar.createChild('span');
-      span.textContent = chunk;
-      text += chunk;
-      return span;
-    }
+    const appendChunk = (chunk, title) => {
+      const toolbarText = new UI.ToolbarText(chunk);
+      toolbarText.setTitle(title ? title : chunk);
+      this._summaryToolbar.appendToolbarItem(toolbarText);
+      return toolbarText.element;
+    };
 
     if (selectedNodeNumber !== nodeCount) {
-      appendChunk(Common.UIString('%d / %d requests', selectedNodeNumber, nodeCount));
-      appendChunk(separator);
-      appendChunk(Common.UIString(
-          '%s / %s transferred', Number.bytesToString(selectedTransferSize), Number.bytesToString(transferSize)));
-      appendChunk(separator);
-      appendChunk(Common.UIString(
-          '%s / %s resources', Number.bytesToString(selectedResourceSize), Number.bytesToString(resourceSize)));
+      appendChunk(ls`${selectedNodeNumber} / ${nodeCount} requests`);
+      this._summaryToolbar.appendSeparator();
+      appendChunk(
+          ls`${Number.bytesToString(selectedTransferSize)} / ${Number.bytesToString(transferSize)} transferred`,
+          ls`${selectedTransferSize} B / ${transferSize} B transferred`);
+      this._summaryToolbar.appendSeparator();
+      appendChunk(
+          ls`${Number.bytesToString(selectedResourceSize)} / ${Number.bytesToString(resourceSize)} resources`,
+          ls`${selectedResourceSize} B / ${resourceSize} B resources`);
     } else {
-      appendChunk(Common.UIString('%d requests', nodeCount));
-      appendChunk(separator);
-      appendChunk(Common.UIString('%s transferred', Number.bytesToString(transferSize)));
-      appendChunk(separator);
-      appendChunk(Common.UIString('%s resources', Number.bytesToString(resourceSize)));
+      appendChunk(ls`${nodeCount} requests`);
+      this._summaryToolbar.appendSeparator();
+      appendChunk(ls`${Number.bytesToString(transferSize)} transferred`, ls`${transferSize} B transferred`);
+      this._summaryToolbar.appendSeparator();
+      appendChunk(ls`${Number.bytesToString(resourceSize)} resources`, ls`${resourceSize} B resources`);
     }
 
     if (baseTime !== -1 && maxTime !== -1) {
-      appendChunk(separator);
-      appendChunk(Common.UIString('Finish: %s', Number.secondsToString(maxTime - baseTime)));
+      this._summaryToolbar.appendSeparator();
+      appendChunk(ls`Finish: ${Number.secondsToString(maxTime - baseTime)}`);
       if (this._mainRequestDOMContentLoadedTime !== -1 && this._mainRequestDOMContentLoadedTime > baseTime) {
-        appendChunk(separator);
+        this._summaryToolbar.appendSeparator();
         const domContentLoadedText =
             ls`DOMContentLoaded: ${Number.secondsToString(this._mainRequestDOMContentLoadedTime - baseTime)}`;
-        appendChunk(domContentLoadedText).classList.add('summary-dcl-event');
+        appendChunk(domContentLoadedText).style.color = Network.NetworkLogView.getDCLEventColor();
       }
       if (this._mainRequestLoadTime !== -1) {
-        appendChunk(separator);
+        this._summaryToolbar.appendSeparator();
         const loadText = ls`Load: ${Number.secondsToString(this._mainRequestLoadTime - baseTime)}`;
-        appendChunk(loadText).classList.add('summary-load-event');
+        appendChunk(loadText).style.color = Network.NetworkLogView.getLoadEventColor();
       }
     }
-    summaryBar.title = text;
   }
 
   scheduleRefresh() {
@@ -1842,6 +1841,22 @@
     const commands = await Promise.all(nonBlobRequests.map(request => this._generatePowerShellCommand(request)));
     return commands.join(';\r\n');
   }
+
+  /**
+   * @return {string}
+   */
+  static getDCLEventColor() {
+    if (UI.themeSupport.themeName() === 'dark')
+      return '#03A9F4';
+    return '#0867CB';
+  }
+
+  /**
+   * @return {string}
+   */
+  static getLoadEventColor() {
+    return UI.themeSupport.patchColorText('#B31412', UI.ThemeSupport.ColorUsage.Foreground);
+  }
 };
 
 Network.NetworkLogView._isFilteredOutSymbol = Symbol('isFilteredOut');
diff --git a/third_party/blink/renderer/devtools/front_end/network/NetworkOverview.js b/third_party/blink/renderer/devtools/front_end/network/NetworkOverview.js
index bcaad0e..bcefb83c 100644
--- a/third_party/blink/renderer/devtools/front_end/network/NetworkOverview.js
+++ b/third_party/blink/renderer/devtools/front_end/network/NetworkOverview.js
@@ -242,7 +242,7 @@
     const height = this.element.offsetHeight;
     context.lineWidth = 1;
     context.beginPath();
-    context.strokeStyle = '#0867CB';  // Keep in sync with .summary-dcl-event CSS rule.
+    context.strokeStyle = Network.NetworkLogView.getDCLEventColor();
     for (let i = this._domContentLoadedEvents.length - 1; i >= 0; --i) {
       const x = Math.round(calculator.computePosition(this._domContentLoadedEvents[i])) + 0.5;
       context.moveTo(x, 0);
@@ -251,7 +251,7 @@
     context.stroke();
 
     context.beginPath();
-    context.strokeStyle = '#B31412';  // Keep in sync with .summary-load-event CSS rule.
+    context.strokeStyle = Network.NetworkLogView.getLoadEventColor();
     for (let i = this._loadEvents.length - 1; i >= 0; --i) {
       const x = Math.round(calculator.computePosition(this._loadEvents[i])) + 0.5;
       context.moveTo(x, 0);
diff --git a/third_party/blink/renderer/devtools/front_end/network/binaryResourceView.css b/third_party/blink/renderer/devtools/front_end/network/binaryResourceView.css
index 12594b7..eab1b72c 100644
--- a/third_party/blink/renderer/devtools/front_end/network/binaryResourceView.css
+++ b/third_party/blink/renderer/devtools/front_end/network/binaryResourceView.css
@@ -8,7 +8,6 @@
   border-top: 1px solid #ccc;
   border-bottom: 0px;
   padding-left: 5px;
-  background-color: #eee;
 }
 
 .binary-view-copied-text {
diff --git a/third_party/blink/renderer/devtools/front_end/network/networkLogView.css b/third_party/blink/renderer/devtools/front_end/network/networkLogView.css
index eaeb07a4..937c2422 100644
--- a/third_party/blink/renderer/devtools/front_end/network/networkLogView.css
+++ b/third_party/blink/renderer/devtools/front_end/network/networkLogView.css
@@ -44,6 +44,10 @@
     overflow: hidden;
 }
 
+.panel.network .toolbar.network-summary-bar {
+    border-bottom: 0px;
+}
+
 .network-summary-bar span[is=dt-icon-label] {
     margin-right: 6px;
 }
@@ -264,10 +268,6 @@
     color: grey;
 }
 
-.network-summary-bar .summary-load-event {
-    color: #B31412;
-}
-
 .network-frame-divider {
     width: 2px;
     background-color: #FCCC49;
@@ -279,14 +279,6 @@
     overflow: hidden;
 }
 
-.network-summary-bar .summary-dcl-event {
-    color: #0867CB;
-}
-
-.-theme-with-dark-background .network-summary-bar .summary-dcl-event {
-    color: #03A9F4;
-}
-
 .network-log-grid.data-grid .resources-dividers {
     z-index: 0;
 }
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
index bb51916a..567751b 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
@@ -328,11 +328,13 @@
 }
 
 void ClipboardPromise::OnLoadBufferComplete(DOMArrayBuffer* array_buffer) {
+  DCHECK(array_buffer);
+  DCHECK_CALLED_ON_VALID_SEQUENCE(async_clipboard_sequence_checker);
+  file_reader_.reset();
+
   String blob_type =
       blob_sequence_data_[clipboard_representation_index_ - 1]->type();
-  DCHECK_CALLED_ON_VALID_SEQUENCE(async_clipboard_sequence_checker);
   DCHECK(IsValidClipboardType(blob_type));
-  file_reader_.reset();
 
   if (blob_type == kMimeTypeImagePng) {
     worker_pool::PostTask(
@@ -422,7 +424,10 @@
 void ClipboardPromise::Reject() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(async_clipboard_sequence_checker);
 
-  script_promise_resolver_->Reject();
+  script_promise_resolver_->Reject(DOMException::Create(
+      DOMExceptionCode::kDataError,
+      "Failed to read Blob for clipboard item type " +
+          blob_sequence_data_[clipboard_representation_index_]->type() + "."));
 }
 
 // TODO(huangdarwin): This is beginning to share responsibility
diff --git a/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc b/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc
index 1c02c37..1b908ce 100644
--- a/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc
+++ b/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc
@@ -104,8 +104,7 @@
       frame, std::move(creation_params), reporting_proxy,
       pending_generator_registry);
   // TODO(bashi): Handle a case where the script controller fails to initialize.
-  global_scope->ScriptController()->InitializeContext(global_scope->Name(),
-                                                      NullURL());
+  global_scope->ScriptController()->Initialize(NullURL());
   MainThreadDebugger::Instance()->ContextCreated(
       global_scope->ScriptController()->GetScriptState(),
       global_scope->GetFrame(), global_scope->DocumentSecurityOrigin());
diff --git a/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc b/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc
index 0f84d908..9050878 100644
--- a/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc
+++ b/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc
@@ -264,8 +264,8 @@
     const WebConsoleMessage& message) {
   shadow_page_->GetDocument()->AddConsoleMessage(ConsoleMessage::Create(
       kOtherMessageSource, message.level, message.text,
-      SourceLocation::Create(message.url, message.line_number,
-                             message.column_number, nullptr)));
+      std::make_unique<SourceLocation>(message.url, message.line_number,
+                                       message.column_number, nullptr)));
 }
 
 void WebEmbeddedWorkerImpl::BindDevToolsAgent(
@@ -520,11 +520,11 @@
           std::move(cached_meta_data), v8_inspector::V8StackTraceId());
     } else {
       // When OMT fetch is enabled and this is a new script, fetch the script
-      // now using ImportClassicScript().
+      // now using FetchAndRunClassicScript().
       auto* outside_settings_object = CreateFetchClientSettingsObject();
-      worker_thread_->ImportClassicScript(worker_start_data_.script_url,
-                                          *outside_settings_object,
-                                          v8_inspector::V8StackTraceId());
+      worker_thread_->FetchAndRunClassicScript(worker_start_data_.script_url,
+                                               *outside_settings_object,
+                                               v8_inspector::V8StackTraceId());
     }
   } else {
     // > "module": Fetch a module worker script graph given job’s serialized
@@ -534,9 +534,9 @@
     auto* outside_settings_object = CreateFetchClientSettingsObject();
     network::mojom::FetchCredentialsMode credentials_mode =
         network::mojom::FetchCredentialsMode::kOmit;
-    worker_thread_->ImportModuleScript(worker_start_data_.script_url,
-                                       *outside_settings_object,
-                                       credentials_mode);
+    worker_thread_->FetchAndRunModuleScript(worker_start_data_.script_url,
+                                            *outside_settings_object,
+                                            credentials_mode);
   }
 }
 
diff --git a/third_party/blink/renderer/modules/gamepad/gamepad.cc b/third_party/blink/renderer/modules/gamepad/gamepad.cc
index 5db3a29..7e17e6b 100644
--- a/third_party/blink/renderer/modules/gamepad/gamepad.cc
+++ b/third_party/blink/renderer/modules/gamepad/gamepad.cc
@@ -33,6 +33,8 @@
     : ContextClient(context),
       index_(0),
       timestamp_(0.0),
+      has_vibration_actuator_(false),
+      vibration_actuator_type_(device::GamepadHapticActuatorType::kDualRumble),
       display_id_(0),
       is_axis_data_dirty_(true),
       is_button_data_dirty_(true) {}
@@ -87,20 +89,10 @@
   is_button_data_dirty_ = true;
 }
 
-void Gamepad::SetVibrationActuator(
+void Gamepad::SetVibrationActuatorInfo(
     const device::GamepadHapticActuator& actuator) {
-  if (!actuator.not_null) {
-    if (vibration_actuator_)
-      vibration_actuator_ = nullptr;
-    return;
-  }
-
-  if (!vibration_actuator_) {
-    vibration_actuator_ =
-        GamepadHapticActuator::Create(GetExecutionContext(), index_);
-  }
-
-  vibration_actuator_->SetType(actuator.type);
+  has_vibration_actuator_ = actuator.not_null;
+  vibration_actuator_type_ = actuator.type;
 }
 
 void Gamepad::SetPose(const device::GamepadPose& pose) {
@@ -132,6 +124,23 @@
   }
 }
 
+void Gamepad::InitializeSharedState() {
+  if (has_vibration_actuator_) {
+    vibration_actuator_ =
+        GamepadHapticActuator::Create(GetExecutionContext(), index_);
+    vibration_actuator_->SetType(vibration_actuator_type_);
+  } else {
+    vibration_actuator_ = nullptr;
+  }
+}
+
+void Gamepad::CopySharedStateFromBackBuffer(const Gamepad* back) {
+  DCHECK(back);
+  // Haptic actuators retain state about ongoing effects that should be
+  // preserved when the buffers are swapped.
+  vibration_actuator_ = back->vibration_actuator_;
+}
+
 void Gamepad::Trace(blink::Visitor* visitor) {
   visitor->Trace(buttons_);
   visitor->Trace(vibration_actuator_);
diff --git a/third_party/blink/renderer/modules/gamepad/gamepad.h b/third_party/blink/renderer/modules/gamepad/gamepad.h
index 6aef9ad6..a0ece959 100644
--- a/third_party/blink/renderer/modules/gamepad/gamepad.h
+++ b/third_party/blink/renderer/modules/gamepad/gamepad.h
@@ -78,7 +78,8 @@
   GamepadHapticActuator* vibrationActuator() const {
     return vibration_actuator_;
   }
-  void SetVibrationActuator(const device::GamepadHapticActuator&);
+  void SetVibrationActuatorInfo(const device::GamepadHapticActuator&);
+  bool HasVibrationActuator() const { return has_vibration_actuator_; }
 
   GamepadPose* pose() const { return pose_; }
   void SetPose(const device::GamepadPose&);
@@ -89,21 +90,57 @@
   unsigned displayId() const { return display_id_; }
   void SetDisplayId(unsigned val) { display_id_ = val; }
 
+  void InitializeSharedState();
+  void CopySharedStateFromBackBuffer(const Gamepad* back);
+
   void Trace(blink::Visitor*) override;
 
  private:
+  // A string identifying the gamepad model.
   String id_;
+
+  // The index of this gamepad within the GamepadList.
   unsigned index_;
+
+  // True if this gamepad was still connected when gamepad state was captured.
   bool connected_;
+
+  // The current time when the gamepad state was captured.
   DOMHighResTimeStamp timestamp_;
+
+  // A string indicating whether the standard mapping is in use.
   String mapping_;
+
+  // Snapshot of the axis state.
   DoubleVector axes_;
+
+  // Snapshot of the button state.
   GamepadButtonVector buttons_;
+
+  // True if the gamepad can produce haptic vibration effects.
+  bool has_vibration_actuator_;
+
+  // The type of haptic actuator used for vibration effects.
+  device::GamepadHapticActuatorType vibration_actuator_type_;
+
+  // The vibration actuator, or nullptr if the gamepad has none.
   Member<GamepadHapticActuator> vibration_actuator_;
+
+  // Snapshot of the gamepad pose.
   Member<GamepadPose> pose_;
+
+  // A string representing the handedness of the gamepad.
   String hand_;
+
+  // An identifier for associating a gamepad with a VR headset.
   unsigned display_id_;
+
+  // True if the data in |axes_| has changed since the last time it was
+  // accessed.
   bool is_axis_data_dirty_;
+
+  // True if the data in |buttons_| has changed since the last time it was
+  // accessed.
   bool is_button_data_dirty_;
 };
 
diff --git a/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc b/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc
index a2240d6..b7331745 100644
--- a/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc
+++ b/third_party/blink/renderer/modules/gamepad/navigator_gamepad.cc
@@ -96,16 +96,16 @@
   if (newly_connected) {
     gamepad.SetIndex(index);
     gamepad.SetMapping(device_gamepad.mapping);
-    gamepad.SetVibrationActuator(device_gamepad.vibration_actuator);
+    gamepad.SetVibrationActuatorInfo(device_gamepad.vibration_actuator);
     // Re-map display ids, since we will hand out at most one VRDisplay.
     gamepad.SetDisplayId(device_gamepad.display_id ? 1 : 0);
-  } else if (!gamepad.vibrationActuator() &&
+  } else if (!gamepad.HasVibrationActuator() &&
              device_gamepad.vibration_actuator.not_null) {
     // Some gamepads require additional steps to determine haptics capability.
     // These gamepads may initially set |vibration_actuator| to null and then
     // update it some time later. Make sure such devices can correctly propagate
     // the changed capabilities.
-    gamepad.SetVibrationActuator(device_gamepad.vibration_actuator);
+    gamepad.SetVibrationActuatorInfo(device_gamepad.vibration_actuator);
   }
 }
 
@@ -306,6 +306,24 @@
   StopUpdating();
 }
 
+void NavigatorGamepad::SwapGamepadBuffers() {
+  // Swap the underlying buffers.
+  gamepads_.Swap(gamepads_back_);
+
+  // Preserve internal state when the buffers are swapped.
+  for (unsigned i = 0; i < gamepads_->length(); ++i) {
+    auto* gamepad_front = gamepads_->item(i);
+    if (!gamepad_front)
+      continue;
+    const auto* gamepad_back =
+        gamepads_back_ ? gamepads_back_->item(i) : nullptr;
+    if (gamepad_back)
+      gamepad_front->CopySharedStateFromBackBuffer(gamepad_back);
+    else
+      gamepad_front->InitializeSharedState();
+  }
+}
+
 void NavigatorGamepad::SampleAndCompareGamepadState() {
   // Avoid re-entry. Do not fetch a new sample until we are finished dispatching
   // events from the previous sample.
@@ -332,7 +350,7 @@
       auto compare_result = GamepadComparisons::Compare(
           gamepads_.Get(), gamepads_back_.Get(), false, false);
       if (compare_result.IsDifferent()) {
-        gamepads_.Swap(gamepads_back_);
+        SwapGamepadBuffers();
         bool is_gamepads_back_exposed = is_gamepads_exposed_;
         is_gamepads_exposed_ = false;
 
@@ -345,18 +363,28 @@
         // of event listeners may also change if listeners are added or removed
         // by another listener.
         for (uint32_t i = 0; i < device::Gamepads::kItemsLengthCap; ++i) {
+          bool is_connected = compare_result.IsGamepadConnected(i);
+          bool is_disconnected = compare_result.IsGamepadDisconnected(i);
+
+          if (is_connected && is_disconnected) {
+            // The newly-connected gamepad represents a different device than
+            // the disconnected gamepad. Clear any shared state copied from the
+            // back buffer.
+            Gamepad* pad = gamepads_->item(i);
+            DCHECK(pad);
+            pad->InitializeSharedState();
+          }
+
           // When a gamepad is disconnected and connected in the same update,
           // dispatch the gamepaddisconnected event first.
-          if (has_connection_event_listener_ &&
-              compare_result.IsGamepadDisconnected(i)) {
+          if (has_connection_event_listener_ && is_disconnected) {
             Gamepad* pad = gamepads_back_->item(i);
             DCHECK(pad);
             pad->SetConnected(false);
             is_gamepads_back_exposed = true;
             DispatchGamepadEvent(event_type_names::kGamepaddisconnected, pad);
           }
-          if (has_connection_event_listener_ &&
-              compare_result.IsGamepadConnected(i)) {
+          if (has_connection_event_listener_ && is_connected) {
             Gamepad* pad = gamepads_->item(i);
             DCHECK(pad);
             is_gamepads_exposed_ = true;
diff --git a/third_party/blink/renderer/modules/gamepad/navigator_gamepad.h b/third_party/blink/renderer/modules/gamepad/navigator_gamepad.h
index 8dabea5..1753603 100644
--- a/third_party/blink/renderer/modules/gamepad/navigator_gamepad.h
+++ b/third_party/blink/renderer/modules/gamepad/navigator_gamepad.h
@@ -68,6 +68,7 @@
  private:
   void DidRemoveGamepadEventListeners();
   bool StartUpdatingIfAttached();
+  void SwapGamepadBuffers();
   void SampleAndCompareGamepadState();
   void DispatchGamepadEvent(const AtomicString&, Gamepad*);
 
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc
index eac3c424..7c5c2c5c 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.cc
@@ -157,17 +157,12 @@
                       scoped_refptr<Observer>(this), webrtc_channel_->state()));
 }
 
-void RTCDataChannel::Observer::OnBufferedAmountChange(
-    uint64_t previous_amount) {
-  // Optimization: Only post a task if the change is a decrease, because the web
-  // interface does not perform any action when there is an increase.
-  if (previous_amount > webrtc_channel_->buffered_amount()) {
-    PostCrossThreadTask(
-        *main_thread_, FROM_HERE,
-        CrossThreadBind(&RTCDataChannel::Observer::OnBufferedAmountDecreaseImpl,
-                        scoped_refptr<Observer>(this),
-                        SafeCast<unsigned>(previous_amount)));
-  }
+void RTCDataChannel::Observer::OnBufferedAmountChange(uint64_t sent_data_size) {
+  PostCrossThreadTask(
+      *main_thread_, FROM_HERE,
+      CrossThreadBind(&RTCDataChannel::Observer::OnBufferedAmountChangeImpl,
+                      scoped_refptr<Observer>(this),
+                      SafeCast<unsigned>(sent_data_size)));
 }
 
 void RTCDataChannel::Observer::OnMessage(const webrtc::DataBuffer& buffer) {
@@ -188,11 +183,11 @@
     blink_channel_->OnStateChange(state);
 }
 
-void RTCDataChannel::Observer::OnBufferedAmountDecreaseImpl(
-    unsigned previous_amount) {
+void RTCDataChannel::Observer::OnBufferedAmountChangeImpl(
+    unsigned sent_data_size) {
   DCHECK(main_thread_->BelongsToCurrentThread());
   if (blink_channel_)
-    blink_channel_->OnBufferedAmountDecrease(previous_amount);
+    blink_channel_->OnBufferedAmountChange(sent_data_size);
 }
 
 void RTCDataChannel::Observer::OnMessageImpl(
@@ -222,6 +217,7 @@
                              this,
                              &RTCDataChannel::ScheduledEventTimerFired),
       buffered_amount_low_threshold_(0U),
+      buffered_amount_(0U),
       stopped_(false),
       observer_(base::MakeRefCounted<Observer>(
           context->GetTaskRunner(TaskType::kInternalMedia),
@@ -310,7 +306,7 @@
 }
 
 unsigned RTCDataChannel::bufferedAmount() const {
-  return SafeCast<unsigned>(channel()->buffered_amount());
+  return buffered_amount_;
 }
 
 unsigned RTCDataChannel::bufferedAmountLowThreshold() const {
@@ -352,10 +348,11 @@
 
   std::string utf8_buffer = static_cast<WebString>(data).Utf8();
   webrtc::DataBuffer data_buffer(utf8_buffer);
+  buffered_amount_ += data_buffer.size();
   RecordMessageSent(*channel().get(), data_buffer.size());
   if (!channel()->Send(data_buffer)) {
-    // FIXME: This should not throw an exception but instead forcefully close
-    // the data channel.
+    // TODO(https://crbug.com/937848): Don't throw an exception if data is
+    // queued.
     ThrowCouldNotSendDataException(&exception_state);
   }
 }
@@ -371,19 +368,21 @@
   if (!data_length)
     return;
 
+  buffered_amount_ += data_length;
   if (!SendRawData(static_cast<const char*>((data->Data())), data_length)) {
-    // FIXME: This should not throw an exception but instead forcefully close
-    // the data channel.
+    // TODO(https://crbug.com/937848): Don't throw an exception if data is
+    // queued.
     ThrowCouldNotSendDataException(&exception_state);
   }
 }
 
 void RTCDataChannel::send(NotShared<DOMArrayBufferView> data,
                           ExceptionState& exception_state) {
+  buffered_amount_ += data.View()->byteLength();
   if (!SendRawData(static_cast<const char*>(data.View()->BaseAddress()),
                    data.View()->byteLength())) {
-    // FIXME: This should not throw an exception but instead forcefully close
-    // the data channel.
+    // TODO(https://crbug.com/937848): Don't throw an exception if data is
+    // queued.
     ThrowCouldNotSendDataException(&exception_state);
   }
 }
@@ -485,12 +484,15 @@
   }
 }
 
-void RTCDataChannel::OnBufferedAmountDecrease(unsigned previous_amount) {
+void RTCDataChannel::OnBufferedAmountChange(unsigned sent_data_size) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DVLOG(1) << "OnBufferedAmountDecrease " << previous_amount;
+  unsigned previous_amount = buffered_amount_;
+  DVLOG(1) << "OnBufferedAmountChange " << previous_amount;
+  DCHECK_GE(buffered_amount_, sent_data_size);
+  buffered_amount_ -= sent_data_size;
 
   if (previous_amount > buffered_amount_low_threshold_ &&
-      bufferedAmount() <= buffered_amount_low_threshold_) {
+      buffered_amount_ <= buffered_amount_low_threshold_) {
     ScheduleDispatchEvent(Event::Create(event_type_names::kBufferedamountlow));
   }
 }
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h
index 0de029931..c43ce09 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h
@@ -139,13 +139,13 @@
 
     // webrtc::DataChannelObserver implementation, called from signaling thread.
     void OnStateChange() override;
-    void OnBufferedAmountChange(uint64_t previous_amount) override;
+    void OnBufferedAmountChange(uint64_t sent_data_size) override;
     void OnMessage(const webrtc::DataBuffer& buffer) override;
 
    private:
     // webrtc::DataChannelObserver implementation on the main thread.
     void OnStateChangeImpl(webrtc::DataChannelInterface::DataState state);
-    void OnBufferedAmountDecreaseImpl(unsigned previous_amount);
+    void OnBufferedAmountChangeImpl(unsigned sent_data_size);
     void OnMessageImpl(std::unique_ptr<webrtc::DataBuffer> buffer);
 
     const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
@@ -154,7 +154,7 @@
   };
 
   void OnStateChange(webrtc::DataChannelInterface::DataState state);
-  void OnBufferedAmountDecrease(unsigned previous_amount);
+  void OnBufferedAmountChange(unsigned previous_amount);
   void OnMessage(std::unique_ptr<webrtc::DataBuffer> buffer);
 
   void Dispose();
@@ -178,6 +178,7 @@
   FRIEND_TEST_ALL_PREFIXES(RTCDataChannelTest, BufferedAmountLow);
 
   unsigned buffered_amount_low_threshold_;
+  unsigned buffered_amount_;
   bool stopped_;
   scoped_refptr<Observer> observer_;
   SEQUENCE_CHECKER(sequence_checker_);
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc
index 98b8f55..564ea77 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc
@@ -146,13 +146,6 @@
     base::RunLoop().RunUntilIdle();
   }
 
-  void DrainBuffer(uint64_t bytes) {
-    RunSynchronous(
-        signaling_thread_.get(),
-        CrossThreadBind(&MockDataChannel::DrainBufferOnSignalingThread,
-                        CrossThreadUnretained(this), bytes));
-  }
-
  protected:
   ~MockDataChannel() override = default;
 
@@ -191,16 +184,6 @@
     }
   }
 
-  void DrainBufferOnSignalingThread(uint64_t bytes) {
-    DCHECK(signaling_thread_->BelongsToCurrentThread());
-    uint64_t old_buffered_amount = SafeCast<uint64_t>(buffered_amount_);
-    buffered_amount_ -= bytes;
-    if (observer_) {
-      observer_->OnBufferedAmountChange(
-          static_cast<unsigned>(old_buffered_amount));
-    }
-  }
-
   scoped_refptr<base::TestSimpleTaskRunner> signaling_thread_;
 
   // Accessed on signaling thread.
@@ -277,9 +260,8 @@
   channel->setBufferedAmountLowThreshold(1);
   channel->send("TEST", IGNORE_EXCEPTION_FOR_TESTING);
   EXPECT_EQ(4U, channel->bufferedAmount());
-  webrtc_channel->DrainBuffer(4);
-  channel->OnBufferedAmountDecrease(4);
-  EXPECT_EQ(1U, channel->scheduled_events_.size());
+  channel->OnBufferedAmountChange(4);
+  ASSERT_EQ(1U, channel->scheduled_events_.size());
   EXPECT_EQ(
       "bufferedamountlow",
       std::string(channel->scheduled_events_.back()->type().Utf8().data()));
@@ -294,7 +276,7 @@
       RTCDataChannel::Create(MakeGarbageCollected<NullExecutionContext>(),
                              webrtc_channel.get(), pc.get());
   channel->OnStateChange(webrtc::DataChannelInterface::kOpen);
-  EXPECT_EQ(1U, channel->scheduled_events_.size());
+  ASSERT_EQ(1U, channel->scheduled_events_.size());
   EXPECT_EQ(
       "open",
       std::string(channel->scheduled_events_.back()->type().Utf8().data()));
@@ -309,7 +291,7 @@
       RTCDataChannel::Create(MakeGarbageCollected<NullExecutionContext>(),
                              webrtc_channel.get(), pc.get());
   channel->OnStateChange(webrtc::DataChannelInterface::kClosed);
-  EXPECT_EQ(1U, channel->scheduled_events_.size());
+  ASSERT_EQ(1U, channel->scheduled_events_.size());
   EXPECT_EQ(
       "close",
       std::string(channel->scheduled_events_.back()->type().Utf8().data()));
@@ -326,7 +308,7 @@
 
   std::unique_ptr<webrtc::DataBuffer> message(new webrtc::DataBuffer("A"));
   channel->OnMessage(std::move(message));
-  EXPECT_EQ(1U, channel->scheduled_events_.size());
+  ASSERT_EQ(1U, channel->scheduled_events_.size());
   EXPECT_EQ(
       "message",
       std::string(channel->scheduled_events_.back()->type().Utf8().data()));
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
index a963e98..49a2d16 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
@@ -33,8 +33,10 @@
 #include <memory>
 #include <utility>
 
+#include "base/feature_list.h"
 #include "base/memory/ptr_util.h"
 #include "base/numerics/safe_conversions.h"
+#include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/web_url.h"
 #include "third_party/blink/renderer/bindings/core/v8/callback_promise_adapter.h"
@@ -51,9 +53,11 @@
 #include "third_party/blink/renderer/core/inspector/worker_thread_debugger.h"
 #include "third_party/blink/renderer/core/loader/threadable_loader.h"
 #include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h"
+#include "third_party/blink/renderer/core/probe/core_probes.h"
 #include "third_party/blink/renderer/core/trustedtypes/trusted_script_url.h"
 #include "third_party/blink/renderer/core/workers/global_scope_creation_params.h"
 #include "third_party/blink/renderer/core/workers/installed_scripts_manager.h"
+#include "third_party/blink/renderer/core/workers/worker_classic_script_loader.h"
 #include "third_party/blink/renderer/core/workers/worker_clients.h"
 #include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h"
 #include "third_party/blink/renderer/modules/event_target_modules.h"
@@ -69,11 +73,13 @@
 #include "third_party/blink/renderer/platform/bindings/script_state.h"
 #include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
 #include "third_party/blink/renderer/platform/histogram.h"
+#include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h"
 #include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
 #include "third_party/blink/renderer/platform/network/content_security_policy_response_headers.h"
 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
+#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
 #include "third_party/blink/renderer/platform/wtf/time.h"
 
 namespace blink {
@@ -136,7 +142,55 @@
       WebSecurityOrigin(GetSecurityOrigin()));
 }
 
-void ServiceWorkerGlobalScope::ImportModuleScript(
+// https://w3c.github.io/ServiceWorker/#update
+void ServiceWorkerGlobalScope::FetchAndRunClassicScript(
+    const KURL& script_url,
+    const FetchClientSettingsObjectSnapshot& outside_settings_object,
+    const v8_inspector::V8StackTraceId& stack_id) {
+  DCHECK(base::FeatureList::IsEnabled(
+      features::kOffMainThreadServiceWorkerScriptFetch));
+  DCHECK(!IsContextPaused());
+
+  // Step 9. "Switching on job's worker type, run these substeps with the
+  // following options:"
+  // "classic: Fetch a classic worker script given job's serialized script url,
+  // job's client, "serviceworker", and the to-be-created environment settings
+  // object for this service worker."
+  auto destination = mojom::RequestContextType::SERVICE_WORKER;
+
+  // "To perform the fetch given request, run the following steps:"
+  // Step 9.1. "Append `Service-Worker`/`script` to request's header list."
+  // Step 9.2. "Set request's cache mode to "no-cache" if any of the following
+  // are true:"
+  // Step 9.3. "Set request's service-workers mode to "none"."
+  // The browser process takes care of these steps.
+
+  // Step 9.4. "If the is top-level flag is unset, then return the result of
+  // fetching request."
+  // This step makes sense only when the worker type is "module". For classic
+  // script fetch, the top-level flag is always set.
+
+  // Step 9.5. "Set request's redirect mode to "error"."
+  // The browser process takes care of this step.
+
+  // Step 9.6. "Fetch request, and asynchronously wait to run the remaining
+  // steps as part of fetch's process response for the response response."
+  WorkerClassicScriptLoader* classic_script_loader =
+      MakeGarbageCollected<WorkerClassicScriptLoader>();
+  classic_script_loader->LoadTopLevelScriptAsynchronously(
+      *this, CreateOutsideSettingsFetcher(outside_settings_object), script_url,
+      destination, network::mojom::FetchRequestMode::kSameOrigin,
+      network::mojom::FetchCredentialsMode::kSameOrigin,
+      GetSecurityContext().AddressSpace(),
+      WTF::Bind(&ServiceWorkerGlobalScope::DidReceiveResponseForClassicScript,
+                WrapWeakPersistent(this),
+                WrapPersistent(classic_script_loader)),
+      WTF::Bind(&ServiceWorkerGlobalScope::DidFetchClassicScript,
+                WrapWeakPersistent(this), WrapPersistent(classic_script_loader),
+                stack_id));
+}
+
+void ServiceWorkerGlobalScope::FetchAndRunModuleScript(
     const KURL& module_url_record,
     const FetchClientSettingsObjectSnapshot& outside_settings_object,
     network::mojom::FetchCredentialsMode credentials_mode) {
@@ -223,6 +277,88 @@
   }
 }
 
+void ServiceWorkerGlobalScope::DidReceiveResponseForClassicScript(
+    WorkerClassicScriptLoader* classic_script_loader) {
+  DCHECK(IsContextThread());
+  DCHECK(base::FeatureList::IsEnabled(
+      features::kOffMainThreadServiceWorkerScriptFetch));
+  probe::DidReceiveScriptResponse(this, classic_script_loader->Identifier());
+}
+
+// https://w3c.github.io/ServiceWorker/#update
+void ServiceWorkerGlobalScope::DidFetchClassicScript(
+    WorkerClassicScriptLoader* classic_script_loader,
+    const v8_inspector::V8StackTraceId& stack_id) {
+  DCHECK(IsContextThread());
+  DCHECK(base::FeatureList::IsEnabled(
+      features::kOffMainThreadServiceWorkerScriptFetch));
+
+  // Step 9. "If the algorithm asynchronously completes with null, then:"
+  if (classic_script_loader->Failed()) {
+    // Step 9.1. "Invoke Reject Job Promise with job and TypeError."
+    // Step 9.2. "If newestWorker is null, invoke Clear Registration algorithm
+    // passing registration as its argument."
+    // Step 9.3. "Invoke Finish Job with job and abort these steps."
+    // The browser process takes care of these steps.
+    ReportingProxy().DidFailToFetchClassicScript();
+    return;
+  }
+  ReportingProxy().DidFetchScript();
+  probe::ScriptImported(this, classic_script_loader->Identifier(),
+                        classic_script_loader->SourceText());
+
+  // Following steps are quoted from the "Run Service Worker" algorithm.
+  // https://w3c.github.io/ServiceWorker/#run-service-worker-algorithm
+  // TODO(nhiroki): Move these steps into a separate function like
+  // RunServiceWorker().
+
+  // Step 4.5. "Set workerGlobalScope's url to serviceWorker's script url."
+  InitializeURL(classic_script_loader->ResponseURL());
+
+  // Step 4.6. "Set workerGlobalScope's HTTPS state to serviceWorker's script
+  // resource's HTTPS state."
+  // This is done in the constructor of WorkerGlobalScope.
+
+  // Step 4.7. "Set workerGlobalScope's referrer policy to serviceWorker's
+  // script resource's referrer policy."
+  auto referrer_policy = network::mojom::ReferrerPolicy::kDefault;
+  if (!classic_script_loader->GetReferrerPolicy().IsNull()) {
+    SecurityPolicy::ReferrerPolicyFromHeaderValue(
+        classic_script_loader->GetReferrerPolicy(),
+        kDoNotSupportReferrerPolicyLegacyKeywords, &referrer_policy);
+    SetReferrerPolicy(referrer_policy);
+  }
+
+  // TODO(nhiroki): Clarify mappings between the steps 4.8-4.11 and
+  // implementation.
+
+  // This is quoted from the "Content Security Policy" algorithm:
+  // "Whenever a user agent invokes Run Service Worker algorithm with a service
+  // worker serviceWorker:
+  // - If serviceWorker's script resource was delivered with a
+  //   Content-Security-Policy HTTP header containing the value policy, the
+  //   user agent must enforce policy for serviceWorker.
+  // - If serviceWorker's script resource was delivered with a
+  //   Content-Security-Policy-Report-Only HTTP header containing the value
+  //   policy, the user agent must monitor policy for serviceWorker."
+  DCHECK_EQ(GlobalScopeCSPApplyMode::kUseResponseCSP, GetCSPApplyMode());
+  if (classic_script_loader->GetContentSecurityPolicy()) {
+    InitContentSecurityPolicyFromVector(
+        classic_script_loader->GetContentSecurityPolicy()->Headers());
+  } else {
+    // Initialize CSP with an empty list.
+    InitContentSecurityPolicyFromVector(Vector<CSPHeaderAndType>());
+  }
+  BindContentSecurityPolicyToExecutionContext();
+
+  // Step 4.12. "Let evaluationStatus be the result of running the classic
+  // script script if script is a classic script, otherwise, the result of
+  // running the module script script if script is a module script."
+  EvaluateClassicScript(
+      classic_script_loader->ResponseURL(), classic_script_loader->SourceText(),
+      classic_script_loader->ReleaseCachedMetadata(), stack_id);
+}
+
 void ServiceWorkerGlobalScope::CountScriptInternal(
     size_t script_size,
     size_t cached_metadata_size) {
@@ -330,8 +466,8 @@
     }
 
     // WorkerGlobalScope sets the response URL, referrer policy and CSP list in
-    // DidImportClassicScript(). Since we bypass calling
-    // DidImportClassicScript(), set them here.
+    // DidFetchClassicScript(). Since we bypass calling DidFetchClassicScript(),
+    // set them here.
 
     DCHECK_EQ(GlobalScopeCSPApplyMode::kUseResponseCSP, GetCSPApplyMode());
 
@@ -450,11 +586,6 @@
     debugger->ExceptionThrown(GetThread(), event);
 }
 
-mojom::RequestContextType
-ServiceWorkerGlobalScope::GetDestinationForMainScript() {
-  return mojom::RequestContextType::SERVICE_WORKER;
-}
-
 void ServiceWorkerGlobalScope::CountCacheStorageInstalledScript(
     uint64_t script_size,
     uint64_t script_metadata_size) {
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
index b399e8b..0595dd4 100644
--- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
+++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
@@ -53,6 +53,7 @@
 class ServiceWorkerThread;
 class StringOrTrustedScriptURL;
 class WaitUntilObserver;
+class WorkerClassicScriptLoader;
 struct GlobalScopeCreationParams;
 struct WebServiceWorkerObjectInfo;
 struct WebServiceWorkerRegistrationObjectInfo;
@@ -80,7 +81,11 @@
   bool ShouldInstallV8Extensions() const final;
 
   // Implements WorkerGlobalScope.
-  void ImportModuleScript(
+  void FetchAndRunClassicScript(
+      const KURL& script_url,
+      const FetchClientSettingsObjectSnapshot& outside_settings_object,
+      const v8_inspector::V8StackTraceId& stack_id) override;
+  void FetchAndRunModuleScript(
       const KURL& module_url_record,
       const FetchClientSettingsObjectSnapshot& outside_settings_object,
       network::mojom::FetchCredentialsMode) override;
@@ -167,7 +172,11 @@
       const KURL& script_url,
       const Vector<uint8_t>* meta_data) override;
   void ExceptionThrown(ErrorEvent*) override;
-  mojom::RequestContextType GetDestinationForMainScript() override;
+
+  void DidReceiveResponseForClassicScript(
+      WorkerClassicScriptLoader* classic_script_loader);
+  void DidFetchClassicScript(WorkerClassicScriptLoader* classic_script_loader,
+                             const v8_inspector::V8StackTraceId& stack_id);
 
   // Counts the |script_size| and |cached_metadata_size| for UMA to measure the
   // number of scripts and the total bytes of scripts.
diff --git a/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc b/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc
index 8153e348..67e364de 100644
--- a/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc
+++ b/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc
@@ -134,7 +134,7 @@
     WebURL script_url =
         url_test_helpers::ToKURL("https://www.example.com/sw.js");
     WebURLResponse response(script_url);
-    response.SetMIMEType("text/javascript");
+    response.SetMimeType("text/javascript");
     response.SetHttpStatusCode(200);
     Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(script_url,
                                                                 response, "");
@@ -231,7 +231,7 @@
   WebURL script_url =
       url_test_helpers::ToKURL("https://www.example.com/sw-404.js");
   WebURLResponse response;
-  response.SetMIMEType("text/javascript");
+  response.SetMimeType("text/javascript");
   response.SetHttpStatusCode(404);
   ResourceError error = ResourceError::Failure(script_url);
   Platform::Current()->GetURLLoaderMockFactory()->RegisterErrorURL(
diff --git a/third_party/blink/renderer/modules/webgpu/BUILD.gn b/third_party/blink/renderer/modules/webgpu/BUILD.gn
index 3e2e9ff..0182dfa 100644
--- a/third_party/blink/renderer/modules/webgpu/BUILD.gn
+++ b/third_party/blink/renderer/modules/webgpu/BUILD.gn
@@ -15,4 +15,7 @@
     "window_webgpu.cc",
     "window_webgpu.h",
   ]
+  deps = [
+    "//third_party/dawn/src/dawn:dawn_headers",
+  ]
 }
diff --git a/third_party/blink/renderer/modules/websockets/dom_websocket.cc b/third_party/blink/renderer/modules/websockets/dom_websocket.cc
index 2baadc0a..26b90ef 100644
--- a/third_party/blink/renderer/modules/websockets/dom_websocket.cc
+++ b/third_party/blink/renderer/modules/websockets/dom_websocket.cc
@@ -614,7 +614,7 @@
     state_ = kClosing;
     channel_->Fail("WebSocket is closed before the connection is established.",
                    mojom::ConsoleMessageLevel::kWarning,
-                   SourceLocation::Create(String(), 0, 0, nullptr));
+                   std::make_unique<SourceLocation>(String(), 0, 0, nullptr));
     return;
   }
   state_ = kClosing;
diff --git a/third_party/blink/renderer/modules/websockets/web_pepper_socket_impl.cc b/third_party/blink/renderer/modules/websockets/web_pepper_socket_impl.cc
index 4eb1db5..c1e4b664 100644
--- a/third_party/blink/renderer/modules/websockets/web_pepper_socket_impl.cc
+++ b/third_party/blink/renderer/modules/websockets/web_pepper_socket_impl.cc
@@ -123,7 +123,7 @@
 
 void WebPepperSocketImpl::Fail(const WebString& reason) {
   private_->Fail(reason, mojom::ConsoleMessageLevel::kError,
-                 SourceLocation::Create(String(), 0, 0, nullptr));
+                 std::make_unique<SourceLocation>(String(), 0, 0, nullptr));
 }
 
 void WebPepperSocketImpl::Disconnect() {
diff --git a/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc b/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc
index 75362aa8..c9b7f86 100644
--- a/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc
+++ b/third_party/blink/renderer/modules/websockets/websocket_channel_impl_test.cc
@@ -801,7 +801,7 @@
 
   Channel()->Fail("fail message from WebSocket",
                   mojom::ConsoleMessageLevel::kError,
-                  SourceLocation::Create(String(), 0, 0, nullptr));
+                  std::make_unique<SourceLocation>(String(), 0, 0, nullptr));
 }
 
 class WebSocketChannelImplHandshakeThrottleTest
@@ -879,7 +879,7 @@
   Channel()->Connect(url(), "");
   Channel()->Fail("close during handshake",
                   mojom::ConsoleMessageLevel::kWarning,
-                  SourceLocation::Create(String(), 0, 0, nullptr));
+                  std::make_unique<SourceLocation>(String(), 0, 0, nullptr));
   checkpoint.Call(1);
 }
 
@@ -900,7 +900,7 @@
   HandleClient()->DidConnect(Handle(), String("a"), String("b"));
   Channel()->Fail("close during handshake",
                   mojom::ConsoleMessageLevel::kWarning,
-                  SourceLocation::Create(String(), 0, 0, nullptr));
+                  std::make_unique<SourceLocation>(String(), 0, 0, nullptr));
   checkpoint.Call(1);
 }
 
diff --git a/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_source.cc b/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_source.cc
index 2334c88..434f6401 100644
--- a/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_source.cc
+++ b/third_party/blink/renderer/platform/exported/mediastream/media_stream_audio_source.cc
@@ -41,7 +41,7 @@
     : is_local_source_(is_local_source),
       disable_local_echo_(disable_local_echo),
       is_stopped_(false),
-      task_runner_(task_runner),
+      task_runner_(std::move(task_runner)),
       weak_factory_(this) {
   DVLOG(1) << "MediaStreamAudioSource@" << this << "::MediaStreamAudioSource("
            << (is_local_source_ ? "local" : "remote") << " source)";
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 f580fb8..c900da2c 100644
--- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc
+++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -374,10 +374,6 @@
   RuntimeEnabledFeatures::SetPortalsEnabled(enable);
 }
 
-void WebRuntimeFeatures::EnablePreloadImageSrcSetEnabled(bool enable) {
-  RuntimeEnabledFeatures::SetPreloadImageSrcSetEnabled(enable);
-}
-
 void WebRuntimeFeatures::EnableRasterInducingScroll(bool enable) {
   RuntimeEnabledFeatures::SetRasterInducingScrollEnabled(enable);
 }
diff --git a/third_party/blink/renderer/platform/exported/web_url_response.cc b/third_party/blink/renderer/platform/exported/web_url_response.cc
index 5cacf47..1681b26 100644
--- a/third_party/blink/renderer/platform/exported/web_url_response.cc
+++ b/third_party/blink/renderer/platform/exported/web_url_response.cc
@@ -116,7 +116,7 @@
   return resource_response_->MimeType();
 }
 
-void WebURLResponse::SetMIMEType(const WebString& mime_type) {
+void WebURLResponse::SetMimeType(const WebString& mime_type) {
   resource_response_->SetMimeType(mime_type);
 }
 
diff --git a/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc b/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc
index 5d11a86..e1fc5f7 100644
--- a/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/raw_resource.cc
@@ -274,7 +274,7 @@
   DCHECK_LE(Clients().size(), 1u);
   RawResourceClient* client =
       ResourceClientWalker<RawResourceClient>(Clients()).Next();
-  if (IsUnusedPreload()) {
+  if (!client && GetResourceRequest().UseStreamOnResponse()) {
     // For preload, we want to store the body while dispatching
     // onload and onerror events.
     bytes_consumer_for_preload_ = MakeGarbageCollected<BufferingBytesConsumer>(
@@ -282,10 +282,6 @@
     return;
   }
 
-  if (!client) {
-    return;
-  }
-
   if (matched_with_non_streaming_destination_) {
     DCHECK(GetResourceRequest().UseStreamOnResponse());
     // The loading was initiated as a preload (hence UseStreamOnResponse is
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 a33d67e..e069aa8 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
@@ -39,6 +39,9 @@
 #include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h"
+#include "third_party/blink/renderer/platform/loader/fetch/response_body_loader.h"
+#include "third_party/blink/renderer/platform/loader/fetch/response_body_loader_client.h"
+#include "third_party/blink/renderer/platform/loader/testing/replaying_bytes_consumer.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
 #include "third_party/blink/renderer/platform/shared_buffer.h"
@@ -55,6 +58,19 @@
   ~RawResourceTest() override = default;
 
  protected:
+  class NoopResponseBodyLoaderClient
+      : public GarbageCollectedFinalized<NoopResponseBodyLoaderClient>,
+        public ResponseBodyLoaderClient {
+    USING_GARBAGE_COLLECTED_MIXIN(NoopResponseBodyLoaderClient);
+
+   public:
+    ~NoopResponseBodyLoaderClient() override {}
+    void DidReceiveData(base::span<const char>) override {}
+    void DidFinishLoadingBody() override {}
+    void DidFailLoadingBody() override {}
+    void DidCancelLoadingBody() override {}
+  };
+
   ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler>
       platform_;
 
@@ -217,4 +233,42 @@
   EXPECT_FALSE(raw->IsAlive());
 }
 
+TEST_F(RawResourceTest, PreloadWithAsynchronousAddClient) {
+  ResourceRequest request(KURL("data:text/html,"));
+  request.SetRequestorOrigin(SecurityOrigin::CreateUniqueOpaque());
+  request.SetUseStreamOnResponse(true);
+
+  Resource* raw = RawResource::CreateForTest(request, ResourceType::kRaw);
+  raw->MarkAsPreload();
+
+  auto* bytes_consumer = MakeGarbageCollected<ReplayingBytesConsumer>(
+      platform_->test_task_runner());
+  bytes_consumer->Add(ReplayingBytesConsumer::Command(
+      ReplayingBytesConsumer::Command::kData, "hello"));
+  bytes_consumer->Add(
+      ReplayingBytesConsumer::Command(ReplayingBytesConsumer::Command::kDone));
+  ResponseBodyLoader* body_loader = MakeGarbageCollected<ResponseBodyLoader>(
+      *bytes_consumer, *MakeGarbageCollected<NoopResponseBodyLoaderClient>(),
+      platform_->test_task_runner().get());
+  Persistent<DummyClient> dummy_client = MakeGarbageCollected<DummyClient>();
+
+  // Set the response first to make ResourceClient addition asynchronous.
+  raw->SetResponse(ResourceResponse(KURL("http://600.613/")));
+
+  FetchParameters params(request);
+  params.MutableResourceRequest().SetUseStreamOnResponse(false);
+  raw->MatchPreload(params, platform_->test_task_runner().get());
+  raw->AddClient(dummy_client, platform_->test_task_runner().get());
+
+  raw->ResponseBodyReceived(*body_loader);
+  raw->FinishForTest();
+  EXPECT_FALSE(dummy_client->Called());
+
+  platform_->RunUntilIdle();
+
+  EXPECT_TRUE(dummy_client->Called());
+  EXPECT_EQ("hello",
+            String(dummy_client->Data().data(), dummy_client->Data().size()));
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/loader/fetch/response_body_loader_client.h b/third_party/blink/renderer/platform/loader/fetch/response_body_loader_client.h
index 15384b8..58921803 100644
--- a/third_party/blink/renderer/platform/loader/fetch/response_body_loader_client.h
+++ b/third_party/blink/renderer/platform/loader/fetch/response_body_loader_client.h
@@ -10,7 +10,7 @@
 // A ResponseBodyLoaderClient receives signals for loading a response body.
 class ResponseBodyLoaderClient : public GarbageCollectedMixin {
  public:
-  ~ResponseBodyLoaderClient() = default;
+  virtual ~ResponseBodyLoaderClient() = default;
 
   // Called when reading a chunk, with the chunk.
   virtual void DidReceiveData(base::span<const char> data) = 0;
diff --git a/third_party/blink/renderer/platform/loader/fetch/response_body_loader_test.cc b/third_party/blink/renderer/platform/loader/fetch/response_body_loader_test.cc
index c5fe311..fb07c02 100644
--- a/third_party/blink/renderer/platform/loader/fetch/response_body_loader_test.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/response_body_loader_test.cc
@@ -36,7 +36,7 @@
 
     TestClient() : TestClient(Option::kNone) {}
     TestClient(Option option) : option_(option) {}
-    virtual ~TestClient() {}
+    ~TestClient() override {}
 
     String GetData() const { return data_; }
     bool LoadingIsFinished() const { return finished_; }
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 3bf30c9..a4ef2fe 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1120,10 +1120,6 @@
       status: "stable",
     },
     {
-      name: "PreloadImageSrcSet",
-      status: "stable",
-    },
-    {
       name: "Presentation",
       status: "stable",
     },
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 23d6a3a..aee2348 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
@@ -606,10 +606,13 @@
 
 void FrameSchedulerImpl::DidCommitProvisionalLoad(
     bool is_web_history_inert_commit,
-    bool is_reload,
-    bool is_main_frame) {
-  main_thread_scheduler_->DidCommitProvisionalLoad(is_web_history_inert_commit,
-                                                   is_reload, is_main_frame);
+    NavigationType navigation_type) {
+  bool is_main_frame = GetFrameType() == FrameType::kMainFrame;
+  if (is_main_frame && navigation_type != NavigationType::kSameDocument)
+    task_time_ = base::TimeDelta();
+  main_thread_scheduler_->DidCommitProvisionalLoad(
+      is_web_history_inert_commit, navigation_type == NavigationType::kReload,
+      is_main_frame);
 }
 
 WebScopedVirtualTimePauser FrameSchedulerImpl::CreateWebScopedVirtualTimePauser(
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h
index 706ada8..887ab89 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h
@@ -102,8 +102,7 @@
   PageScheduler* GetPageScheduler() const override;
   void DidStartProvisionalLoad(bool is_main_frame) override;
   void DidCommitProvisionalLoad(bool is_web_history_inert_commit,
-                                bool is_reload,
-                                bool is_main_frame) override;
+                                NavigationType navigation_type) override;
   WebScopedVirtualTimePauser CreateWebScopedVirtualTimePauser(
       const WTF::String& name,
       WebScopedVirtualTimePauser::VirtualTaskDuration duration) override;
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
index 50e6522..0e25125 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
@@ -12,6 +12,7 @@
 #include "base/metrics/field_trial_param_associator.h"
 #include "base/metrics/field_trial_params.h"
 #include "base/run_loop.h"
+#include "base/strings/stringprintf.h"
 #include "base/task/sequence_manager/test/sequence_manager_for_test.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/scoped_task_environment.h"
@@ -83,6 +84,14 @@
         FrameScheduler::FrameType::kSubframe);
   }
 
+  void ResetFrameScheduler(FrameScheduler::FrameType frame_type) {
+    frame_scheduler_delegate_ =
+        std::make_unique<FrameSchedulerDelegateForTesting>();
+    frame_scheduler_ = FrameSchedulerImpl::Create(
+        page_scheduler_.get(), frame_scheduler_delegate_.get(), nullptr,
+        frame_type);
+  }
+
   void TearDown() override {
     frame_scheduler_.reset();
     page_scheduler_.reset();
@@ -96,6 +105,10 @@
     return frame_scheduler_delegate_->update_task_time_calls_;
   }
 
+  void ResetTotalUpdateTaskTimeCalls() {
+    frame_scheduler_delegate_->update_task_time_calls_ = 0;
+  }
+
  protected:
   scoped_refptr<TaskQueue> throttleable_task_queue() {
     return throttleable_task_queue_;
@@ -171,6 +184,12 @@
     frame_scheduler_->DidChangeResourceLoadingPriority(task_queue, priority);
   }
 
+  void DidCommitProvisionalLoad(
+      FrameScheduler::NavigationType navigation_type) {
+    frame_scheduler_->DidCommitProvisionalLoad(
+        /*is_web_history_inert_commit=*/false, navigation_type);
+  }
+
   base::test::ScopedFeatureList& scoped_feature_list() { return feature_list_; }
 
   std::unique_ptr<base::FieldTrialList> field_trial_list_;
@@ -486,20 +505,64 @@
 }
 
 TEST_F(FrameSchedulerImplTest, PagePostsCpuTasks) {
-  DCHECK(GetTaskTime().is_zero());
-  DCHECK_EQ(GetTotalUpdateTaskTimeCalls(), 0);
+  EXPECT_TRUE(GetTaskTime().is_zero());
+  EXPECT_EQ(0, GetTotalUpdateTaskTimeCalls());
   UnpausableTaskQueue()->task_runner()->PostTask(
       FROM_HERE, base::BindOnce(&RunTaskOfLength, &task_environment_,
                                 base::TimeDelta::FromMilliseconds(10)));
   base::RunLoop().RunUntilIdle();
-  DCHECK(!GetTaskTime().is_zero());
-  DCHECK_EQ(GetTotalUpdateTaskTimeCalls(), 0);
+  EXPECT_FALSE(GetTaskTime().is_zero());
+  EXPECT_EQ(0, GetTotalUpdateTaskTimeCalls());
   UnpausableTaskQueue()->task_runner()->PostTask(
       FROM_HERE, base::BindOnce(&RunTaskOfLength, &task_environment_,
                                 base::TimeDelta::FromMilliseconds(100)));
   base::RunLoop().RunUntilIdle();
-  DCHECK(GetTaskTime().is_zero());
-  DCHECK_EQ(GetTotalUpdateTaskTimeCalls(), 1);
+  EXPECT_TRUE(GetTaskTime().is_zero());
+  EXPECT_EQ(1, GetTotalUpdateTaskTimeCalls());
+}
+
+TEST_F(FrameSchedulerImplTest, FramePostsCpuTasksThroughReloadRenavigate) {
+  const struct {
+    FrameScheduler::FrameType frame_type;
+    FrameScheduler::NavigationType navigation_type;
+    bool expect_task_time_zero;
+    int expected_total_calls;
+  } kTestCases[] = {{FrameScheduler::FrameType::kMainFrame,
+                     FrameScheduler::NavigationType::kOther, false, 0},
+                    {FrameScheduler::FrameType::kMainFrame,
+                     FrameScheduler::NavigationType::kReload, false, 0},
+                    {FrameScheduler::FrameType::kMainFrame,
+                     FrameScheduler::NavigationType::kSameDocument, true, 1},
+                    {FrameScheduler::FrameType::kSubframe,
+                     FrameScheduler::NavigationType::kOther, true, 1},
+                    {FrameScheduler::FrameType::kSubframe,
+                     FrameScheduler::NavigationType::kSameDocument, true, 1}};
+  for (const auto& test_case : kTestCases) {
+    SCOPED_TRACE(base::StringPrintf(
+        "FrameType: %d, NavigationType: %d : TaskTime.is_zero %d, CallCount %d",
+        test_case.frame_type, test_case.navigation_type,
+        test_case.expect_task_time_zero, test_case.expected_total_calls));
+    ResetFrameScheduler(test_case.frame_type);
+    EXPECT_TRUE(GetTaskTime().is_zero());
+    EXPECT_EQ(0, GetTotalUpdateTaskTimeCalls());
+
+    // Check the rest of the values after different types of commit.
+    UnpausableTaskQueue()->task_runner()->PostTask(
+        FROM_HERE, base::BindOnce(&RunTaskOfLength, &task_environment_,
+                                  base::TimeDelta::FromMilliseconds(60)));
+    base::RunLoop().RunUntilIdle();
+    EXPECT_FALSE(GetTaskTime().is_zero());
+    EXPECT_EQ(0, GetTotalUpdateTaskTimeCalls());
+
+    DidCommitProvisionalLoad(test_case.navigation_type);
+
+    UnpausableTaskQueue()->task_runner()->PostTask(
+        FROM_HERE, base::BindOnce(&RunTaskOfLength, &task_environment_,
+                                  base::TimeDelta::FromMilliseconds(60)));
+    base::RunLoop().RunUntilIdle();
+    EXPECT_EQ(test_case.expect_task_time_zero, GetTaskTime().is_zero());
+    EXPECT_EQ(test_case.expected_total_calls, GetTotalUpdateTaskTimeCalls());
+  }
 }
 
 TEST_F(FrameSchedulerImplTest, PageFreezeWithKeepActive) {
diff --git a/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h b/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h
index 567b0c3..c15e9d2e 100644
--- a/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h
+++ b/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h
@@ -46,6 +46,12 @@
     kSubframe,
   };
 
+  enum class NavigationType {
+    kReload,
+    kSameDocument,
+    kOther,
+  };
+
   // The scheduler may throttle tasks associated with offscreen frames.
   virtual void SetFrameVisible(bool) = 0;
   virtual bool IsFrameVisible() const = 0;
@@ -108,8 +114,7 @@
   // may reset the task cost estimators and the UserModel. Must be called from
   // the main thread.
   virtual void DidCommitProvisionalLoad(bool is_web_history_inert_commit,
-                                        bool is_reload,
-                                        bool is_main_frame) = 0;
+                                        NavigationType navigation_type) = 0;
 
   // Tells the scheduler that the first meaningful paint has occured for this
   // frame.
diff --git a/third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h b/third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h
index 70379c3..b4ee855 100644
--- a/third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h
+++ b/third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h
@@ -137,9 +137,9 @@
     return WebScopedVirtualTimePauser();
   }
   void DidStartProvisionalLoad(bool is_main_frame) override {}
-  void DidCommitProvisionalLoad(bool is_web_history_inert_commit,
-                                bool is_reload,
-                                bool is_main_frame) override {}
+  void DidCommitProvisionalLoad(
+      bool is_web_history_inert_commit,
+      FrameScheduler::NavigationType navigation_type) override {}
   void OnFirstMeaningfulPaint() override {}
   std::unique_ptr<ActiveConnectionHandle> OnActiveConnectionCreated() override {
     return nullptr;
diff --git a/third_party/blink/renderer/platform/scheduler/test/renderer_scheduler_test_support.cc b/third_party/blink/renderer/platform/scheduler/test/renderer_scheduler_test_support.cc
index 4af2a79..d2158d8 100644
--- a/third_party/blink/renderer/platform/scheduler/test/renderer_scheduler_test_support.cc
+++ b/third_party/blink/renderer/platform/scheduler/test/renderer_scheduler_test_support.cc
@@ -73,7 +73,8 @@
     return WebScopedVirtualTimePauser();
   }
   void DidStartProvisionalLoad(bool is_main_frame) override {}
-  void DidCommitProvisionalLoad(bool, bool, bool) override {}
+  void DidCommitProvisionalLoad(bool, FrameScheduler::NavigationType) override {
+  }
   void OnFirstMeaningfulPaint() override {}
   bool IsExemptFromBudgetBasedThrottling() const override { return false; }
   std::unique_ptr<blink::mojom::blink::PauseSubresourceLoadingHandle>
diff --git a/third_party/blink/renderer/platform/testing/url_test_helpers.cc b/third_party/blink/renderer/platform/testing/url_test_helpers.cc
index d694735..ba515d2e 100644
--- a/third_party/blink/renderer/platform/testing/url_test_helpers.cc
+++ b/third_party/blink/renderer/platform/testing/url_test_helpers.cc
@@ -69,7 +69,7 @@
   timing.Initialize();
 
   WebURLResponse response(full_url);
-  response.SetMIMEType(mime_type);
+  response.SetMimeType(mime_type);
   response.SetHTTPHeaderField(http_names::kContentType, mime_type);
   response.SetHttpStatusCode(200);
   response.SetLoadTiming(timing);
@@ -82,7 +82,7 @@
   timing.Initialize();
 
   WebURLResponse response;
-  response.SetMIMEType("image/png");
+  response.SetMimeType("image/png");
   response.SetHTTPHeaderField(http_names::kContentType, "image/png");
   response.SetHttpStatusCode(404);
   response.SetLoadTiming(timing);
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-features=NetworkService b/third_party/blink/web_tests/FlagExpectations/disable-features=NetworkService
index 8fa693f..f337c3c 100644
--- a/third_party/blink/web_tests/FlagExpectations/disable-features=NetworkService
+++ b/third_party/blink/web_tests/FlagExpectations/disable-features=NetworkService
@@ -11,7 +11,6 @@
 crbug.com/899303 http/tests/inspector-protocol/fetch/fetch-renderer.js [ Timeout ]
 crbug.com/917284 external/wpt/service-workers/service-worker/claim-fetch-with-appcache.https.html [ Failure ]
 crbug.com/917284 virtual/disabled-service-worker-servicification/external/wpt/service-workers/service-worker/claim-fetch-with-appcache.https.html [ Failure ]
-crbug.com/917284 virtual/outofblink-cors/external/wpt/service-workers/service-worker/claim-fetch-with-appcache.https.html [ Failure ]
 crbug.com/933880 external/wpt/FileAPI/url/cross-global-revoke.sub.html [ Failure ]
 crbug.com/933880 external/wpt/FileAPI/url/url-with-fetch.any.html [ Failure ]
 crbug.com/933880 external/wpt/FileAPI/url/url-with-xhr.any.html [ Failure ]
@@ -21,12 +20,6 @@
 # enabled this fails in both content_shell and chrome.
 Bug(none) http/tests/misc/redirect-to-about-blank.html [ Pass ]
 
-crbug.com/906959 virtual/outofblink-cors/external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/shared-worker/no-redirect/insecure-protocol.http.html [ Failure ]
-crbug.com/906959 virtual/outofblink-cors/external/wpt/referrer-policy/no-referrer/http-rp/same-origin/http-http/shared-worker/keep-origin-redirect/generic.http.html [ Failure ]
-crbug.com/906959 virtual/outofblink-cors/external/wpt/referrer-policy/no-referrer/http-rp/same-origin/http-http/shared-worker/no-redirect/generic.http.html [ Failure ]
-crbug.com/906959 virtual/outofblink-cors/external/wpt/referrer-policy/no-referrer/meta-referrer/same-origin/http-http/shared-worker/keep-origin-redirect/generic.http.html [ Failure ]
-crbug.com/906959 virtual/outofblink-cors/external/wpt/referrer-policy/no-referrer/meta-referrer/same-origin/http-http/shared-worker/no-redirect/generic.http.html [ Failure ]
-crbug.com/906959 virtual/outofblink-cors/http/tests/security/isolatedWorld/cross-origin-xhr.html [ Crash ]
-
 # The below is only supported with network service.
 Bug(none) virtual/omt-worker-fetch [ Skip ]
+Bug(none) virtual/outofblink-cors [ Skip ]
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
index f436816..418af10 100644
--- a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
@@ -185,6 +185,34 @@
 crbug.com/591099 external/wpt/css/css-text/line-breaking/line-breaking-ic-003.html [ Pass ]
 crbug.com/591099 external/wpt/css/css-text/overflow-wrap/overflow-wrap-anywhere-001.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-text/overflow-wrap/overflow-wrap-break-word-005.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping-000.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping-001.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping-002.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping-003.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping-004.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping-005.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping-006.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping-007.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping-008.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping-009.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping-010.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping-011.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping-014.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping-015.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping-016.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping-017.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping-018.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping-020.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping-021.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping-022.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping_cchar-000.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping_cchar-002.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping_cchar-003.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping_cchar-008.html [ Pass ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping_cchar-009.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping_cchar-010.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping_cchar-011.html [ Failure ]
+crbug.com/591099 external/wpt/css/css-text/shaping/shaping_lig-000.html [ Pass ]
 crbug.com/591099 external/wpt/css/css-text/text-indent/text-indent-percentage-004.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-text/text-transform/text-transform-capitalize-028.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-text/white-space/line-edge-white-space-collapse-001.html [ Pass ]
@@ -347,7 +375,7 @@
 crbug.com/591099 external/wpt/fetch/api/response/response-clone.html [ Pass ]
 crbug.com/591099 external/wpt/fetch/http-cache/cc-request.html [ Pass ]
 crbug.com/591099 external/wpt/fullscreen/api/element-ready-check-containing-iframe-manual.html [ Pass ]
-crbug.com/591099 external/wpt/fullscreen/api/element-request-fullscreen-and-remove-manual.html [ Pass ]
+crbug.com/591099 external/wpt/fullscreen/api/element-request-fullscreen-and-remove-manual.html [ Failure Pass ]
 crbug.com/591099 external/wpt/geolocation-API/PositionOptions.https.html [ Failure Pass ]
 crbug.com/591099 external/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects.html [ Crash ]
 crbug.com/591099 external/wpt/html/browsers/the-window-object/window-open-noopener.html?_parent [ Pass ]
@@ -360,6 +388,7 @@
 crbug.com/591099 external/wpt/html/semantics/links/links-created-by-a-and-area-elements/target_blank_implicit_noopener.tentative.html [ Pass Timeout ]
 crbug.com/591099 external/wpt/html/semantics/scripting-1/the-script-element/execution-timing/111.html [ Pass ]
 crbug.com/591099 external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/no-active-script-manual-module.html [ Timeout ]
+crbug.com/591099 external/wpt/html/user-activation/activation-transfer-with-click.tentative.html [ Pass ]
 crbug.com/591099 external/wpt/html/user-activation/activation-transfer-without-click.tentative.html [ Pass ]
 crbug.com/591099 external/wpt/infrastructure/reftest/size.html [ Pass ]
 crbug.com/591099 external/wpt/mediacapture-fromelement/ended.html [ Pass ]
@@ -429,7 +458,7 @@
 crbug.com/591099 fast/dom/SelectorAPI/resig-SelectorsAPI-test.xhtml [ Pass ]
 crbug.com/591099 fast/dom/shadow/focus-controller-recursion-crash.html [ Pass ]
 crbug.com/591099 fast/dom/shadow/svg-style-in-shadow-tree-crash.html [ Pass ]
-crbug.com/591099 fast/events/before-unload-return-value-from-listener.html [ Pass ]
+crbug.com/591099 fast/events/before-unload-return-value-from-listener.html [ Pass Timeout ]
 crbug.com/591099 fast/events/touch/compositor-touch-hit-rects-continuation.html [ Failure ]
 crbug.com/591099 fast/events/touch/compositor-touch-hit-rects-list-translate.html [ Failure ]
 crbug.com/591099 fast/events/touch/compositor-touch-hit-rects.html [ Failure ]
diff --git a/third_party/blink/web_tests/SmokeTests b/third_party/blink/web_tests/SmokeTests
index 0f38560..817f8a0 100644
--- a/third_party/blink/web_tests/SmokeTests
+++ b/third_party/blink/web_tests/SmokeTests
@@ -769,7 +769,6 @@
 fast/writing-mode/english-lr-text.html
 fast/writing-mode/flipped-blocks-outline-crash.html
 fast/writing-mode/percentage-padding.html
-fast/xmlhttprequest/xmlhttprequest-missing-file-exception.html
 fast/xmlhttprequest/xmlhttprequest-responseXML-invalid-xml.html
 fast/xmlhttprequest/xmlhttprequest-responseXML-xml-text-responsetype.html
 fast/xpath/nodeset-duplicates.html
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 383e622..693abf2c 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -3038,6 +3038,33 @@
 crbug.com/939181 virtual/not-site-per-process/external/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects.html [ Failure Timeout ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping-021.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping-001.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping_cchar-000.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping-018.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping_cchar-006.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping_cchar-002.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping_cchar-003.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping_cchar-008.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping-006.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping-000.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping_cchar-001.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping-020.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping-003.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping-002.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping-016.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping_cchar-005.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping_cchar-007.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping-022.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping_lig-000.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping-007.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping-005.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping-008.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping-004.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping-017.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping_cchar-004.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping-014.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-text/shaping/shaping-015.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-text/word-break/word-break-break-word-overflow-wrap-interactions.html [ Failure ]
 crbug.com/626703 external/wpt/css/css-sizing/range-percent-intrinsic-size-2a.html [ Failure ]
 crbug.com/626703 external/wpt/infrastructure/reftest/reftest_fuzzy.html [ Failure ]
@@ -5391,7 +5418,6 @@
 crbug.com/824539 [ Android ] fast/text/international/bidi-LDB-2-formatting-characters.html [ Failure ]
 crbug.com/824539 [ Android ] fast/text/international/bidi-neutral-directionality-paragraph-start.html [ Failure ]
 crbug.com/824539 [ Android ] fast/writing-mode/english-lr-text.html [ Failure ]
-crbug.com/824539 [ Android ] fast/xmlhttprequest/xmlhttprequest-missing-file-exception.html [ Failure ]
 crbug.com/824539 [ Android ] http/tests/plugins/navigator-plugins-in-cross-origin-frame.html [ Failure ]
 crbug.com/824539 [ Android ] http/tests/security/local-JavaScript-from-remote.html [ Crash Failure ]
 crbug.com/824539 [ Android ] virtual/outofblink-cors/http/tests/security/local-JavaScript-from-remote.html [ Crash Failure ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites
index d2b7391..20f7696 100644
--- a/third_party/blink/web_tests/VirtualTestSuites
+++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -456,47 +456,47 @@
   {
     "prefix": "outofblink-cors",
     "base": "external/wpt/fetch",
-    "args": ["--enable-features=OutOfBlinkCors,ServiceWorkerServicification"]
+    "args": ["--enable-features=OutOfBlinkCors,NetworkService"]
   },
   {
     "prefix": "outofblink-cors",
     "base": "external/wpt/http",
-    "args": ["--enable-features=OutOfBlinkCors,ServiceWorkerServicification"]
+    "args": ["--enable-features=OutOfBlinkCors,NetworkService"]
   },
   {
     "prefix": "outofblink-cors",
     "base": "external/wpt/referrer-policy",
-    "args": ["--enable-features=OutOfBlinkCors,ServiceWorkerServicification"]
+    "args": ["--enable-features=OutOfBlinkCors,NetworkService"]
   },
   {
     "prefix": "outofblink-cors",
     "base": "external/wpt/service-workers",
-    "args": ["--enable-features=OutOfBlinkCors,ServiceWorkerServicification"]
+    "args": ["--enable-features=OutOfBlinkCors,NetworkService"]
   },
   {
     "prefix": "outofblink-cors",
     "base": "external/wpt/xhr",
-    "args": ["--enable-features=OutOfBlinkCors,ServiceWorkerServicification"]
+    "args": ["--enable-features=OutOfBlinkCors,NetworkService"]
   },
   {
     "prefix": "outofblink-cors",
     "base": "http/tests/fetch",
-    "args": ["--enable-features=OutOfBlinkCors,ServiceWorkerServicification"]
+    "args": ["--enable-features=OutOfBlinkCors,NetworkService"]
   },
   {
     "prefix": "outofblink-cors",
     "base": "http/tests/navigation",
-    "args": ["--enable-features=OutOfBlinkCors,ServiceWorkerServicification"]
+    "args": ["--enable-features=OutOfBlinkCors,NetworkService"]
   },
   {
     "prefix": "outofblink-cors",
     "base": "http/tests/security",
-    "args": ["--enable-features=OutOfBlinkCors,ServiceWorkerServicification"]
+    "args": ["--enable-features=OutOfBlinkCors,NetworkService"]
   },
   {
     "prefix": "outofblink-cors",
     "base": "http/tests/xmlhttprequest",
-    "args": ["--enable-features=OutOfBlinkCors,ServiceWorkerServicification"]
+    "args": ["--enable-features=OutOfBlinkCors,NetworkService"]
   },
   {
     "prefix": "presentation",
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/element-in-template.html b/third_party/blink/web_tests/display-lock/lock-before-append/element-in-template.html
new file mode 100644
index 0000000..f7c9ef8
--- /dev/null
+++ b/third_party/blink/web_tests/display-lock/lock-before-append/element-in-template.html
@@ -0,0 +1,51 @@
+<!doctype HTML>
+
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+
+<style>
+  div {
+    contain: style layout;
+  }
+</style>
+
+<template id=template><div id="child">foo</div></template>
+<div id="container"></div>
+
+<script>
+
+async_test((t) => {
+
+  async function templateTest() {
+    const templateChild = template.content.firstChild;
+    t.step(() => assert_not_equals(templateChild.displayLock, null, "Can access displayLock on element in template"));
+
+    const acquirePromise = templateChild.displayLock.acquire({ timeout: Infinity });
+    await acquirePromise;
+    t.step(() => assert_true(templateChild.displayLock.locked, "Can lock element in template"));
+
+    const adoptedNode = document.adoptNode(templateChild);
+    t.step(() => assert_true(adoptedNode.displayLock.locked, "Adopted element is still locked"));
+
+    container.appendChild(adoptedNode);
+    t.step(() => assert_true(adoptedNode.displayLock.locked, "Still locked after appended"));
+
+    await adoptedNode.displayLock.commit();
+    t.step(() => assert_false(adoptedNode.displayLock.locked, "Can commit"));
+
+    await adoptedNode.displayLock.acquire({ timeout: Infinity });
+
+    t.step(() => assert_true(adoptedNode.displayLock.locked, "Can re-lock element"));
+
+    await adoptedNode.displayLock.commit();
+    t.step(() => assert_false(adoptedNode.displayLock.locked, "Can re-commit element"));
+
+    t.done();
+  }
+
+  window.onload = function() {
+    requestAnimationFrame(() => requestAnimationFrame(templateTest));
+  };
+}, "Testing locking element in templates");
+
+</script>
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
index 5d89f469..6341de8e 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
@@ -64155,6 +64155,426 @@
      {}
     ]
    ],
+   "css/css-text/shaping/shaping-000.html": [
+    [
+     "/css/css-text/shaping/shaping-000.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping-000-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping-001.html": [
+    [
+     "/css/css-text/shaping/shaping-001.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping-002.html": [
+    [
+     "/css/css-text/shaping/shaping-002.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping-002-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping-003.html": [
+    [
+     "/css/css-text/shaping/shaping-003.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping-003-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping-004.html": [
+    [
+     "/css/css-text/shaping/shaping-004.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping-004-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping-005.html": [
+    [
+     "/css/css-text/shaping/shaping-005.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping-005-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping-006.html": [
+    [
+     "/css/css-text/shaping/shaping-006.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping-006-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping-007.html": [
+    [
+     "/css/css-text/shaping/shaping-007.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping-007-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping-008.html": [
+    [
+     "/css/css-text/shaping/shaping-008.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping-008-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping-009.html": [
+    [
+     "/css/css-text/shaping/shaping-009.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping-009-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping-010.html": [
+    [
+     "/css/css-text/shaping/shaping-010.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping-010-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping-011.html": [
+    [
+     "/css/css-text/shaping/shaping-011.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping-011-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping-012.html": [
+    [
+     "/css/css-text/shaping/shaping-012.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping-012-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping-013.html": [
+    [
+     "/css/css-text/shaping/shaping-013.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping-012-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping-014.html": [
+    [
+     "/css/css-text/shaping/shaping-014.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping-014-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping-015.html": [
+    [
+     "/css/css-text/shaping/shaping-015.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping-015-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping-016.html": [
+    [
+     "/css/css-text/shaping/shaping-016.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping-016-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping-017.html": [
+    [
+     "/css/css-text/shaping/shaping-017.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping-017-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping-018.html": [
+    [
+     "/css/css-text/shaping/shaping-018.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping-018-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping-020.html": [
+    [
+     "/css/css-text/shaping/shaping-020.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping-020-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping-021.html": [
+    [
+     "/css/css-text/shaping/shaping-021.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping-021-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping-022.html": [
+    [
+     "/css/css-text/shaping/shaping-022.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping-022-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping_cchar-000.html": [
+    [
+     "/css/css-text/shaping/shaping_cchar-000.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping_cchar-000-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping_cchar-001.html": [
+    [
+     "/css/css-text/shaping/shaping_cchar-001.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping_cchar-001-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping_cchar-002.html": [
+    [
+     "/css/css-text/shaping/shaping_cchar-002.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping_cchar-002-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping_cchar-003.html": [
+    [
+     "/css/css-text/shaping/shaping_cchar-003.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping_cchar-003-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping_cchar-004.html": [
+    [
+     "/css/css-text/shaping/shaping_cchar-004.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping_cchar-004-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping_cchar-005.html": [
+    [
+     "/css/css-text/shaping/shaping_cchar-005.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping_cchar-005-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping_cchar-006.html": [
+    [
+     "/css/css-text/shaping/shaping_cchar-006.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping_cchar-006-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping_cchar-007.html": [
+    [
+     "/css/css-text/shaping/shaping_cchar-007.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping_cchar-007-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping_cchar-008.html": [
+    [
+     "/css/css-text/shaping/shaping_cchar-008.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping_cchar-008-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping_cchar-009.html": [
+    [
+     "/css/css-text/shaping/shaping_cchar-009.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping_cchar-009-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping_cchar-010.html": [
+    [
+     "/css/css-text/shaping/shaping_cchar-010.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping_cchar-010-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping_cchar-011.html": [
+    [
+     "/css/css-text/shaping/shaping_cchar-011.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping_cchar-011-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping_lig-000.html": [
+    [
+     "/css/css-text/shaping/shaping_lig-000.html",
+     [
+      [
+       "/css/css-text/shaping/reference/shaping_lig-000-ref.html",
+       "=="
+      ]
+     ],
+     {}
+    ]
+   ],
    "css/css-text/tab-size/tab-min-rendered-width-1.html": [
     [
      "/css/css-text/tab-size/tab-min-rendered-width-1.html",
@@ -145402,6 +145822,181 @@
      {}
     ]
    ],
+   "css/css-text/shaping/reference/shaping-000-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping-001-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping-002-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping-003-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping-004-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping-005-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping-006-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping-007-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping-008-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping-009-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping-010-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping-011-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping-012-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping-013-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping-014-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping-015-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping-016-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping-017-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping-018-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping-020-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping-021-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping-022-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping_cchar-000-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping_cchar-001-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping_cchar-002-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping_cchar-003-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping_cchar-004-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping_cchar-005-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping_cchar-006-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping_cchar-007-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping_cchar-008-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping_cchar-009-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping_cchar-010-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping_cchar-011-ref.html": [
+    [
+     {}
+    ]
+   ],
+   "css/css-text/shaping/reference/shaping_lig-000-ref.html": [
+    [
+     {}
+    ]
+   ],
    "css/css-text/support/1x1-green.png": [
     [
      {}
@@ -172602,6 +173197,26 @@
      {}
     ]
    ],
+   "html/semantics/forms/form-submission-target/rel-base-target-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "html/semantics/forms/form-submission-target/rel-button-target-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "html/semantics/forms/form-submission-target/rel-form-target-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "html/semantics/forms/form-submission-target/rel-input-target-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "html/semantics/forms/form-submission-target/resources/endpoint.html": [
     [
      {}
@@ -180052,6 +180667,16 @@
      {}
     ]
    ],
+   "portals/resources/portals-nested-1.html": [
+    [
+     {}
+    ]
+   ],
+   "portals/resources/portals-nested-2.html": [
+    [
+     {}
+    ]
+   ],
    "portals/resources/portals-rendering-portal.html": [
     [
      {}
@@ -274991,6 +275616,12 @@
      {}
     ]
    ],
+   "portals/portals-nested.html": [
+    [
+     "/portals/portals-nested.html",
+     {}
+    ]
+   ],
    "portals/portals-no-referrer.html": [
     [
      "/portals/portals-no-referrer.html",
@@ -294271,6 +294902,12 @@
      {}
     ]
    ],
+   "webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiobuffersource-null.html": [
+    [
+     "/webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiobuffersource-null.html",
+     {}
+    ]
+   ],
    "webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiobuffersource-one-sample-loop.html": [
     [
      "/webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiobuffersource-one-sample-loop.html",
@@ -307927,6 +308564,24 @@
      {}
     ]
    ],
+   "css/css-text/shaping/shaping-023.html": [
+    [
+     "/css/css-text/shaping/shaping-023.html",
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping-024.html": [
+    [
+     "/css/css-text/shaping/shaping-024.html",
+     {}
+    ]
+   ],
+   "css/css-text/shaping/shaping-025.html": [
+    [
+     "/css/css-text/shaping/shaping-025.html",
+     {}
+    ]
+   ],
    "css/css-text/text-align/text-align-end-018.html": [
     [
      "/css/css-text/text-align/text-align-end-018.html",
@@ -373014,6 +373669,298 @@
    "ce5731551aec95f08df44f15ea6491045d14b235",
    "testharness"
   ],
+  "css/css-text/shaping/reference/shaping-000-ref.html": [
+   "62c8b500aaf097e0fb61f87b382ec4e5e0a4dd7e",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping-001-ref.html": [
+   "d9465300dfe26673eedf02c7a858c20f53f6ee42",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping-002-ref.html": [
+   "96d3c1ffdd84f37d2d0643bafc02d4447334c4b0",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping-003-ref.html": [
+   "4143f916dcd49f7618d207e116b5928ed5ad4de8",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping-004-ref.html": [
+   "263f279bec7bc9f36803b55f3166eb472f3e5be4",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping-005-ref.html": [
+   "9614f5d315c89c363613d2abb9cd43a881e1ce4c",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping-006-ref.html": [
+   "1a265c4320c892eb02fd9bd9a397c3596714a66e",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping-007-ref.html": [
+   "8021eb99070ab4d305e6ce8e897c5023e6f4a130",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping-008-ref.html": [
+   "4e47e4763ed75c90c790afdb33541b75f58ffc11",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping-009-ref.html": [
+   "bcdd7acbb682cea6658a4a326e66b7bd70448e8b",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping-010-ref.html": [
+   "98416e98a7c32e48ad503e35f17a5bf69376d3b6",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping-011-ref.html": [
+   "b4bd94222108e728d57b46eb8af4a170507adc77",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping-012-ref.html": [
+   "c00fd2cb832e0b3a8cb34f41c9c358eb5e2713cd",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping-013-ref.html": [
+   "199aeb9870f20c05fc1e5ba048d51a128f764e58",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping-014-ref.html": [
+   "1d08b44ed2f516fe4e110609b674e54565ed1a7d",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping-015-ref.html": [
+   "2269909e4aee2749c19fd761baecf22528b50cb7",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping-016-ref.html": [
+   "5fa5cd093903b1f234acd5fae97b99ad487ecaa4",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping-017-ref.html": [
+   "94ffc829ab4b0877e01b5737d117b63ab3ec428c",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping-018-ref.html": [
+   "b53c5aeb8d95f91159adf379ca35d1cf0fb27716",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping-020-ref.html": [
+   "b95a6d57342fdf9906a225006076089a3433a369",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping-021-ref.html": [
+   "f3b45a1377c6dc4279b02f9e413bde5543a79d4a",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping-022-ref.html": [
+   "b0f60a57dd54bbe622d8eeb992be75ebd92bfd64",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping_cchar-000-ref.html": [
+   "62df53aae2c732c14168765b0096a5211887c1df",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping_cchar-001-ref.html": [
+   "28f2d0ad063f6dad6839b7ffd3bdbe144ed8bf53",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping_cchar-002-ref.html": [
+   "e46a4663051d095836d7b53dba30520c5b38f4fc",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping_cchar-003-ref.html": [
+   "835ad521fd0abf84ad0ce0808ae8dcded00110d1",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping_cchar-004-ref.html": [
+   "5ec1500dde88cdb66071ba35765bb16b17e878b8",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping_cchar-005-ref.html": [
+   "4d83cf6ec0978c70d21b3f3de376672b3ac02c03",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping_cchar-006-ref.html": [
+   "3a293849849ae24530bb1a71e97d546afcbb5eb6",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping_cchar-007-ref.html": [
+   "950ef6457cdef75cd4b90693c677c3780ec4d7c4",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping_cchar-008-ref.html": [
+   "0e54de5098dbeb967393e4a4a9fb339658aea5e1",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping_cchar-009-ref.html": [
+   "9470b65ea508a8e94f453aa7b5fc04f4d5b4ed7c",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping_cchar-010-ref.html": [
+   "59f02a8d5589a135ce3d1112df79ae2ceaa31fdf",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping_cchar-011-ref.html": [
+   "83a5139a21af44465a45768539294a31cab91ba4",
+   "support"
+  ],
+  "css/css-text/shaping/reference/shaping_lig-000-ref.html": [
+   "7b92b83625b3800d3791efbe1248d8cc5ca2beb0",
+   "support"
+  ],
+  "css/css-text/shaping/shaping-000.html": [
+   "6a56c09064d929157693c37908e4ad78b6bd39e8",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping-001.html": [
+   "5c5ac1a0cd48b46388042625f79a3d1b1a3ac432",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping-002.html": [
+   "f4b4122bf56a634fec829cb61ed9bbc51780d059",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping-003.html": [
+   "3cc4b3dfc3f20e961e85dac6bad2130f582f74d6",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping-004.html": [
+   "3b7d1724e5cc7507a28d185d5cf659a07b4b4e8a",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping-005.html": [
+   "2ef446f6c5a21c05153118af4ddfc821c25a8642",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping-006.html": [
+   "5fad09bc317e5b238de3fc746e0e07e2cbe921cb",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping-007.html": [
+   "33a81b6df1a94483c9155b7b41339dfcd2517d0d",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping-008.html": [
+   "f7f1fad60358071dcab584d186727d975b85fdc5",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping-009.html": [
+   "979e5fd59066beb60ca33c793d0a770719f40e5d",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping-010.html": [
+   "02f7ce38bc936a20cbc86035d0331f1e8e62ba22",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping-011.html": [
+   "a2316f5487767e3fab817efa12f5f831a30449e0",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping-012.html": [
+   "6bc26206d32c32a1376543b89f4820bb6c2b1328",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping-013.html": [
+   "a4b55b22c267f15687bea91dadc7ee46b83df0dd",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping-014.html": [
+   "100a7d788598662021859ec5c83dcbc5f8a574f4",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping-015.html": [
+   "fcbc44a57dd913a8df113050a96b4f47938e4218",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping-016.html": [
+   "da3246215f96f8d6681b294bd33baaceb3d26915",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping-017.html": [
+   "cb1acef205f2d5d200f0d056f0a5902f016a2d3d",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping-018.html": [
+   "a4b69e964351b6a1180cb2d98fc1705a10f4b8a5",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping-020.html": [
+   "10f612c3a257c9e786b3252d32830bdfe5bd2b07",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping-021.html": [
+   "53201685edbadeb1e188af27e5bd57b57048bcf6",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping-022.html": [
+   "06dde6f370c62525ac5f085cf6eac5ff201a1af4",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping-023.html": [
+   "4ab0c1b31a744ab2121f9a9ff18564535588993f",
+   "visual"
+  ],
+  "css/css-text/shaping/shaping-024.html": [
+   "306ce43663d340627cc0bdca04cfd2a8a3d56956",
+   "visual"
+  ],
+  "css/css-text/shaping/shaping-025.html": [
+   "0c08600bfc4b9c7cc34ba9e88b6e5f8802faaaa6",
+   "visual"
+  ],
+  "css/css-text/shaping/shaping_cchar-000.html": [
+   "62490a2b48a250b1cc79ef96db613032475223f5",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping_cchar-001.html": [
+   "48ab60a20c85b3c9be263cb986a80f5cb4e84fdd",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping_cchar-002.html": [
+   "5885743d9088927f3cbf45c5a470f7681dfe3707",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping_cchar-003.html": [
+   "32f40dd45edcd938a9a2f9218ba4a7717894381f",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping_cchar-004.html": [
+   "2b24475031e6879564aaee9607f1bf573ae98e8e",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping_cchar-005.html": [
+   "8454d4ea0541e2e380bb862b1f3e3a2b2e6352c5",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping_cchar-006.html": [
+   "5f36e7dde57067b4c50792b54dcd2f8815397304",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping_cchar-007.html": [
+   "bd9e44e660997f80bef03de1676170b0fce22583",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping_cchar-008.html": [
+   "17295db5234904d2313f3b2b3fa31b25c9f5bd19",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping_cchar-009.html": [
+   "e17218d29a8822830656d11683f9947640b2aa5b",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping_cchar-010.html": [
+   "0f9d8a4c1fd56061eab3474a3f729d0b37ed1a2f",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping_cchar-011.html": [
+   "8ab7606d9ceb5d6a211a1ff708dc0cd6fcc1c861",
+   "reftest"
+  ],
+  "css/css-text/shaping/shaping_lig-000.html": [
+   "6b918350596637ad77c7899558e842d3bdff1354",
+   "reftest"
+  ],
   "css/css-text/support/1x1-green.png": [
    "b98ca0ba0a03c580ac339e4a3653539cfa8edc71",
    "support"
@@ -425414,18 +426361,34 @@
    "f37bc33f6f93ca94940ffeb0066945eb9aa020ee",
    "testharness"
   ],
+  "html/semantics/forms/form-submission-target/rel-base-target-expected.txt": [
+   "6d848622efe8cf1ac7a49ac1f458517e51147db8",
+   "support"
+  ],
   "html/semantics/forms/form-submission-target/rel-base-target.html": [
    "222be95d2e8a9da39525fbf6d8048e6cdfd7a982",
    "testharness"
   ],
+  "html/semantics/forms/form-submission-target/rel-button-target-expected.txt": [
+   "c2ff926d578885e946f148903c330ac2a878e380",
+   "support"
+  ],
   "html/semantics/forms/form-submission-target/rel-button-target.html": [
    "76fa8685905ad233f9312be3f6bf09503158a666",
    "testharness"
   ],
+  "html/semantics/forms/form-submission-target/rel-form-target-expected.txt": [
+   "88e33b90d9131401e3e53638d311198e3ff3ae2c",
+   "support"
+  ],
   "html/semantics/forms/form-submission-target/rel-form-target.html": [
    "58611f41a9fdaea1611513e02dad87e017728f9a",
    "testharness"
   ],
+  "html/semantics/forms/form-submission-target/rel-input-target-expected.txt": [
+   "b67908139dc6327eabc12a1a5da4b6f4c61de6eb",
+   "support"
+  ],
   "html/semantics/forms/form-submission-target/rel-input-target.html": [
    "b80e0240bae3802b04118249ec2b94e16a91e9e6",
    "testharness"
@@ -446634,6 +447597,10 @@
    "e0f1d63743c54c687d62f86abe278873fa823430",
    "testharness"
   ],
+  "portals/portals-nested.html": [
+   "26b264ee0509844141b9e8e4ae6999fa20ba04ef",
+   "testharness"
+  ],
   "portals/portals-no-referrer.html": [
    "0386272f441a0c2e19452821968a624d3ab16700",
    "testharness"
@@ -446682,6 +447649,14 @@
    "5db75d5b5fd5c12d5a77181ee1cac48f76657a57",
    "support"
   ],
+  "portals/resources/portals-nested-1.html": [
+   "f558e510f51517cf81ea9e2b1b30fa963cffb68a",
+   "support"
+  ],
+  "portals/resources/portals-nested-2.html": [
+   "e8a2322cabd7fb0fa1debd4b2a0c06c9d1034f70",
+   "support"
+  ],
   "portals/resources/portals-rendering-portal.html": [
    "1b6f23f512da5bb7d1c7b5b85e48277470d2e146",
    "support"
@@ -472634,6 +473609,10 @@
    "4e0de21e96fa8470f5305d9405bdccf8f937e660",
    "testharness"
   ],
+  "webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiobuffersource-null.html": [
+   "b5b1ec0c3db2f02557d0be7f7c2d6499ea3ae8a7",
+   "testharness"
+  ],
   "webaudio/the-audio-api/the-audiobuffersourcenode-interface/audiobuffersource-one-sample-loop.html": [
    "af1454a5a9f4644058c71715de7541e4800d2feb",
    "testharness"
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-000-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-000-ref.html
new file mode 100644
index 0000000..62c8b50
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-000-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: span</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span>&zwj;ع&zwj;</span>&zwj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span>&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-001-ref.html
new file mode 100644
index 0000000..d946530
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-001-ref.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: colour</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.color { color:blue; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="color">&zwj;ع&zwj;</span>&zwj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="color">&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-002-ref.html
new file mode 100644
index 0000000..96d3c1f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-002-ref.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: font-weight</title>
+<style type="text/css">
+@font-face {
+	font-family: 'csstest_noto';
+	src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+	font-weight: normal;
+	font-style: normal;
+	}
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.fontweight { font-weight: bold; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="fontweight">&zwj;ع&zwj;</span>&zwj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="fontweight">&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-003-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-003-ref.html
new file mode 100644
index 0000000..4143f91
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-003-ref.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: font-style</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.fontstyle { font-style: italic; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="fontstyle">&zwj;ع&zwj;</span>&zwj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="fontstyle">&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-004-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-004-ref.html
new file mode 100644
index 0000000..263f279
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-004-ref.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: margin 0</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.margin { margin:0; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="margin">&zwj;ع&zwj;</span>&zwj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="margin">&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-005-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-005-ref.html
new file mode 100644
index 0000000..9614f5d3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-005-ref.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: padding 0</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.padding { padding:0; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="padding">&zwj;ع&zwj;</span>&zwj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="padding">&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-006-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-006-ref.html
new file mode 100644
index 0000000..1a265c4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-006-ref.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: border 0</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.margin { margin:0; }
+.padding { padding:0; }
+.border { border:0; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="border">&zwj;ع&zwj;</span>&zwj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="border">&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-007-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-007-ref.html
new file mode 100644
index 0000000..8021eb9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-007-ref.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: font size 100%</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.fontsize { font-size:100%; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="fontsize">&zwj;ع&zwj;</span>&zwj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="fontsize">&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-008-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-008-ref.html
new file mode 100644
index 0000000..4e47e476
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-008-ref.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: font size 120%</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.fontsizeplus { font-size:120%; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="fontsizeplus">&zwj;ع&zwj;</span>&zwj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="fontsizeplus">&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-009-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-009-ref.html
new file mode 100644
index 0000000..bcdd7ac
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-009-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: margin &gt; 0</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.margin { margin: 0.5em; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters DON'T join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+<div class="ref" lang="ar" dir="rtl">ع&zwnj;<span class="margin">&zwnj;ع&zwnj;</span>&zwnj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwnj;<span class="margin">&zwnj;ع&zwnj;</span>&zwnj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-010-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-010-ref.html
new file mode 100644
index 0000000..98416e98
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-010-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: padding &gt; 0</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.padding { padding: 0.5em; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters DON'T join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+<div class="ref" lang="ar" dir="rtl">ع&zwnj;<span class="padding">&zwnj;ع&zwnj;</span>&zwnj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwnj;<span class="padding">&zwnj;ع&zwnj;</span>&zwnj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-011-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-011-ref.html
new file mode 100644
index 0000000..b4bd9422
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-011-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: border &gt; 0</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.border { border: 1px solid #ccc; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters DON'T join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+<div class="ref" lang="ar" dir="rtl">ع&zwnj;<span class="border">&zwnj;ع&zwnj;</span>&zwnj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwnj;<span class="border">&zwnj;ع&zwnj;</span>&zwnj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-012-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-012-ref.html
new file mode 100644
index 0000000..c00fd2c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-012-ref.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: isolation, bdi</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters DON'T join.</p>
+<p><small>Skip if markup alone breaks the join (test shaping-000)</small><br/>
+<small>Skip this test if bdi and dir=auto don't produce isolation in this browser.</small></p>
+<div class="ref" lang="ar" dir="rtl">ع&zwnj;<bdi>&zwnj;ع&zwnj;</bdi>&zwnj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwnj;<bdi>&zwnj;ع&zwnj;</bdi>&zwnj;ع</div>
+<!-- Notes:
+This test only works if bdi and dir=auto are supported by the browser.
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-013-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-013-ref.html
new file mode 100644
index 0000000..199aeb98
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-013-ref.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: isolation, auto</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters DON'T join.</p>
+<p><small>Skip if markup alone breaks the join (test shaping-000)</small><br/>
+<small>Skip this test if bdi and dir=auto don't produce isolation in this browser.</small></p>
+<div class="ref" lang="ar" dir="rtl">ع&zwnj;<bdi>&zwnj;ع&zwnj;</bdi>&zwnj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwnj;<bdi>&zwnj;ع&zwnj;</bdi>&zwnj;ع</div>
+<!-- Notes:
+This test only works if bdi and dir=auto are supported by the browser.
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-014-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-014-ref.html
new file mode 100644
index 0000000..1d08b44
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-014-ref.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: text-decoration</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+.styled { text-decoration: underline; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if both boxes look the same.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;ع&zwj;</span>&zwj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-015-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-015-ref.html
new file mode 100644
index 0000000..2269909
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-015-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: text-decoration</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { text-decoration: underline; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;ع&zwj;</span>&zwj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-016-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-016-ref.html
new file mode 100644
index 0000000..5fa5cd0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-016-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: outline</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { outline: 1px solid blue; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;ع&zwj;</span>&zwj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-017-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-017-ref.html
new file mode 100644
index 0000000..94ffc829a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-017-ref.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: em element</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { font-style: italic; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if both boxes look the same.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<em>&zwj;ع&zwj;</em>&zwj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+It also assumes that the default rendering for the em element is italic.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-018-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-018-ref.html
new file mode 100644
index 0000000..b53c5aeb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-018-ref.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: b element</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { font-weight: bold; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<b>&zwj;ع&zwj;</b>&zwj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+It also assumes that the default rendering for the b element is bold.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-020-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-020-ref.html
new file mode 100644
index 0000000..b95a6d57
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-020-ref.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>n'ko, colour</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoSansNko-regular-webfont.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { color:blue; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three N'Ko characters join.</p>
+<div class="ref" lang="nqo" dir="rtl">ߞ&zwj;<span class="styled">&zwj;ߞ&zwj;</span>&zwj;ߞ</div>
+<div class="ref" lang="nqo" dir="rtl">ߞ&zwj;<span class="styled">&zwj;ߞ&zwj;</span>&zwj;ߞ</div>
+<!-- Notes:
+This test uses the Noto Sans N'Ko font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-021-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-021-ref.html
new file mode 100644
index 0000000..f3b45a1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-021-ref.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>n'ko, font-style</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoSansNko-regular-webfont.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { font-style:italic; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three N'Ko characters join.</p>
+<div class="ref" lang="nqo" dir="rtl">ߞ&zwj;<span class="styled">&zwj;ߞ&zwj;</span>&zwj;ߞ</div>
+<div class="ref" lang="nqo" dir="rtl">ߞ&zwj;<span class="styled">&zwj;ߞ&zwj;</span>&zwj;ߞ</div>
+<!-- Notes:
+This test uses the Noto Sans N'Ko font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-022-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-022-ref.html
new file mode 100644
index 0000000..b0f60a5
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping-022-ref.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>n'ko, text-decoration</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoSansNko-regular-webfont.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { text-decoration: underline; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three N'Ko characters join.</p>
+<div class="ref" lang="nqo" dir="rtl">ߞ&zwj;<span class="styled">&zwj;ߞ&zwj;</span>&zwj;ߞ</div>
+<div class="ref" lang="nqo" dir="rtl">ߞ&zwj;<span class="styled">&zwj;ߞ&zwj;</span>&zwj;ߞ</div>
+<!-- Notes:
+This test uses the Noto Sans N'Ko font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-000-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-000-ref.html
new file mode 100644
index 0000000..62df53aae
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-000-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>marked up diacritic: span</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the Arabic base characters in each word join.</p>
+<div class="ref" lang="ar" dir="rtl">ع&#x064E;ع ع&#x0651;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&#x064E;ع ع&#x0651;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-001-ref.html
new file mode 100644
index 0000000..28f2d0a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-001-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>styled diacritic: colour</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { color:blue; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the Arabic base characters in each word join.</p>
+<p><small>Skip if markup alone breaks the join (test shaping_cchar-000)</small></p>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;&#x064E;&zwj;</span>&zwj;ع ع&zwj;<span class="styled">&zwj;&#x0651;&zwj;</span>&zwj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;&#x064E;&zwj;</span>&zwj;ع ع&zwj;<span class="styled">&zwj;&#x0651;&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-002-ref.html
new file mode 100644
index 0000000..e46a466
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-002-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>styled diacritic: font-weight</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { font-weight: bold; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the Arabic base characters in each word join.</p>
+<p><small>Skip if markup alone breaks the join (test shaping_cchar-000)</small><br/>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;&#x064E;&zwj;</span>&zwj;ع ع&zwj;<span class="styled">&zwj;&#x0651;&zwj;</span>&zwj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;&#x064E;&zwj;</span>&zwj;ع ع&zwj;<span class="styled">&zwj;&#x0651;&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-003-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-003-ref.html
new file mode 100644
index 0000000..835ad521
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-003-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>styled diacritic: font-style</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { font-style: italic; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the Arabic base characters in each word join.</p>
+<p><small>Skip if markup alone breaks the join (test shaping_cchar-000)</small><br/>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;&#x064E;&zwj;</span>&zwj;ع ع&zwj;<span class="styled">&zwj;&#x0651;&zwj;</span>&zwj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;&#x064E;&zwj;</span>&zwj;ع ع&zwj;<span class="styled">&zwj;&#x0651;&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-004-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-004-ref.html
new file mode 100644
index 0000000..5ec1500
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-004-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>styled diacritic: margin 0</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { margin:0; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the Arabic base characters in each word join.</p>
+<p><small>Skip if markup alone breaks the join (test shaping_cchar-000)</small><br/>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;&#x064E;&zwj;</span>&zwj;ع ع&zwj;<span class="styled">&zwj;&#x0651;&zwj;</span>&zwj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;&#x064E;&zwj;</span>&zwj;ع ع&zwj;<span class="styled">&zwj;&#x0651;&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-005-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-005-ref.html
new file mode 100644
index 0000000..4d83cf6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-005-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>styled diacritic: padding 0</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { padding:0; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the Arabic base characters in each word join.</p>
+<p><small>Skip if markup alone breaks the join (test shaping_cchar-000)</small><br/>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;&#x064E;&zwj;</span>&zwj;ع ع&zwj;<span class="styled">&zwj;&#x0651;&zwj;</span>&zwj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;&#x064E;&zwj;</span>&zwj;ع ع&zwj;<span class="styled">&zwj;&#x0651;&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-006-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-006-ref.html
new file mode 100644
index 0000000..3a293849
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-006-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>styled diacritic: border 0</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { border:0; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the Arabic base characters in each word join.</p>
+<p><small>Skip if markup alone breaks the join (test shaping_cchar-000)</small><br/>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;&#x064E;&zwj;</span>&zwj;ع ع&zwj;<span class="styled">&zwj;&#x0651;&zwj;</span>&zwj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;&#x064E;&zwj;</span>&zwj;ع ع&zwj;<span class="styled">&zwj;&#x0651;&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-007-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-007-ref.html
new file mode 100644
index 0000000..950ef64
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-007-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>styled diacritic: font size 100%</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { font-size:100%; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the Arabic base characters in each word join.</p>
+<p><small>Skip if markup alone breaks the join (test shaping_cchar-000)</small><br/>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;&#x064E;&zwj;</span>&zwj;ع ع&zwj;<span class="styled">&zwj;&#x0651;&zwj;</span>&zwj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;&#x064E;&zwj;</span>&zwj;ع ع&zwj;<span class="styled">&zwj;&#x0651;&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-008-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-008-ref.html
new file mode 100644
index 0000000..0e54de5
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-008-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>styled diacritic: font size 120%</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { font-size:120%; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the Arabic base characters in each word join.</p>
+<p><small>Skip if markup alone breaks the join (test shaping_cchar-000)</small><br/>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;&#x064E;&zwj;</span>&zwj;ع ع&zwj;<span class="styled">&zwj;&#x0651;&zwj;</span>&zwj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;&#x064E;&zwj;</span>&zwj;ع ع&zwj;<span class="styled">&zwj;&#x0651;&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-009-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-009-ref.html
new file mode 100644
index 0000000..9470b65ea
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-009-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>styled diacritic: margin &gt; 0</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 5em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { margin: 0.5em; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the Arabic characters DON'T show joining forms.</p>
+<p><small>Skip if markup alone breaks the join (test shaping_cchar-000)</small><br/>
+<div class="ref" lang="ar" dir="rtl">ع&zwnj;<span class="styled">&zwnj;&#x064E;&zwnj;</span>&zwnj;ع ع&zwnj;<span class="styled">&zwnj;&#x0651;&zwnj;</span>&zwnj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwnj;<span class="styled">&zwnj;&#x064E;&zwnj;</span>&zwnj;ع ع&zwnj;<span class="styled">&zwnj;&#x0651;&zwnj;</span>&zwnj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-010-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-010-ref.html
new file mode 100644
index 0000000..59f02a8d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-010-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>styled diacritic: padding &gt; 0</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 5em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { padding: 0.5em; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the Arabic characters DON'T show joining forms.</p>
+<p><small>Skip if markup alone breaks the join (test shaping_cchar-000)</small><br/>
+<div class="ref" lang="ar" dir="rtl">ع&zwnj;<span class="styled">&zwnj;&#x064E;&zwnj;</span>&zwnj;ع ع&zwnj;<span class="styled">&zwnj;&#x0651;&zwnj;</span>&zwnj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwnj;<span class="styled">&zwnj;&#x064E;&zwnj;</span>&zwnj;ع ع&zwnj;<span class="styled">&zwnj;&#x0651;&zwnj;</span>&zwnj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-011-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-011-ref.html
new file mode 100644
index 0000000..83a5139a2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_cchar-011-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>styled diacritic: border &gt; 0</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 5em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { border: 1px solid #ccc; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the Arabic characters DON'T show joining forms.</p>
+<p><small>Skip if markup alone breaks the join (test shaping_cchar-000)</small><br/>
+<div class="ref" lang="ar" dir="rtl">ع&zwnj;<span class="styled">&zwnj;&#x064E;&zwnj;</span>&zwnj;ع ع&zwnj;<span class="styled">&zwnj;&#x0651;&zwnj;</span>&zwnj;ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwnj;<span class="styled">&zwnj;&#x064E;&zwnj;</span>&zwnj;ع ع&zwnj;<span class="styled">&zwnj;&#x0651;&zwnj;</span>&zwnj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_lig-000-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_lig-000-ref.html
new file mode 100644
index 0000000..7b92b83
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/reference/shaping_lig-000-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>ligatures: span</title>
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+<div class="ref" lang="ar" dir="rtl">علا</div>
+<div class="ref" lang="ar" dir="rtl">علا</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-000.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-000.html
new file mode 100644
index 0000000..6a56c09
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-000.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: span</title>
+<meta name="assert" content="Shaping should not be broken across inline box boundaries with no styling change.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping-000-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+<div class="test" lang="ar" dir="rtl">ع<span>ع</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span>&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-001.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-001.html
new file mode 100644
index 0000000..5c5ac1a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-001.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: colour</title>
+<meta name="assert" content="Shaping should not be broken across inline box boundaries for changes to colour.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping-001-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.color { color:blue; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+
+<div class="test" lang="ar" dir="rtl">ع<span class="color">ع</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="color">&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-002.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-002.html
new file mode 100644
index 0000000..f4b4122
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-002.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: font-weight</title>
+<meta name="assert" content="Shaping should not be broken across inline box boundaries for changes in font weight.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping-002-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.fontweight { font-weight: bold; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+
+<div class="test" lang="ar" dir="rtl">ع<span class="fontweight">ع</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="fontweight">&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-003.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-003.html
new file mode 100644
index 0000000..3cc4b3dfc
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-003.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: font-style</title>
+<meta name="assert" content="Shaping should not be broken across inline box boundaries for changes in font style.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping-003-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.fontstyle { font-style: italic; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+
+<div class="test" lang="ar" dir="rtl">ع<span class="fontstyle">ع</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="fontstyle">&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-004.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-004.html
new file mode 100644
index 0000000..3b7d1724
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-004.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: margin 0</title>
+<meta name="assert" content="Shaping should not be broken across inline box boundaries when margin is set to 0.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping-004-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.margin { margin:0; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+
+<div class="test" lang="ar" dir="rtl">ع<span class="margin">ع</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="margin">&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-005.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-005.html
new file mode 100644
index 0000000..2ef446f6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-005.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: padding 0</title>
+<meta name="assert" content="Shaping should not be broken across inline box boundaries when padding is set to 0.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping-005-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.padding { padding:0; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+
+<div class="test" lang="ar" dir="rtl">ع<span class="padding">ع</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="padding">&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-006.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-006.html
new file mode 100644
index 0000000..5fad09b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-006.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: border 0</title>
+<meta name="assert" content="Shaping should not be broken across inline box boundaries when border is set to 0.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping-006-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.margin { margin:0; }
+.padding { padding:0; }
+.border { border:0; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+
+<div class="test" lang="ar" dir="rtl">ع<span class="border">ع</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="border">&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-007.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-007.html
new file mode 100644
index 0000000..33a81b6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-007.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: font size 100%</title>
+<meta name="assert" content="Shaping should not be broken across inline box boundaries when font-size is set to 100%.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping-007-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.fontsize { font-size:100%; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+
+<div class="test" lang="ar" dir="rtl">ع<span class="fontsize">ع</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="fontsize">&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-008.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-008.html
new file mode 100644
index 0000000..f7f1fad
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-008.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: font size 120%</title>
+<meta name="assert" content="Shaping should not be broken across inline box boundaries for changes to font-size.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping-008-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.fontsizeplus { font-size:120%; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+
+<div class="test" lang="ar" dir="rtl">ع<span class="fontsizeplus">ع</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="fontsizeplus">&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-009.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-009.html
new file mode 100644
index 0000000..979e5fd
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-009.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: margin &gt; 0</title>
+<meta name="assert" content="Shaping SHOULD be broken across inline box boundaries when marginis set to a non-zero value.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping-009-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.margin { margin: 0.5em; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters DON'T join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+<div class="test" lang="ar" dir="rtl">ع<span class="margin">ع</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwnj;<span class="margin">&zwnj;ع&zwnj;</span>&zwnj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-010.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-010.html
new file mode 100644
index 0000000..02f7ce38
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-010.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: padding &gt; 0</title>
+<meta name="assert" content="Shaping SHOULD be broken across inline box boundaries when padding is set to a non-zero value.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping-010-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.padding { padding: 0.5em; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters DON'T join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+<div class="test" lang="ar" dir="rtl">ع<span class="padding">ع</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwnj;<span class="padding">&zwnj;ع&zwnj;</span>&zwnj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-011.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-011.html
new file mode 100644
index 0000000..a2316f5
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-011.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: border &gt; 0</title>
+<meta name="assert" content="Shaping SHOULD be broken across inline box boundaries when border is set to a non-zero value.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping-011-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.border { border: 1px solid #ccc; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters DON'T join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+<div class="test" lang="ar" dir="rtl">ع<span class="border">ع</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwnj;<span class="border">&zwnj;ع&zwnj;</span>&zwnj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-012.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-012.html
new file mode 100644
index 0000000..6bc26206
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-012.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: isolation, bdi</title>
+<meta name="assert" content="Shaping SHOULD be broken across inline box boundaries when isolation occurs.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping-012-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters DON'T join.</p>
+<p><small>Skip if markup alone breaks the join (test shaping-000)</small><br/>
+<small>Skip this test if bdi and dir=auto don't produce isolation in this browser.</small></p>
+<div class="test" lang="ar" dir="rtl">ع<bdi>ع</bdi>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwnj;<bdi>&zwnj;ع&zwnj;</bdi>&zwnj;ع</div>
+<!-- Notes:
+This test only works if bdi and dir=auto are supported by the browser.
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-013.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-013.html
new file mode 100644
index 0000000..a4b55b2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-013.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: isolation, auto</title>
+<meta name="assert" content="Shaping SHOULD be broken across inline box boundaries when isolation occurs.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping-012-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters DON'T join.</p>
+<p><small>Skip if markup alone breaks the join (test shaping-000)</small><br/>
+<small>Skip this test if bdi and dir=auto don't produce isolation in this browser.</small></p>
+<div class="test" lang="ar" dir="rtl">ع<span dir="auto">ع</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwnj;<bdi>&zwnj;ع&zwnj;</bdi>&zwnj;ع</div>
+<!-- Notes:
+This test only works if bdi and dir=auto are supported by the browser.
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-014.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-014.html
new file mode 100644
index 0000000..100a7d7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-014.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: text-decoration</title>
+<meta name="assert" content="Shaping should not be broken across inline box boundaries for changes in text-decoration.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping-014-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { text-decoration: underline; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if both boxes look the same.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+<div class="test" lang="ar" dir="rtl">ع<span class="styled">ع</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-015.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-015.html
new file mode 100644
index 0000000..fcbc44a5
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-015.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: text-decoration</title>
+<meta name="assert" content="Shaping should not be broken across inline box boundaries for changes in text-decoration.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping-015-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { text-decoration: underline; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+<div class="test" lang="ar" dir="rtl">ع<span class="styled">ع</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-016.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-016.html
new file mode 100644
index 0000000..da324621
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-016.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: outline</title>
+<meta name="assert" content="Shaping should not be broken across inline box boundaries for changes in outline.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping-016-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { outline: 1px solid blue; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+<div class="test" lang="ar" dir="rtl">ع<span class="styled">ع</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-017.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-017.html
new file mode 100644
index 0000000..cb1acef
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-017.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: em element</title>
+<meta name="assert" content="Shaping should not be broken across inline box boundaries for the em element.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping-017-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { font-style: italic; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if both boxes look the same.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+<div class="test" lang="ar" dir="rtl">ع<em>ع</em>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+It also assumes that the default rendering for the em element is italic.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-018.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-018.html
new file mode 100644
index 0000000..a4b69e9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-018.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>shaping: b element</title>
+<meta name="assert" content="Shaping should not be broken across inline box boundaries for the b element.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping-018-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { font-weight: bold; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+<small>Skip if markup alone breaks the join (test shaping-000)</small>
+<div class="test" lang="ar" dir="rtl">ع<b>ع</b>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;ع&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+It also assumes that the default rendering for the b element is bold.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-020.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-020.html
new file mode 100644
index 0000000..10f612c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-020.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>n'ko, colour</title>
+<meta name="assert" content="Shaping should not be broken across inline box boundaries for changes to colour in N'Ko.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping-020-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoSansNko-regular-webfont.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { color:blue; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three N'Ko characters join.</p>
+<div class="test" lang="nqo" dir="rtl">ߞ<span class="styled">ߞ</span>ߞ</div>
+<div class="ref" lang="nqo" dir="rtl">ߞ&zwj;<span class="styled">&zwj;ߞ&zwj;</span>&zwj;ߞ</div>
+<!-- Notes:
+This test uses the Noto Sans N'Ko font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-021.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-021.html
new file mode 100644
index 0000000..5320168
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-021.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>n'ko, font-style</title>
+<meta name="assert" content="Shaping should not be broken across inline box boundaries for changes to font-style in N'Ko.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping-021-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoSansNko-regular-webfont.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { font-style:italic; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three N'Ko characters join.</p>
+<div class="test" lang="nqo" dir="rtl">ߞ<span class="styled">ߞ</span>ߞ</div>
+<div class="ref" lang="nqo" dir="rtl">ߞ&zwj;<span class="styled">&zwj;ߞ&zwj;</span>&zwj;ߞ</div>
+<!-- Notes:
+This test uses the Noto Sans N'Ko font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-022.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-022.html
new file mode 100644
index 0000000..06dde6f3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-022.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>n'ko, text-decoration</title>
+<meta name="assert" content="Shaping should not be broken across inline box boundaries for changes to text-decoration in N'Ko.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping-022-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoSansNko-regular-webfont.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { text-decoration: underline; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three N'Ko characters join.</p>
+<div class="test" lang="nqo" dir="rtl">ߞ<span class="styled">ߞ</span>ߞ</div>
+<div class="ref" lang="nqo" dir="rtl">ߞ&zwj;<span class="styled">&zwj;ߞ&zwj;</span>&zwj;ߞ</div>
+<!-- Notes:
+This test uses the Noto Sans N'Ko font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-023.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-023.html
new file mode 100644
index 0000000..4ab0c1b3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-023.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>mongolian, colour</title>
+<meta name="assert" content="Shaping should not be broken across inline box boundaries for changes to colour in Mongolian.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoSansMongolian-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; writing-mode: vertical-lr; }
+/* the CSS above is not part of the test */
+.styled { color:blue; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Mongolian characters join in the right-hand line.</p>
+<small>Skip the test if the line on the left isn't arranged vertically and joined up.</small>
+<div class="test" lang="mn" dir="rtl">ᠨᠨᠨ<br/>ᠨ<span class="styled">ᠨ</span>ᠨ</div>
+<!-- Notes:
+This test uses the Noto Sans Mongolian font to control variables related to font choice.
+The test is manual because Safari (and possibly other browsers) don't support joining for vertical Mongolian anyway, so ref tests wouldn't test the correct thing.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-024.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-024.html
new file mode 100644
index 0000000..306ce43
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-024.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>mongolian, font-style</title>
+<meta name="assert" content="Shaping should not be broken across inline box boundaries for changes to font-style in Mongolian.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoSansMongolian-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; writing-mode: vertical-lr; }
+/* the CSS above is not part of the test */
+.styled { font-style:italic; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Mongolian characters join in the right-hand line.</p>
+<small>Skip the test if the line on the left isn't arranged vertically and joined up.</small>
+<div class="test" lang="mn" dir="rtl">ᠨᠨᠨ<br/>ᠨ<span class="styled">ᠨ</span>ᠨ</div>
+<!-- Notes:
+This test uses the Noto Sans Mongolian font to control variables related to font choice.
+The test is manual because Safari (and possibly other browsers) don't support joining for vertical Mongolian anyway, so ref tests wouldn't test the correct thing.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-025.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-025.html
new file mode 100644
index 0000000..0c08600
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping-025.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>mongolian, text-decoration</title>
+<meta name="assert" content="Shaping should not be broken across inline box boundaries for changes to text-decoration in Mongolian.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoSansMongolian-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; writing-mode: vertical-lr; }
+/* the CSS above is not part of the test */
+.styled { text-decoration:underline; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Mongolian characters join in the right-hand line.</p>
+<small>Skip the test if the line on the left isn't arranged vertically and joined up.</small>
+<div class="test" lang="mn" dir="rtl">ᠨᠨᠨ<br/>ᠨ<span class="styled">ᠨ</span>ᠨ</div>
+<!-- Notes:
+This test uses the Noto Sans Mongolian font to control variables related to font choice.
+The test is manual because Safari (and possibly other browsers) don't support joining for vertical Mongolian anyway, so ref tests wouldn't test the correct thing.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-000.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-000.html
new file mode 100644
index 0000000..62490a2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-000.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>marked up diacritic: span</title>
+<meta name="assert" content="Shaping should not be broken by a span with no styling change for an intervening diacritic.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping_cchar-000-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the Arabic base characters in each word join.</p>
+<div class="test" lang="ar" dir="rtl">ع<span>&#x064E;</span>ع ع<span>&#x0651;</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&#x064E;ع ع&#x0651;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-001.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-001.html
new file mode 100644
index 0000000..48ab60a2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-001.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>styled diacritic: colour</title>
+<meta name="assert" content="Shaping should not be broken for changes to colour for an intervening diacritic.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping_cchar-001-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { color:blue; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the Arabic base characters in each word join.</p>
+<p><small>Skip if markup alone breaks the join (test shaping_cchar-000)</small></p>
+<div class="test" lang="ar" dir="rtl">ع<span class="styled">&#x064E;</span>ع ع<span class="styled">&#x0651;</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;&#x064E;&zwj;</span>&zwj;ع ع&zwj;<span class="styled">&zwj;&#x0651;&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-002.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-002.html
new file mode 100644
index 0000000..5885743
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-002.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>styled diacritic: font-weight</title>
+<meta name="assert" content="Shaping should not be broken for changes in font weight for an intervening diacritic.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping_cchar-002-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { font-weight: bold; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the Arabic base characters in each word join.</p>
+<p><small>Skip if markup alone breaks the join (test shaping_cchar-000)</small><br/>
+<div class="test" lang="ar" dir="rtl">ع<span class="styled">&#x064E;</span>ع ع<span class="styled">&#x0651;</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;&#x064E;&zwj;</span>&zwj;ع ع&zwj;<span class="styled">&zwj;&#x0651;&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-003.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-003.html
new file mode 100644
index 0000000..32f40dd4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-003.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>styled diacritic: font-style</title>
+<meta name="assert" content="Shaping should not be broken for changes in font style for an intervening diacritic.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping_cchar-003-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { font-style: italic; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the Arabic base characters in each word join.</p>
+<p><small>Skip if markup alone breaks the join (test shaping_cchar-000)</small><br/>
+<div class="test" lang="ar" dir="rtl">ع<span class="styled">&#x064E;</span>ع ع<span class="styled">&#x0651;</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;&#x064E;&zwj;</span>&zwj;ع ع&zwj;<span class="styled">&zwj;&#x0651;&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-004.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-004.html
new file mode 100644
index 0000000..2b24475
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-004.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>styled diacritic: margin 0</title>
+<meta name="assert" content="Shaping should not be broken when margin is set to 0 for an intervening diacritic.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping_cchar-004-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { margin:0; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the Arabic base characters in each word join.</p>
+<p><small>Skip if markup alone breaks the join (test shaping_cchar-000)</small><br/>
+<div class="test" lang="ar" dir="rtl">ع<span class="styled">&#x064E;</span>ع ع<span class="styled">&#x0651;</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;&#x064E;&zwj;</span>&zwj;ع ع&zwj;<span class="styled">&zwj;&#x0651;&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-005.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-005.html
new file mode 100644
index 0000000..8454d4ea
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-005.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>styled diacritic: padding 0</title>
+<meta name="assert" content="Shaping should not be broken when padding is set to 0 for an intervening diacritic.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping_cchar-005-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { padding:0; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the Arabic base characters in each word join.</p>
+<p><small>Skip if markup alone breaks the join (test shaping_cchar-000)</small><br/>
+<div class="test" lang="ar" dir="rtl">ع<span class="styled">&#x064E;</span>ع ع<span class="styled">&#x0651;</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;&#x064E;&zwj;</span>&zwj;ع ع&zwj;<span class="styled">&zwj;&#x0651;&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-006.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-006.html
new file mode 100644
index 0000000..5f36e7d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-006.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>styled diacritic: border 0</title>
+<meta name="assert" content="Shaping should not be broken when border is set to 0 for an intervening diacritic.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping_cchar-006-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { border:0; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the Arabic base characters in each word join.</p>
+<p><small>Skip if markup alone breaks the join (test shaping_cchar-000)</small><br/>
+<div class="test" lang="ar" dir="rtl">ع<span class="styled">&#x064E;</span>ع ع<span class="styled">&#x0651;</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;&#x064E;&zwj;</span>&zwj;ع ع&zwj;<span class="styled">&zwj;&#x0651;&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-007.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-007.html
new file mode 100644
index 0000000..bd9e44e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-007.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>styled diacritic: font size 100%</title>
+<meta name="assert" content="Shaping should not be broken when font-size is set to 100% for an intervening diacritic.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping_cchar-007-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { font-size:100%; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the Arabic base characters in each word join.</p>
+<p><small>Skip if markup alone breaks the join (test shaping_cchar-000)</small><br/>
+<div class="test" lang="ar" dir="rtl">ع<span class="styled">&#x064E;</span>ع ع<span class="styled">&#x0651;</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;&#x064E;&zwj;</span>&zwj;ع ع&zwj;<span class="styled">&zwj;&#x0651;&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-008.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-008.html
new file mode 100644
index 0000000..17295db
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-008.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>styled diacritic: font size 120%</title>
+<meta name="assert" content="Shaping should not be broken when font-size is changed for an intervening diacritic.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping_cchar-008-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { font-size:120%; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the Arabic base characters in each word join.</p>
+<p><small>Skip if markup alone breaks the join (test shaping_cchar-000)</small><br/>
+<div class="test" lang="ar" dir="rtl">ع<span class="styled">&#x064E;</span>ع ع<span class="styled">&#x0651;</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwj;<span class="styled">&zwj;&#x064E;&zwj;</span>&zwj;ع ع&zwj;<span class="styled">&zwj;&#x0651;&zwj;</span>&zwj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-009.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-009.html
new file mode 100644
index 0000000..e17218d2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-009.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>styled diacritic: margin &gt; 0</title>
+<meta name="assert" content="Shaping SHOULD be broken when margin is set to a non-zero value on an intervening diacritic.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping_cchar-009-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 5em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { margin: 0.5em; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the Arabic characters DON'T show joining forms.</p>
+<p><small>Skip if markup alone breaks the join (test shaping_cchar-000)</small><br/>
+<div class="test" lang="ar" dir="rtl">ع<span class="styled">&#x064E;</span>ع ع<span class="styled">&#x0651;</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwnj;<span class="styled">&zwnj;&#x064E;&zwnj;</span>&zwnj;ع ع&zwnj;<span class="styled">&zwnj;&#x0651;&zwnj;</span>&zwnj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-010.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-010.html
new file mode 100644
index 0000000..0f9d8a4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-010.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>styled diacritic: padding &gt; 0</title>
+<meta name="assert" content="Shaping SHOULD be broken when padding is set to a non-zero value on an intervening diacritic.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping_cchar-010-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 5em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { padding: 0.5em; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the Arabic characters DON'T show joining forms.</p>
+<p><small>Skip if markup alone breaks the join (test shaping_cchar-000)</small><br/>
+<div class="test" lang="ar" dir="rtl">ع<span class="styled">&#x064E;</span>ع ع<span class="styled">&#x0651;</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwnj;<span class="styled">&zwnj;&#x064E;&zwnj;</span>&zwnj;ع ع&zwnj;<span class="styled">&zwnj;&#x0651;&zwnj;</span>&zwnj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-011.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-011.html
new file mode 100644
index 0000000..8ab7606
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_cchar-011.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>styled diacritic: border &gt; 0</title>
+<meta name="assert" content="Shaping SHOULD be broken when border is set to a non-zero value on an intervening diacritic.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping_cchar-011-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 5em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+.styled { border: 1px solid #ccc; }
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the Arabic characters DON'T show joining forms.</p>
+<p><small>Skip if markup alone breaks the join (test shaping_cchar-000)</small><br/>
+<div class="test" lang="ar" dir="rtl">ع<span class="styled">&#x064E;</span>ع ع<span class="styled">&#x0651;</span>ع</div>
+<div class="ref" lang="ar" dir="rtl">ع&zwnj;<span class="styled">&zwnj;&#x064E;&zwnj;</span>&zwnj;ع ع&zwnj;<span class="styled">&zwnj;&#x0651;&zwnj;</span>&zwnj;ع</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_lig-000.html b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_lig-000.html
new file mode 100644
index 0000000..6b91835
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/shaping/shaping_lig-000.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html  lang="en" >
+<head>
+<meta charset="utf-8">
+<title>ligatures: span</title>
+<meta name="assert" content="Markup inside a ligature with no styling will NOT break joining behaviour.">
+<link rel="author" title="Richard Ishida" href="mailto:ishida@w3.org">
+<link rel="help" href="https://drafts.csswg.org/css-text/#boundary-shaping">
+<link rel="match" href="reference/shaping_lig-000-ref.html">
+<style type="text/css">
+@font-face {
+    font-family: 'csstest_noto';
+    src: url('/fonts/noto/NotoNaskhArabic-regular.woff2') format('woff2');
+    font-weight: normal;
+    font-style: normal;
+    }
+.test, .ref { border: 1px solid #02D7F6;  margin: 20px;  padding: 10px; width: 3em; font-size: 120px; font-family: "csstest_noto"; }
+/* the CSS above is not part of the test */
+</style>
+</head>
+<body>
+<p class="instructions">Test passes if the three Arabic characters join.</p>
+<div class="test" lang="ar" dir="rtl">ع<span>ل</span>ا</div>
+<div class="ref" lang="ar" dir="rtl">علا</div>
+<!-- Notes:
+This test uses the Noto Naskh Arabic font to control variables related to font choice.
+-->
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/portals/portals-nested.html b/third_party/blink/web_tests/external/wpt/portals/portals-nested.html
new file mode 100644
index 0000000..26b264e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/portals/portals-nested.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+  <script>
+    promise_test(() => {
+      var portal = document.createElement("portal");
+      portal.src = "resources/portals-nested-1.html";
+      document.body.appendChild(portal);
+      var waitForMessage = new Promise((resolve, reject) => {
+        var bc = new BroadcastChannel("portals-nested");
+        bc.onmessage = () => {
+          bc.close();
+          resolve();
+        }
+      });
+      return waitForMessage;
+    }, "nested portals shouldn't crash");
+  </script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/portals/resources/portals-nested-1.html b/third_party/blink/web_tests/external/wpt/portals/resources/portals-nested-1.html
new file mode 100644
index 0000000..f558e51
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/portals/resources/portals-nested-1.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<body>
+  <portal src="portals-nested-2.html"></portal>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/portals/resources/portals-nested-2.html b/third_party/blink/web_tests/external/wpt/portals/resources/portals-nested-2.html
new file mode 100644
index 0000000..e8a2322
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/portals/resources/portals-nested-2.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<script>
+  var bc = new BroadcastChannel("portals-nested");
+  bc.postMessage("loaded");
+  bc.close();
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/service-worker-csp-worker.py b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/service-worker-csp-worker.py
index 5f06454..9d2b1f2d 100644
--- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/service-worker-csp-worker.py
+++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/resources/service-worker-csp-worker.py
@@ -17,6 +17,15 @@
                 'Importing the other origins script should fail.');
   }, 'importScripts test for default-src');
 
+test(function() {
+    assert_throws(EvalError(),
+                  function() { eval('1 + 1'); },
+                  'eval() should throw EvalError.')
+    assert_throws(EvalError(),
+                  function() { new Function('1 + 1'); },
+                  'new Function() should throw EvalError.')
+  }, 'eval test for default-src');
+
 async_test(function(t) {
     fetch(host_info.HTTPS_REMOTE_ORIGIN +
           base_path() + 'fetch-access-control.py?ACAOrigin=*',
@@ -63,6 +72,15 @@
                 'Importing the other origins script should fail.');
   }, 'importScripts test for script-src');
 
+test(function() {
+    assert_throws(EvalError(),
+                  function() { eval('1 + 1'); },
+                  'eval() should throw EvalError.')
+    assert_throws(EvalError(),
+                  function() { new Function('1 + 1'); },
+                  'new Function() should throw EvalError.')
+  }, 'eval test for script-src');
+
 async_test(function(t) {
     fetch(host_info.HTTPS_REMOTE_ORIGIN +
           base_path() + 'fetch-access-control.py?ACAOrigin=*',
@@ -109,6 +127,18 @@
                  'Importing the other origins script should not fail.');
   }, 'importScripts test for connect-src');
 
+test(function() {
+    var eval_failed = false;
+    try {
+      eval('1 + 1');
+      new Function('1 + 1');
+    } catch(e) {
+      eval_failed = true;
+    }
+    assert_false(eval_failed,
+                 'connect-src without unsafe-eval should not block eval().');
+  }, 'eval test for connect-src');
+
 async_test(function(t) {
     fetch(host_info.HTTPS_REMOTE_ORIGIN +
           base_path() + 'fetch-access-control.py?ACAOrigin=*',
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCDataChannel-bufferedAmount-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc/RTCDataChannel-bufferedAmount-expected.txt
index d1c7fba..d98b02263 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCDataChannel-bufferedAmount-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCDataChannel-bufferedAmount-expected.txt
@@ -1,7 +1,12 @@
 This is a testharness.js-based test.
-FAIL bufferedAmount should increase to byte length of encoded unicode string sent assert_equals: Expect bufferedAmount to be the byte length of the unicode string expected 12 but got 0
-FAIL bufferedAmount should increase to byte length of buffer sent assert_equals: Expect bufferedAmount to increase to byte length of sent buffer expected 5 but got 0
+PASS bufferedAmount should increase to byte length of encoded unicode string sent
+PASS bufferedAmount should increase to byte length of buffer sent
 FAIL bufferedAmount should increase to size of blob sent promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'send' on 'RTCDataChannel': Blob support not implemented yet"
-FAIL bufferedAmount should increase by byte length for each message sent assert_unreached: Unexpected promise rejection: Error: assert_equals: Expect bufferedAmount to be the total length of all messages queued to send expected 5 but got 0 Reached unreachable code
+FAIL bufferedAmount should increase by byte length for each message sent assert_unreached: Unexpected promise rejection: NotSupportedError: Failed to execute 'send' on 'RTCDataChannel': Blob support not implemented yet Reached unreachable code
+PASS Data channel bufferedamountlow event fires after send() is complete
+PASS Data channel bufferedamount is data.length on send(data)
+PASS Data channel bufferedamount returns the same amount if no more data is sent on the channel
+PASS Data channel bufferedamountlow event fires only once after multiple consecutive send() calls
+PASS Data channel bufferedamountlow event fires after each sent message
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCDataChannel-bufferedAmount.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCDataChannel-bufferedAmount.html
index 2c37cc27..f4a7104a 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCDataChannel-bufferedAmount.html
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCDataChannel-bufferedAmount.html
@@ -166,4 +166,59 @@
       assert_unreached(`Unexpected promise rejection: ${err}`)));
   }, 'bufferedAmount should increase by byte length for each message sent');
 
+  promise_test(async t => {
+    const [channel1, channel2] = await createDataChannelPair();
+    channel1.addEventListener('bufferedamountlow', t.step_func_done(() => {
+      assert_true(channel1.bufferedAmount <= channel1.bufferedAmountLowThreshold);
+    }));
+    const eventWatcher = new EventWatcher(t, channel1, ['bufferedamountlow']);
+    channel1.send(helloString);
+    await eventWatcher.wait_for(['bufferedamountlow']);
+  }, 'Data channel bufferedamountlow event fires after send() is complete');
+
+  promise_test(async t => {
+    const [channel1, channel2] = await createDataChannelPair();
+    channel1.send(helloString);
+    assert_equals(channel1.bufferedAmount, helloString.length);
+    await awaitMessage(channel2);
+    assert_equals(channel1.bufferedAmount, 0);
+  }, 'Data channel bufferedamount is data.length on send(data)');
+
+  promise_test(async t => {
+    const [channel1, channel2] = await createDataChannelPair();
+    channel1.send(helloString);
+    assert_equals(channel1.bufferedAmount, helloString.length);
+    assert_equals(channel1.bufferedAmount, helloString.length);
+  }, 'Data channel bufferedamount returns the same amount if no more data is' +
+     ' sent on the channel');
+
+  promise_test(async t => {
+    const [channel1, channel2] = await createDataChannelPair();
+    let eventFireCount = 0;
+    channel1.addEventListener('bufferedamountlow', t.step_func(() => {
+      assert_true(channel1.bufferedAmount <= channel1.bufferedAmountLowThreshold);
+      assert_equals(++eventFireCount, 1);
+    }));
+    const eventWatcher = new EventWatcher(t, channel1, ['bufferedamountlow']);
+    channel1.send(helloString);
+    assert_equals(channel1.bufferedAmount, helloString.length);
+    channel1.send(helloString);
+    assert_equals(channel1.bufferedAmount, 2 * helloString.length);
+    await eventWatcher.wait_for(['bufferedamountlow']);
+  }, 'Data channel bufferedamountlow event fires only once after multiple' +
+    ' consecutive send() calls');
+
+  promise_test(async t => {
+    const [channel1, channel2] = await createDataChannelPair();
+    const eventWatcher = new EventWatcher(t, channel1, ['bufferedamountlow']);
+    channel1.send(helloString);
+    assert_equals(channel1.bufferedAmount, helloString.length);
+    await eventWatcher.wait_for(['bufferedamountlow']);
+    assert_equals(await awaitMessage(channel2), helloString);
+    channel1.send(helloString);
+    assert_equals(channel1.bufferedAmount, helloString.length);
+    await eventWatcher.wait_for(['bufferedamountlow']);
+    assert_equals(await awaitMessage(channel2), helloString);
+  }, 'Data channel bufferedamountlow event fires after each sent message');
+
 </script>
diff --git a/third_party/blink/web_tests/fast/encoding/GBK/close-gbk-converter.html b/third_party/blink/web_tests/fast/encoding/GBK/close-gbk-converter.html
index 760ba2564..783bb1e 100644
--- a/third_party/blink/web_tests/fast/encoding/GBK/close-gbk-converter.html
+++ b/third_party/blink/web_tests/fast/encoding/GBK/close-gbk-converter.html
@@ -8,11 +8,11 @@
 function test() {
     var req = new XMLHttpRequest;
     req.open("GET", "?§Ø", false);
-    req.send();
+    try { req.send(); } catch (e) {}
 
     req = new XMLHttpRequest;
     req.open("GET", "/§Ø", false);
-    req.send();
+    try { req.send(); } catch (e) {}
 }
 </script>
 </head>
diff --git a/third_party/blink/web_tests/fast/xmlhttprequest/set-dangerous-headers-local-expected.txt b/third_party/blink/web_tests/fast/xmlhttprequest/set-dangerous-headers-local-expected.txt
deleted file mode 100644
index 3b39968..0000000
--- a/third_party/blink/web_tests/fast/xmlhttprequest/set-dangerous-headers-local-expected.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-CONSOLE WARNING: line 15: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-CONSOLE ERROR: line 17: Refused to set unsafe header "ACCEPT-CHARSET"
-CONSOLE ERROR: line 18: Refused to set unsafe header "ACCEPT-ENCODING"
-CONSOLE ERROR: line 19: Refused to set unsafe header "ACCESS-CONTROL-REQUEST-HEADERS"
-CONSOLE ERROR: line 20: Refused to set unsafe header "ACCESS-CONTROL-REQUEST-METHOD"
-CONSOLE ERROR: line 26: Refused to set unsafe header "CONNECTION"
-CONSOLE ERROR: line 27: Refused to set unsafe header "CONTENT-LENGTH"
-CONSOLE ERROR: line 28: Refused to set unsafe header "COOKIE"
-CONSOLE ERROR: line 29: Refused to set unsafe header "COOKIE2"
-CONSOLE ERROR: line 30: Refused to set unsafe header "DATE"
-CONSOLE ERROR: line 31: Refused to set unsafe header "DNT"
-CONSOLE ERROR: line 32: Refused to set unsafe header "EXPECT"
-CONSOLE ERROR: line 33: Refused to set unsafe header "HOST"
-CONSOLE ERROR: line 34: Refused to set unsafe header "KEEP-ALIVE"
-CONSOLE ERROR: line 35: Refused to set unsafe header "ORIGIN"
-CONSOLE ERROR: line 36: Refused to set unsafe header "REFERER"
-CONSOLE ERROR: line 37: Refused to set unsafe header "TE"
-CONSOLE ERROR: line 38: Refused to set unsafe header "TRAILER"
-CONSOLE ERROR: line 39: Refused to set unsafe header "TRANSFER-ENCODING"
-CONSOLE ERROR: line 40: Refused to set unsafe header "UPGRADE"
-CONSOLE ERROR: line 41: Refused to set unsafe header "USER-AGENT"
-CONSOLE ERROR: line 42: Refused to set unsafe header "VIA"
-CONSOLE ERROR: line 44: Refused to set unsafe header "Proxy-"
-CONSOLE ERROR: line 45: Refused to set unsafe header "Proxy-test"
-CONSOLE ERROR: line 46: Refused to set unsafe header "PROXY-FOO"
-CONSOLE ERROR: line 48: Refused to set unsafe header "Sec-"
-CONSOLE ERROR: line 49: Refused to set unsafe header "Sec-test"
-CONSOLE ERROR: line 50: Refused to set unsafe header "SEC-FOO"
-Test that setRequestHeader cannot be used to alter security-sensitive headers for file:// urls.
-
-SUCCESS
diff --git a/third_party/blink/web_tests/fast/xmlhttprequest/set-dangerous-headers-local.html b/third_party/blink/web_tests/fast/xmlhttprequest/set-dangerous-headers-local.html
deleted file mode 100644
index a488d54..0000000
--- a/third_party/blink/web_tests/fast/xmlhttprequest/set-dangerous-headers-local.html
+++ /dev/null
@@ -1,65 +0,0 @@
-<html>
-<body>
-<p>Test that setRequestHeader cannot be used to alter security-sensitive headers
-for file:// urls.</p>
-<pre id=result>FAIL: script didn't run or raised an unexpected exception.</pre>
-<script>
-    if (window.testRunner)
-        testRunner.dumpAsText();
-
-    if (window.location.href.indexOf("file://") != 0) {
-        document.getElementById("result").textContent =
-            "ERROR: Not running from file:// origin.";
-    } else {
-        req = new XMLHttpRequest;
-        req.open("GET", "resources/print-headers.cgi", false);
-
-        req.setRequestHeader("ACCEPT-CHARSET", "foobar");
-        req.setRequestHeader("ACCEPT-ENCODING", "foobar");
-        req.setRequestHeader("ACCESS-CONTROL-REQUEST-HEADERS", "foobar");
-        req.setRequestHeader("ACCESS-CONTROL-REQUEST-METHOD", "foobar");
-        // AUTHORIZATION is no longer forbidden. See
-        // https://bugs.webkit.org/show_bug.cgi?id=24957 for more details. Set to
-        // a value other than the foobar since some http servers (lighttp) do not
-        // strip this out (Apache does).
-        req.setRequestHeader("AUTHORIZATION", "baz");
-        req.setRequestHeader("CONNECTION", "foobar");
-        req.setRequestHeader("CONTENT-LENGTH", "123456");
-        req.setRequestHeader("COOKIE", "foobar");
-        req.setRequestHeader("COOKIE2", "foobar");
-        req.setRequestHeader("DATE", "foobar");
-        req.setRequestHeader("DNT", "foobar");
-        req.setRequestHeader("EXPECT", "100-continue");
-        req.setRequestHeader("HOST", "foobar");
-        req.setRequestHeader("KEEP-ALIVE", "foobar");
-        req.setRequestHeader("ORIGIN", "foobar");
-        req.setRequestHeader("REFERER", "foobar");
-        req.setRequestHeader("TE", "foobar");
-        req.setRequestHeader("TRAILER", "foobar");
-        req.setRequestHeader("TRANSFER-ENCODING", "foobar");
-        req.setRequestHeader("UPGRADE", "foobar");
-        req.setRequestHeader("USER-AGENT", "foobar");
-        req.setRequestHeader("VIA", "foobar");
-
-        req.setRequestHeader("Proxy-", "foobar");
-        req.setRequestHeader("Proxy-test", "foobar");
-        req.setRequestHeader("PROXY-FOO", "foobar");
-
-        req.setRequestHeader("Sec-", "foobar");
-        req.setRequestHeader("Sec-test", "foobar");
-        req.setRequestHeader("SEC-FOO", "foobar");
-
-        try {
-            req.send("");
-            if (req.responseText.match("100-continue|foobar|123456"))
-                document.getElementById("result").textContent =
-                    req.responseText;
-            else
-                document.getElementById("result").textContent = "SUCCESS";
-        } catch (ex) {
-            document.getElementById("result").textContent = ex;
-        }
-    }
-</script>
-</body>
-</html>
diff --git a/third_party/blink/web_tests/fast/xmlhttprequest/xmlhttprequest-missing-file-exception-expected.txt b/third_party/blink/web_tests/fast/xmlhttprequest/xmlhttprequest-missing-file-exception-expected.txt
deleted file mode 100644
index 4064c90..0000000
--- a/third_party/blink/web_tests/fast/xmlhttprequest/xmlhttprequest-missing-file-exception-expected.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-CONSOLE WARNING: line 26: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
-This test checks for rdar://problem/4962298 REGRESSION: Synchronous XHR for missing local file throws exception -- breaks Wikipedia widget
-
-PASS: No exception.
-readyState: 4 (number)
-responseText:  (string)
-responseXML: null (object)
-statusText:  (string)
-
diff --git a/third_party/blink/web_tests/fast/xmlhttprequest/xmlhttprequest-missing-file-exception.html b/third_party/blink/web_tests/fast/xmlhttprequest/xmlhttprequest-missing-file-exception.html
deleted file mode 100644
index be20215..0000000
--- a/third_party/blink/web_tests/fast/xmlhttprequest/xmlhttprequest-missing-file-exception.html
+++ /dev/null
@@ -1,51 +0,0 @@
-<p>This test checks for rdar://problem/4962298 REGRESSION: Synchronous XHR for missing local file throws exception -- breaks Wikipedia widget</p>
-<hr>
-
-<pre id="console"></pre>
-
-<script>
-function log(s)
-{
-    document.getElementById("console").appendChild(document.createTextNode(s + "\n"));
-}
-
-function logProperty(object, propertyName)
-{
-    var property;
-    try {
-        property = object[propertyName];
-    } catch(e) {
-        property = e;
-    }
-    log(propertyName + ": " + property + " (" + typeof property + ")");
-}
-
-function sendRequest() 
-{
-    var request = new XMLHttpRequest();
-    request.open("GET", "file:///iamthewalrus", false);
-    request.send(null);
-    return request;
-}
-
-if (window.testRunner)
-    testRunner.dumpAsText();
-
-try {
-    var request = sendRequest();
-
-    var properties = [
-        "readyState",
-        "responseText",
-        "responseXML",
-        /* "status", -- excluded because it differs on tiger and leopard */
-        "statusText",
-    ];
-    
-    log("PASS: No exception.");
-    for (var i = 0; i < properties.length; i++) //>
-        logProperty(request, properties[i]);
-} catch(e) {
-    log("FAIL: Caught exception " + e + ".");
-}
-</script>
diff --git a/third_party/blink/web_tests/fast/xmlhttprequest/xmlhttprequest-recursive-sync-event.html b/third_party/blink/web_tests/fast/xmlhttprequest/xmlhttprequest-recursive-sync-event.html
index a4b917e..afb2e3b 100644
--- a/third_party/blink/web_tests/fast/xmlhttprequest/xmlhttprequest-recursive-sync-event.html
+++ b/third_party/blink/web_tests/fast/xmlhttprequest/xmlhttprequest-recursive-sync-event.html
@@ -29,7 +29,7 @@
         }
     };
     xhr.open("GET", "recurse.html", false);
-    xhr.send(null);
+    try { xhr.send(null); } catch (e) {}
     log("PASS");
 }
 </script>
diff --git a/third_party/blink/web_tests/gamepad/gamepad-vibration.html b/third_party/blink/web_tests/gamepad/gamepad-vibration.html
index 7e1e7ad1..41779b4e 100644
--- a/third_party/blink/web_tests/gamepad/gamepad-vibration.html
+++ b/third_party/blink/web_tests/gamepad/gamepad-vibration.html
@@ -52,5 +52,55 @@
     assert_equals(gamepad.vibrationActuator, gamepad.vibrationActuator);
 }, "vibration actuator is same object");
 
+promise_test(async (t) => {
+    // Connect a gamepad with a dual-rumble vibration actuator.
+    let connectPromise = ongamepadconnected(t);
+    gamepadController.connect(0);
+    gamepadController.setId(0, "Ipswich Pro");
+    gamepadController.setButtonCount(0, 1);
+    gamepadController.setDualRumbleVibrationActuator(0, true);
+    gamepadController.dispatchConnected(0);
+    await connectPromise;
+
+    let gamepadBefore = navigator.getGamepads()[0];
+
+    // Press button 0.
+    gamepadController.setButtonData(0, 0, 1);
+
+    let gamepadAfter = navigator.getGamepads()[0];
+    assert_equals(gamepadAfter.buttons[0].value, 1.0);
+
+    assert_equals(gamepadBefore.vibrationActuator,
+                  gamepadAfter.vibrationActuator);
+}, "vibration actuator is still the same object after a button press");
+
+promise_test(async (t) => {
+    // Connect a gamepad with a dual-rumble vibration actuator.
+    let connectPromise = ongamepadconnected(t);
+    gamepadController.connect(0);
+    gamepadController.setId(0, "Nintendto Experiment");
+    gamepadController.setDualRumbleVibrationActuator(0, true);
+    gamepadController.dispatchConnected(0);
+    await connectPromise;
+
+    let gamepadBefore = navigator.getGamepads()[0];
+
+    // Disconnect the gamepad and connect a different one, also with vibration.
+    connectPromise = ongamepadconnected(t);
+    gamepadController.disconnect(0);
+    gamepadController.connect(0);
+    gamepadController.setId(0, "Nintendto Implement");
+    gamepadController.setDualRumbleVibrationActuator(0, true);
+    gamepadController.dispatchConnected(0);
+    await connectPromise;
+
+    let gamepadAfter = navigator.getGamepads()[0];
+
+    assert_equals(gamepadAfter.id, "Nintendto Implement");
+    assert_not_equals(gamepadBefore.vibrationActuator,
+                      gamepadAfter.vibrationActuator);
+}, "vibration actuator is different for different gamepad");
+
+
 </script>
 </body>
diff --git a/third_party/blink/web_tests/http/tests/intersection-observer/cross-origin-occlusion-tracking.html b/third_party/blink/web_tests/http/tests/intersection-observer/cross-origin-occlusion-tracking.html
new file mode 100644
index 0000000..33d3a70
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/intersection-observer/cross-origin-occlusion-tracking.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<style>
+pre, #log {
+  position: absolute;
+  top: 0;
+  left: 200px;
+}
+</style>
+
+<iframe src="http://localhost:8080/intersection-observer/resources/subframe-occlusion-tracking.html"></iframe>
+
+<script>
+
+if (self.internals) {
+  internals.DisableIntersectionObserverThrottleDelay();
+}
+
+async_test(t => {
+  let iframe = document.querySelector("iframe");
+  if (self.internals && !internals.isSiteIsolated(iframe)) {
+    t.done();
+    return;
+  }
+
+  let checkTracking = (expected => {
+    if (self.internals) {
+      t.step(() => {
+        assert_equals(internals.isTrackingOcclusionForIFrame(iframe), expected);
+      });
+    }
+  });
+
+  checkTracking(false);
+
+  let count = 0;
+  addEventListener("message", event => {
+    requestAnimationFrame(() => {
+      checkTracking(event.data.expected);
+      if (count++ > 3) {
+        t.done();
+      } else {
+        iframe.contentWindow.postMessage("", "*");
+      }
+    });
+  });
+
+  iframe.addEventListener("load", t.step_func(() => {
+    checkTracking(false);
+    requestAnimationFrame(() => {
+      iframe.contentWindow.postMessage("", "*")
+      checkTracking(false);
+    });
+  }));
+}, "Test that an OOP iframe only gets occlusion information from its parent if the iframe has an IntersectionObserver that needs it.");
+
+</script>
diff --git a/third_party/blink/web_tests/http/tests/intersection-observer/resources/subframe-occlusion-tracking.html b/third_party/blink/web_tests/http/tests/intersection-observer/resources/subframe-occlusion-tracking.html
new file mode 100644
index 0000000..51ca2d1b
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/intersection-observer/resources/subframe-occlusion-tracking.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<div id='target'>Hello, world!</div>
+
+<script>
+let observer = null;
+let trackVisibility = true;
+
+addEventListener("message", event => {
+  if (observer) {
+    observer.disconnect();
+    observer = null;
+    requestAnimationFrame(() => {
+      setTimeout(() => {
+        event.source.postMessage({expected: false}, "*");
+      });
+    });
+  } else {
+    observer = new IntersectionObserver(
+      entries => {}, {trackVisibility: trackVisibility, delay: 100});
+    observer.observe(document.getElementById('target'));
+    requestAnimationFrame(() => {
+      setTimeout(() => {
+        event.source.postMessage({expected: trackVisibility}, "*");
+        trackVisibility = !trackVisibility;
+      });
+    });
+  }
+});
+</script>
diff --git a/third_party/blink/web_tests/http/tests/serviceworker/csp-fetch-from-installed-service-worker-default-expected.txt b/third_party/blink/web_tests/http/tests/serviceworker/csp-fetch-from-installed-service-worker-default-expected.txt
new file mode 100644
index 0000000..19b56ff
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/serviceworker/csp-fetch-from-installed-service-worker-default-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+PASS CSP test for default-src in installed ServiceWorkerGlobalScope
+PASS importScripts test for default-src
+FAIL eval test for default-src assert_throws: eval() should throw EvalError. function "function() { eval('1 + 1'); }" did not throw
+PASS Fetch test for default-src
+PASS Redirected fetch test for default-src
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/http/tests/serviceworker/csp-fetch-from-installed-service-worker-script-expected.txt b/third_party/blink/web_tests/http/tests/serviceworker/csp-fetch-from-installed-service-worker-script-expected.txt
new file mode 100644
index 0000000..e13cc67
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/serviceworker/csp-fetch-from-installed-service-worker-script-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+PASS CSP test for script-src in installed ServiceWorkerGlobalScope
+PASS importScripts test for script-src
+FAIL eval test for script-src assert_throws: eval() should throw EvalError. function "function() { eval('1 + 1'); }" did not throw
+PASS Fetch test for script-src
+PASS Redirected fetch test for script-src
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/http/tests/serviceworker/resources/fetch-with-csp-worker.php b/third_party/blink/web_tests/http/tests/serviceworker/resources/fetch-with-csp-worker.php
index 8869dc6a..2ed3d3c 100644
--- a/third_party/blink/web_tests/http/tests/serviceworker/resources/fetch-with-csp-worker.php
+++ b/third_party/blink/web_tests/http/tests/serviceworker/resources/fetch-with-csp-worker.php
@@ -21,6 +21,15 @@
                 'Importing the other origins script should fail.');
   }, 'importScripts test for default-src');
 
+test(function() {
+    assert_throws(EvalError(),
+                  function() { eval('1 + 1'); },
+                  'eval() should throw EvalError.')
+    assert_throws(EvalError(),
+                  function() { new Function('1 + 1'); },
+                  'new Function() should throw EvalError.')
+  }, 'eval test for default-src');
+
 async_test(function(t) {
     fetch(host_info.HTTPS_REMOTE_ORIGIN +
           base_path() + 'fetch-access-control.php?ACAOrigin=*',
@@ -68,6 +77,15 @@
                 'Importing the other origins script should fail.');
   }, 'importScripts test for script-src');
 
+test(function() {
+    assert_throws(EvalError(),
+                  function() { eval('1 + 1'); },
+                  'eval() should throw EvalError.')
+    assert_throws(EvalError(),
+                  function() { new Function('1 + 1'); },
+                  'new Function() should throw EvalError.')
+  }, 'eval test for script-src');
+
 async_test(function(t) {
     fetch(host_info.HTTPS_REMOTE_ORIGIN +
           base_path() + 'fetch-access-control.php?ACAOrigin=*',
@@ -116,6 +134,18 @@
                  'Importing the other origins script should not fail.');
   }, 'importScripts test for connect-src');
 
+test(function() {
+    var eval_failed = false;
+    try {
+      eval('1 + 1');
+      new Function('1 + 1');
+    } catch(e) {
+      eval_failed = true;
+    }
+    assert_false(eval_failed,
+                 'connect-src without unsafe-eval should not block eval().');
+  }, 'eval test for connect-src');
+
 async_test(function(t) {
     fetch(host_info.HTTPS_REMOTE_ORIGIN +
           base_path() + 'fetch-access-control.php?ACAOrigin=*',
@@ -165,4 +195,4 @@
   }
 }
 
-echo $body;
\ No newline at end of file
+echo $body;
diff --git a/third_party/blink/web_tests/virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/service-worker-csp-default.https-expected.txt b/third_party/blink/web_tests/virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/service-worker-csp-default.https-expected.txt
new file mode 100644
index 0000000..7409f704
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/service-worker-csp-default.https-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+PASS CSP test for default-src in ServiceWorkerGlobalScope
+PASS importScripts test for default-src
+FAIL eval test for default-src assert_throws: eval() should throw EvalError. function "function() { eval('1 + 1'); }" did not throw
+PASS Fetch test for default-src
+PASS Redirected fetch test for default-src
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/service-worker-csp-script.https-expected.txt b/third_party/blink/web_tests/virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/service-worker-csp-script.https-expected.txt
new file mode 100644
index 0000000..a4f95319
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/service-worker-csp-script.https-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+PASS CSP test for script-src in ServiceWorkerGlobalScope
+PASS importScripts test for script-src
+FAIL eval test for script-src assert_throws: eval() should throw EvalError. function "function() { eval('1 + 1'); }" did not throw
+PASS Fetch test for script-src
+PASS Redirected fetch test for script-src
+Harness: the test ran to completion.
+
diff --git a/third_party/closure_compiler/externs/automation.js b/third_party/closure_compiler/externs/automation.js
index 7d440bfa..b55a86b1 100644
--- a/third_party/closure_compiler/externs/automation.js
+++ b/third_party/closure_compiler/externs/automation.js
@@ -31,6 +31,7 @@
   CLICKED: 'clicked',
   DOCUMENT_SELECTION_CHANGED: 'documentSelectionChanged',
   DOCUMENT_TITLE_CHANGED: 'documentTitleChanged',
+  END_OF_TEST: 'endOfTest',
   EXPANDED_CHANGED: 'expandedChanged',
   FOCUS: 'focus',
   FOCUS_CONTEXT: 'focusContext',
@@ -319,6 +320,7 @@
   SET_SEQUENTIAL_FOCUS_NAVIGATION_STARTING_POINT: 'setSequentialFocusNavigationStartingPoint',
   SET_VALUE: 'setValue',
   SHOW_CONTEXT_MENU: 'showContextMenu',
+  SIGNAL_END_OF_TEST: 'signalEndOfTest',
 };
 
 /**
diff --git a/third_party/libaom/cmake_update.sh b/third_party/libaom/cmake_update.sh
index c6c05ea..8922ff5 100755
--- a/third_party/libaom/cmake_update.sh
+++ b/third_party/libaom/cmake_update.sh
@@ -175,6 +175,19 @@
 
 reset_dirs linux/arm64
 gen_config_files linux/arm64 "${toolchain}/arm64-linux-gcc.cmake ${all_platforms}"
+
+# Same thing for Windows arm64.
+
+reset_dirs win/arm64
+cp "${CFG}/linux/arm64/config"/* "${CFG}/win/arm64/config/"
+sed -i.bak \
+  -e 's/\(#define[[:space:]]INLINE[[:space:]]*\)inline/#define INLINE __inline/' \
+  -e 's/\(#define[[:space:]]HAVE_PTHREAD_H[[:space:]]*\)1/#define HAVE_PTHREAD_H 0/' \
+  -e 's/\(#define[[:space:]]HAVE_UNISTD_H[[:space:]]*\)1/#define HAVE_UNISTD_H 0/' \
+  -e 's/\(#define[[:space:]]CONFIG_GCC[[:space:]]*\)1/#define CONFIG_GCC 0/' \
+  -e 's/\(#define[[:space:]]CONFIG_MSVS[[:space:]]*\)0/#define CONFIG_MSVS 1/' \
+  "${CFG}/win/arm64/config/aom_config.h"
+rm "${CFG}/win/arm64/config/aom_config.h.bak"
 )
 
 update_readme
diff --git a/third_party/libaom/source/config/win/arm64/config/aom_config.asm b/third_party/libaom/source/config/win/arm64/config/aom_config.asm
new file mode 100644
index 0000000..8542adc7
--- /dev/null
+++ b/third_party/libaom/source/config/win/arm64/config/aom_config.asm
@@ -0,0 +1,78 @@
+;
+; Copyright (c) 2019, Alliance for Open Media. All rights reserved
+;
+; This source code is subject to the terms of the BSD 2 Clause License and
+; the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+; was not distributed with this source code in the LICENSE file, you can
+; obtain it at www.aomedia.org/license/software. If the Alliance for Open
+; Media Patent License 1.0 was not distributed with this source code in the
+; PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+;
+ARCH_ARM equ 1
+ARCH_MIPS equ 0
+ARCH_PPC equ 0
+ARCH_X86 equ 0
+ARCH_X86_64 equ 0
+CONFIG_2PASS_PARTITION_SEARCH_LVL equ 1
+CONFIG_ACCOUNTING equ 0
+CONFIG_ANALYZER equ 0
+CONFIG_AV1_DECODER equ 1
+CONFIG_AV1_ENCODER equ 0
+CONFIG_BIG_ENDIAN equ 0
+CONFIG_BITSTREAM_DEBUG equ 0
+CONFIG_COEFFICIENT_RANGE_CHECKING equ 0
+CONFIG_COLLECT_INTER_MODE_RD_STATS equ 1
+CONFIG_COLLECT_PARTITION_STATS equ 0
+CONFIG_COLLECT_RD_STATS equ 0
+CONFIG_DEBUG equ 0
+CONFIG_DENOISE equ 1
+CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 equ 1
+CONFIG_DIST_8X8 equ 0
+CONFIG_ENTROPY_STATS equ 0
+CONFIG_FILEOPTIONS equ 1
+CONFIG_FP_MB_STATS equ 0
+CONFIG_GCC equ 1
+CONFIG_GCOV equ 0
+CONFIG_GPROF equ 0
+CONFIG_INSPECTION equ 0
+CONFIG_INTERNAL_STATS equ 0
+CONFIG_INTER_STATS_ONLY equ 0
+CONFIG_LIBYUV equ 1
+CONFIG_LOWBITDEPTH equ 1
+CONFIG_MAX_DECODE_PROFILE equ 0
+CONFIG_MISMATCH_DEBUG equ 0
+CONFIG_MULTITHREAD equ 1
+CONFIG_NORMAL_TILE_MODE equ 1
+CONFIG_ONE_PASS_SVM equ 0
+CONFIG_OS_SUPPORT equ 1
+CONFIG_PIC equ 0
+CONFIG_RD_DEBUG equ 0
+CONFIG_RUNTIME_CPU_DETECT equ 0
+CONFIG_SHARED equ 0
+CONFIG_SHARP_SETTINGS equ 0
+CONFIG_SIZE_LIMIT equ 1
+CONFIG_SPATIAL_RESAMPLING equ 1
+CONFIG_SPEED_STATS equ 0
+CONFIG_STATIC equ 1
+CONFIG_WEBM_IO equ 1
+DECODE_HEIGHT_LIMIT equ 16384
+DECODE_WIDTH_LIMIT equ 16384
+HAVE_AVX equ 0
+HAVE_AVX2 equ 0
+HAVE_DSPR2 equ 0
+HAVE_FEXCEPT equ 1
+HAVE_MIPS32 equ 0
+HAVE_MIPS64 equ 0
+HAVE_MMX equ 0
+HAVE_MSA equ 0
+HAVE_NEON equ 1
+HAVE_PTHREAD_H equ 1
+HAVE_SSE equ 0
+HAVE_SSE2 equ 0
+HAVE_SSE3 equ 0
+HAVE_SSE4_1 equ 0
+HAVE_SSE4_2 equ 0
+HAVE_SSSE3 equ 0
+HAVE_UNISTD_H equ 1
+HAVE_VSX equ 0
+HAVE_WXWIDGETS equ 0
diff --git a/third_party/libaom/source/config/win/arm64/config/aom_config.c b/third_party/libaom/source/config/win/arm64/config/aom_config.c
new file mode 100644
index 0000000..4aa0d2d
--- /dev/null
+++ b/third_party/libaom/source/config/win/arm64/config/aom_config.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2016, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+#include "aom/aom_codec.h"
+static const char* const cfg = "cmake ../source/libaom -G \"Unix Makefiles\" -DCMAKE_TOOLCHAIN_FILE=\"../source/libaom/build/cmake/toolchains/arm64-linux-gcc.cmake\" -DCONFIG_AV1_ENCODER=0 -DCONFIG_LOWBITDEPTH=1 -DCONFIG_MAX_DECODE_PROFILE=0 -DCONFIG_NORMAL_TILE_MODE=1 -DCONFIG_SIZE_LIMIT=1 -DDECODE_HEIGHT_LIMIT=16384 -DDECODE_WIDTH_LIMIT=16384";
+const char *aom_codec_build_config(void) {return cfg;}
diff --git a/third_party/libaom/source/config/win/arm64/config/aom_config.h b/third_party/libaom/source/config/win/arm64/config/aom_config.h
new file mode 100644
index 0000000..248dec2
--- /dev/null
+++ b/third_party/libaom/source/config/win/arm64/config/aom_config.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2019, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+#ifndef AOM_CONFIG_H_
+#define AOM_CONFIG_H_
+#define ARCH_ARM 1
+#define ARCH_MIPS 0
+#define ARCH_PPC 0
+#define ARCH_X86 0
+#define ARCH_X86_64 0
+#define CONFIG_2PASS_PARTITION_SEARCH_LVL 1
+#define CONFIG_ACCOUNTING 0
+#define CONFIG_ANALYZER 0
+#define CONFIG_AV1_DECODER 1
+#define CONFIG_AV1_ENCODER 0
+#define CONFIG_BIG_ENDIAN 0
+#define CONFIG_BITSTREAM_DEBUG 0
+#define CONFIG_COEFFICIENT_RANGE_CHECKING 0
+#define CONFIG_COLLECT_INTER_MODE_RD_STATS 1
+#define CONFIG_COLLECT_PARTITION_STATS 0
+#define CONFIG_COLLECT_RD_STATS 0
+#define CONFIG_DEBUG 0
+#define CONFIG_DENOISE 1
+#define CONFIG_DISABLE_FULL_PIXEL_SPLIT_8X8 1
+#define CONFIG_DIST_8X8 0
+#define CONFIG_ENTROPY_STATS 0
+#define CONFIG_FILEOPTIONS 1
+#define CONFIG_FP_MB_STATS 0
+#define CONFIG_GCC 0
+#define CONFIG_GCOV 0
+#define CONFIG_GPROF 0
+#define CONFIG_INSPECTION 0
+#define CONFIG_INTERNAL_STATS 0
+#define CONFIG_INTER_STATS_ONLY 0
+#define CONFIG_LIBYUV 1
+#define CONFIG_LOWBITDEPTH 1
+#define CONFIG_MAX_DECODE_PROFILE 0
+#define CONFIG_MISMATCH_DEBUG 0
+#define CONFIG_MULTITHREAD 1
+#define CONFIG_NORMAL_TILE_MODE 1
+#define CONFIG_ONE_PASS_SVM 0
+#define CONFIG_OS_SUPPORT 1
+#define CONFIG_PIC 0
+#define CONFIG_RD_DEBUG 0
+#define CONFIG_RUNTIME_CPU_DETECT 0
+#define CONFIG_SHARED 0
+#define CONFIG_SHARP_SETTINGS 0
+#define CONFIG_SIZE_LIMIT 1
+#define CONFIG_SPATIAL_RESAMPLING 1
+#define CONFIG_SPEED_STATS 0
+#define CONFIG_STATIC 1
+#define CONFIG_WEBM_IO 1
+#define DECODE_HEIGHT_LIMIT 16384
+#define DECODE_WIDTH_LIMIT 16384
+#define HAVE_AVX 0
+#define HAVE_AVX2 0
+#define HAVE_DSPR2 0
+#define HAVE_FEXCEPT 1
+#define HAVE_MIPS32 0
+#define HAVE_MIPS64 0
+#define HAVE_MMX 0
+#define HAVE_MSA 0
+#define HAVE_NEON 1
+#define HAVE_PTHREAD_H 0
+#define HAVE_SSE 0
+#define HAVE_SSE2 0
+#define HAVE_SSE3 0
+#define HAVE_SSE4_1 0
+#define HAVE_SSE4_2 0
+#define HAVE_SSSE3 0
+#define HAVE_UNISTD_H 0
+#define HAVE_VSX 0
+#define HAVE_WXWIDGETS 0
+#define INLINE __inline
+#endif  // AOM_CONFIG_H_
diff --git a/third_party/libaom/source/config/win/arm64/config/aom_dsp_rtcd.h b/third_party/libaom/source/config/win/arm64/config/aom_dsp_rtcd.h
new file mode 100644
index 0000000..dd882516
--- /dev/null
+++ b/third_party/libaom/source/config/win/arm64/config/aom_dsp_rtcd.h
@@ -0,0 +1,3320 @@
+// This file is generated. Do not edit.
+#ifndef AOM_DSP_RTCD_H_
+#define AOM_DSP_RTCD_H_
+
+#ifdef RTCD_C
+#define RTCD_EXTERN
+#else
+#define RTCD_EXTERN extern
+#endif
+
+/*
+ * DSP
+ */
+
+#include "aom/aom_integer.h"
+#include "aom_dsp/aom_dsp_common.h"
+#include "av1/common/blockd.h"
+#include "av1/common/enums.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void aom_blend_a64_hmask_c(uint8_t* dst,
+                           uint32_t dst_stride,
+                           const uint8_t* src0,
+                           uint32_t src0_stride,
+                           const uint8_t* src1,
+                           uint32_t src1_stride,
+                           const uint8_t* mask,
+                           int w,
+                           int h);
+void aom_blend_a64_hmask_neon(uint8_t* dst,
+                              uint32_t dst_stride,
+                              const uint8_t* src0,
+                              uint32_t src0_stride,
+                              const uint8_t* src1,
+                              uint32_t src1_stride,
+                              const uint8_t* mask,
+                              int w,
+                              int h);
+#define aom_blend_a64_hmask aom_blend_a64_hmask_neon
+
+void aom_blend_a64_mask_c(uint8_t* dst,
+                          uint32_t dst_stride,
+                          const uint8_t* src0,
+                          uint32_t src0_stride,
+                          const uint8_t* src1,
+                          uint32_t src1_stride,
+                          const uint8_t* mask,
+                          uint32_t mask_stride,
+                          int w,
+                          int h,
+                          int subx,
+                          int suby);
+#define aom_blend_a64_mask aom_blend_a64_mask_c
+
+void aom_blend_a64_vmask_c(uint8_t* dst,
+                           uint32_t dst_stride,
+                           const uint8_t* src0,
+                           uint32_t src0_stride,
+                           const uint8_t* src1,
+                           uint32_t src1_stride,
+                           const uint8_t* mask,
+                           int w,
+                           int h);
+void aom_blend_a64_vmask_neon(uint8_t* dst,
+                              uint32_t dst_stride,
+                              const uint8_t* src0,
+                              uint32_t src0_stride,
+                              const uint8_t* src1,
+                              uint32_t src1_stride,
+                              const uint8_t* mask,
+                              int w,
+                              int h);
+#define aom_blend_a64_vmask aom_blend_a64_vmask_neon
+
+void aom_convolve8_horiz_c(const uint8_t* src,
+                           ptrdiff_t src_stride,
+                           uint8_t* dst,
+                           ptrdiff_t dst_stride,
+                           const int16_t* filter_x,
+                           int x_step_q4,
+                           const int16_t* filter_y,
+                           int y_step_q4,
+                           int w,
+                           int h);
+#define aom_convolve8_horiz aom_convolve8_horiz_c
+
+void aom_convolve8_vert_c(const uint8_t* src,
+                          ptrdiff_t src_stride,
+                          uint8_t* dst,
+                          ptrdiff_t dst_stride,
+                          const int16_t* filter_x,
+                          int x_step_q4,
+                          const int16_t* filter_y,
+                          int y_step_q4,
+                          int w,
+                          int h);
+#define aom_convolve8_vert aom_convolve8_vert_c
+
+void aom_convolve_copy_c(const uint8_t* src,
+                         ptrdiff_t src_stride,
+                         uint8_t* dst,
+                         ptrdiff_t dst_stride,
+                         const int16_t* filter_x,
+                         int x_step_q4,
+                         const int16_t* filter_y,
+                         int y_step_q4,
+                         int w,
+                         int h);
+#define aom_convolve_copy aom_convolve_copy_c
+
+void aom_dc_128_predictor_16x16_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+void aom_dc_128_predictor_16x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_16x16 aom_dc_128_predictor_16x16_neon
+
+void aom_dc_128_predictor_16x32_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_dc_128_predictor_16x32 aom_dc_128_predictor_16x32_c
+
+void aom_dc_128_predictor_16x4_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_128_predictor_16x4 aom_dc_128_predictor_16x4_c
+
+void aom_dc_128_predictor_16x64_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_dc_128_predictor_16x64 aom_dc_128_predictor_16x64_c
+
+void aom_dc_128_predictor_16x8_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_128_predictor_16x8 aom_dc_128_predictor_16x8_c
+
+void aom_dc_128_predictor_2x2_c(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_128_predictor_2x2 aom_dc_128_predictor_2x2_c
+
+void aom_dc_128_predictor_32x16_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_dc_128_predictor_32x16 aom_dc_128_predictor_32x16_c
+
+void aom_dc_128_predictor_32x32_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+void aom_dc_128_predictor_32x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_128_predictor_32x32 aom_dc_128_predictor_32x32_neon
+
+void aom_dc_128_predictor_32x64_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_dc_128_predictor_32x64 aom_dc_128_predictor_32x64_c
+
+void aom_dc_128_predictor_32x8_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_128_predictor_32x8 aom_dc_128_predictor_32x8_c
+
+void aom_dc_128_predictor_4x16_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_128_predictor_4x16 aom_dc_128_predictor_4x16_c
+
+void aom_dc_128_predictor_4x4_c(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+void aom_dc_128_predictor_4x4_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_128_predictor_4x4 aom_dc_128_predictor_4x4_neon
+
+void aom_dc_128_predictor_4x8_c(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_128_predictor_4x8 aom_dc_128_predictor_4x8_c
+
+void aom_dc_128_predictor_64x16_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_dc_128_predictor_64x16 aom_dc_128_predictor_64x16_c
+
+void aom_dc_128_predictor_64x32_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_dc_128_predictor_64x32 aom_dc_128_predictor_64x32_c
+
+void aom_dc_128_predictor_64x64_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_dc_128_predictor_64x64 aom_dc_128_predictor_64x64_c
+
+void aom_dc_128_predictor_8x16_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_128_predictor_8x16 aom_dc_128_predictor_8x16_c
+
+void aom_dc_128_predictor_8x32_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_128_predictor_8x32 aom_dc_128_predictor_8x32_c
+
+void aom_dc_128_predictor_8x4_c(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_128_predictor_8x4 aom_dc_128_predictor_8x4_c
+
+void aom_dc_128_predictor_8x8_c(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+void aom_dc_128_predictor_8x8_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_128_predictor_8x8 aom_dc_128_predictor_8x8_neon
+
+void aom_dc_left_predictor_16x16_c(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+void aom_dc_left_predictor_16x16_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_16x16 aom_dc_left_predictor_16x16_neon
+
+void aom_dc_left_predictor_16x32_c(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_left_predictor_16x32 aom_dc_left_predictor_16x32_c
+
+void aom_dc_left_predictor_16x4_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_dc_left_predictor_16x4 aom_dc_left_predictor_16x4_c
+
+void aom_dc_left_predictor_16x64_c(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_left_predictor_16x64 aom_dc_left_predictor_16x64_c
+
+void aom_dc_left_predictor_16x8_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_dc_left_predictor_16x8 aom_dc_left_predictor_16x8_c
+
+void aom_dc_left_predictor_2x2_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_left_predictor_2x2 aom_dc_left_predictor_2x2_c
+
+void aom_dc_left_predictor_32x16_c(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_left_predictor_32x16 aom_dc_left_predictor_32x16_c
+
+void aom_dc_left_predictor_32x32_c(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+void aom_dc_left_predictor_32x32_neon(uint8_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint8_t* above,
+                                      const uint8_t* left);
+#define aom_dc_left_predictor_32x32 aom_dc_left_predictor_32x32_neon
+
+void aom_dc_left_predictor_32x64_c(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_left_predictor_32x64 aom_dc_left_predictor_32x64_c
+
+void aom_dc_left_predictor_32x8_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_dc_left_predictor_32x8 aom_dc_left_predictor_32x8_c
+
+void aom_dc_left_predictor_4x16_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_dc_left_predictor_4x16 aom_dc_left_predictor_4x16_c
+
+void aom_dc_left_predictor_4x4_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+void aom_dc_left_predictor_4x4_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_left_predictor_4x4 aom_dc_left_predictor_4x4_neon
+
+void aom_dc_left_predictor_4x8_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_left_predictor_4x8 aom_dc_left_predictor_4x8_c
+
+void aom_dc_left_predictor_64x16_c(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_left_predictor_64x16 aom_dc_left_predictor_64x16_c
+
+void aom_dc_left_predictor_64x32_c(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_left_predictor_64x32 aom_dc_left_predictor_64x32_c
+
+void aom_dc_left_predictor_64x64_c(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_left_predictor_64x64 aom_dc_left_predictor_64x64_c
+
+void aom_dc_left_predictor_8x16_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_dc_left_predictor_8x16 aom_dc_left_predictor_8x16_c
+
+void aom_dc_left_predictor_8x32_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_dc_left_predictor_8x32 aom_dc_left_predictor_8x32_c
+
+void aom_dc_left_predictor_8x4_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_left_predictor_8x4 aom_dc_left_predictor_8x4_c
+
+void aom_dc_left_predictor_8x8_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+void aom_dc_left_predictor_8x8_neon(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_dc_left_predictor_8x8 aom_dc_left_predictor_8x8_neon
+
+void aom_dc_predictor_16x16_c(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+void aom_dc_predictor_16x16_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_16x16 aom_dc_predictor_16x16_neon
+
+void aom_dc_predictor_16x32_c(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_dc_predictor_16x32 aom_dc_predictor_16x32_c
+
+void aom_dc_predictor_16x4_c(uint8_t* dst,
+                             ptrdiff_t y_stride,
+                             const uint8_t* above,
+                             const uint8_t* left);
+#define aom_dc_predictor_16x4 aom_dc_predictor_16x4_c
+
+void aom_dc_predictor_16x64_c(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_dc_predictor_16x64 aom_dc_predictor_16x64_c
+
+void aom_dc_predictor_16x8_c(uint8_t* dst,
+                             ptrdiff_t y_stride,
+                             const uint8_t* above,
+                             const uint8_t* left);
+#define aom_dc_predictor_16x8 aom_dc_predictor_16x8_c
+
+void aom_dc_predictor_2x2_c(uint8_t* dst,
+                            ptrdiff_t y_stride,
+                            const uint8_t* above,
+                            const uint8_t* left);
+#define aom_dc_predictor_2x2 aom_dc_predictor_2x2_c
+
+void aom_dc_predictor_32x16_c(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_dc_predictor_32x16 aom_dc_predictor_32x16_c
+
+void aom_dc_predictor_32x32_c(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+void aom_dc_predictor_32x32_neon(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_predictor_32x32 aom_dc_predictor_32x32_neon
+
+void aom_dc_predictor_32x64_c(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_dc_predictor_32x64 aom_dc_predictor_32x64_c
+
+void aom_dc_predictor_32x8_c(uint8_t* dst,
+                             ptrdiff_t y_stride,
+                             const uint8_t* above,
+                             const uint8_t* left);
+#define aom_dc_predictor_32x8 aom_dc_predictor_32x8_c
+
+void aom_dc_predictor_4x16_c(uint8_t* dst,
+                             ptrdiff_t y_stride,
+                             const uint8_t* above,
+                             const uint8_t* left);
+#define aom_dc_predictor_4x16 aom_dc_predictor_4x16_c
+
+void aom_dc_predictor_4x4_c(uint8_t* dst,
+                            ptrdiff_t y_stride,
+                            const uint8_t* above,
+                            const uint8_t* left);
+void aom_dc_predictor_4x4_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_dc_predictor_4x4 aom_dc_predictor_4x4_neon
+
+void aom_dc_predictor_4x8_c(uint8_t* dst,
+                            ptrdiff_t y_stride,
+                            const uint8_t* above,
+                            const uint8_t* left);
+#define aom_dc_predictor_4x8 aom_dc_predictor_4x8_c
+
+void aom_dc_predictor_64x16_c(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_dc_predictor_64x16 aom_dc_predictor_64x16_c
+
+void aom_dc_predictor_64x32_c(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_dc_predictor_64x32 aom_dc_predictor_64x32_c
+
+void aom_dc_predictor_64x64_c(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_dc_predictor_64x64 aom_dc_predictor_64x64_c
+
+void aom_dc_predictor_8x16_c(uint8_t* dst,
+                             ptrdiff_t y_stride,
+                             const uint8_t* above,
+                             const uint8_t* left);
+#define aom_dc_predictor_8x16 aom_dc_predictor_8x16_c
+
+void aom_dc_predictor_8x32_c(uint8_t* dst,
+                             ptrdiff_t y_stride,
+                             const uint8_t* above,
+                             const uint8_t* left);
+#define aom_dc_predictor_8x32 aom_dc_predictor_8x32_c
+
+void aom_dc_predictor_8x4_c(uint8_t* dst,
+                            ptrdiff_t y_stride,
+                            const uint8_t* above,
+                            const uint8_t* left);
+#define aom_dc_predictor_8x4 aom_dc_predictor_8x4_c
+
+void aom_dc_predictor_8x8_c(uint8_t* dst,
+                            ptrdiff_t y_stride,
+                            const uint8_t* above,
+                            const uint8_t* left);
+void aom_dc_predictor_8x8_neon(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_dc_predictor_8x8 aom_dc_predictor_8x8_neon
+
+void aom_dc_top_predictor_16x16_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+void aom_dc_top_predictor_16x16_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_16x16 aom_dc_top_predictor_16x16_neon
+
+void aom_dc_top_predictor_16x32_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_dc_top_predictor_16x32 aom_dc_top_predictor_16x32_c
+
+void aom_dc_top_predictor_16x4_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_top_predictor_16x4 aom_dc_top_predictor_16x4_c
+
+void aom_dc_top_predictor_16x64_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_dc_top_predictor_16x64 aom_dc_top_predictor_16x64_c
+
+void aom_dc_top_predictor_16x8_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_top_predictor_16x8 aom_dc_top_predictor_16x8_c
+
+void aom_dc_top_predictor_2x2_c(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_top_predictor_2x2 aom_dc_top_predictor_2x2_c
+
+void aom_dc_top_predictor_32x16_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_dc_top_predictor_32x16 aom_dc_top_predictor_32x16_c
+
+void aom_dc_top_predictor_32x32_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+void aom_dc_top_predictor_32x32_neon(uint8_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint8_t* above,
+                                     const uint8_t* left);
+#define aom_dc_top_predictor_32x32 aom_dc_top_predictor_32x32_neon
+
+void aom_dc_top_predictor_32x64_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_dc_top_predictor_32x64 aom_dc_top_predictor_32x64_c
+
+void aom_dc_top_predictor_32x8_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_top_predictor_32x8 aom_dc_top_predictor_32x8_c
+
+void aom_dc_top_predictor_4x16_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_top_predictor_4x16 aom_dc_top_predictor_4x16_c
+
+void aom_dc_top_predictor_4x4_c(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+void aom_dc_top_predictor_4x4_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_top_predictor_4x4 aom_dc_top_predictor_4x4_neon
+
+void aom_dc_top_predictor_4x8_c(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_top_predictor_4x8 aom_dc_top_predictor_4x8_c
+
+void aom_dc_top_predictor_64x16_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_dc_top_predictor_64x16 aom_dc_top_predictor_64x16_c
+
+void aom_dc_top_predictor_64x32_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_dc_top_predictor_64x32 aom_dc_top_predictor_64x32_c
+
+void aom_dc_top_predictor_64x64_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_dc_top_predictor_64x64 aom_dc_top_predictor_64x64_c
+
+void aom_dc_top_predictor_8x16_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_top_predictor_8x16 aom_dc_top_predictor_8x16_c
+
+void aom_dc_top_predictor_8x32_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_dc_top_predictor_8x32 aom_dc_top_predictor_8x32_c
+
+void aom_dc_top_predictor_8x4_c(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_dc_top_predictor_8x4 aom_dc_top_predictor_8x4_c
+
+void aom_dc_top_predictor_8x8_c(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+void aom_dc_top_predictor_8x8_neon(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_dc_top_predictor_8x8 aom_dc_top_predictor_8x8_neon
+
+void aom_h_predictor_16x16_c(uint8_t* dst,
+                             ptrdiff_t y_stride,
+                             const uint8_t* above,
+                             const uint8_t* left);
+void aom_h_predictor_16x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_16x16 aom_h_predictor_16x16_neon
+
+void aom_h_predictor_16x32_c(uint8_t* dst,
+                             ptrdiff_t y_stride,
+                             const uint8_t* above,
+                             const uint8_t* left);
+#define aom_h_predictor_16x32 aom_h_predictor_16x32_c
+
+void aom_h_predictor_16x4_c(uint8_t* dst,
+                            ptrdiff_t y_stride,
+                            const uint8_t* above,
+                            const uint8_t* left);
+#define aom_h_predictor_16x4 aom_h_predictor_16x4_c
+
+void aom_h_predictor_16x64_c(uint8_t* dst,
+                             ptrdiff_t y_stride,
+                             const uint8_t* above,
+                             const uint8_t* left);
+#define aom_h_predictor_16x64 aom_h_predictor_16x64_c
+
+void aom_h_predictor_16x8_c(uint8_t* dst,
+                            ptrdiff_t y_stride,
+                            const uint8_t* above,
+                            const uint8_t* left);
+#define aom_h_predictor_16x8 aom_h_predictor_16x8_c
+
+void aom_h_predictor_2x2_c(uint8_t* dst,
+                           ptrdiff_t y_stride,
+                           const uint8_t* above,
+                           const uint8_t* left);
+#define aom_h_predictor_2x2 aom_h_predictor_2x2_c
+
+void aom_h_predictor_32x16_c(uint8_t* dst,
+                             ptrdiff_t y_stride,
+                             const uint8_t* above,
+                             const uint8_t* left);
+#define aom_h_predictor_32x16 aom_h_predictor_32x16_c
+
+void aom_h_predictor_32x32_c(uint8_t* dst,
+                             ptrdiff_t y_stride,
+                             const uint8_t* above,
+                             const uint8_t* left);
+void aom_h_predictor_32x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_h_predictor_32x32 aom_h_predictor_32x32_neon
+
+void aom_h_predictor_32x64_c(uint8_t* dst,
+                             ptrdiff_t y_stride,
+                             const uint8_t* above,
+                             const uint8_t* left);
+#define aom_h_predictor_32x64 aom_h_predictor_32x64_c
+
+void aom_h_predictor_32x8_c(uint8_t* dst,
+                            ptrdiff_t y_stride,
+                            const uint8_t* above,
+                            const uint8_t* left);
+#define aom_h_predictor_32x8 aom_h_predictor_32x8_c
+
+void aom_h_predictor_4x16_c(uint8_t* dst,
+                            ptrdiff_t y_stride,
+                            const uint8_t* above,
+                            const uint8_t* left);
+#define aom_h_predictor_4x16 aom_h_predictor_4x16_c
+
+void aom_h_predictor_4x4_c(uint8_t* dst,
+                           ptrdiff_t y_stride,
+                           const uint8_t* above,
+                           const uint8_t* left);
+void aom_h_predictor_4x4_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_h_predictor_4x4 aom_h_predictor_4x4_neon
+
+void aom_h_predictor_4x8_c(uint8_t* dst,
+                           ptrdiff_t y_stride,
+                           const uint8_t* above,
+                           const uint8_t* left);
+#define aom_h_predictor_4x8 aom_h_predictor_4x8_c
+
+void aom_h_predictor_64x16_c(uint8_t* dst,
+                             ptrdiff_t y_stride,
+                             const uint8_t* above,
+                             const uint8_t* left);
+#define aom_h_predictor_64x16 aom_h_predictor_64x16_c
+
+void aom_h_predictor_64x32_c(uint8_t* dst,
+                             ptrdiff_t y_stride,
+                             const uint8_t* above,
+                             const uint8_t* left);
+#define aom_h_predictor_64x32 aom_h_predictor_64x32_c
+
+void aom_h_predictor_64x64_c(uint8_t* dst,
+                             ptrdiff_t y_stride,
+                             const uint8_t* above,
+                             const uint8_t* left);
+#define aom_h_predictor_64x64 aom_h_predictor_64x64_c
+
+void aom_h_predictor_8x16_c(uint8_t* dst,
+                            ptrdiff_t y_stride,
+                            const uint8_t* above,
+                            const uint8_t* left);
+#define aom_h_predictor_8x16 aom_h_predictor_8x16_c
+
+void aom_h_predictor_8x32_c(uint8_t* dst,
+                            ptrdiff_t y_stride,
+                            const uint8_t* above,
+                            const uint8_t* left);
+#define aom_h_predictor_8x32 aom_h_predictor_8x32_c
+
+void aom_h_predictor_8x4_c(uint8_t* dst,
+                           ptrdiff_t y_stride,
+                           const uint8_t* above,
+                           const uint8_t* left);
+#define aom_h_predictor_8x4 aom_h_predictor_8x4_c
+
+void aom_h_predictor_8x8_c(uint8_t* dst,
+                           ptrdiff_t y_stride,
+                           const uint8_t* above,
+                           const uint8_t* left);
+void aom_h_predictor_8x8_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_h_predictor_8x8 aom_h_predictor_8x8_neon
+
+void aom_highbd_blend_a64_d16_mask_c(uint8_t* dst,
+                                     uint32_t dst_stride,
+                                     const CONV_BUF_TYPE* src0,
+                                     uint32_t src0_stride,
+                                     const CONV_BUF_TYPE* src1,
+                                     uint32_t src1_stride,
+                                     const uint8_t* mask,
+                                     uint32_t mask_stride,
+                                     int w,
+                                     int h,
+                                     int subx,
+                                     int suby,
+                                     ConvolveParams* conv_params,
+                                     const int bd);
+#define aom_highbd_blend_a64_d16_mask aom_highbd_blend_a64_d16_mask_c
+
+void aom_highbd_blend_a64_hmask_c(uint8_t* dst,
+                                  uint32_t dst_stride,
+                                  const uint8_t* src0,
+                                  uint32_t src0_stride,
+                                  const uint8_t* src1,
+                                  uint32_t src1_stride,
+                                  const uint8_t* mask,
+                                  int w,
+                                  int h,
+                                  int bd);
+#define aom_highbd_blend_a64_hmask aom_highbd_blend_a64_hmask_c
+
+void aom_highbd_blend_a64_mask_c(uint8_t* dst,
+                                 uint32_t dst_stride,
+                                 const uint8_t* src0,
+                                 uint32_t src0_stride,
+                                 const uint8_t* src1,
+                                 uint32_t src1_stride,
+                                 const uint8_t* mask,
+                                 uint32_t mask_stride,
+                                 int w,
+                                 int h,
+                                 int subx,
+                                 int suby,
+                                 int bd);
+#define aom_highbd_blend_a64_mask aom_highbd_blend_a64_mask_c
+
+void aom_highbd_blend_a64_vmask_c(uint8_t* dst,
+                                  uint32_t dst_stride,
+                                  const uint8_t* src0,
+                                  uint32_t src0_stride,
+                                  const uint8_t* src1,
+                                  uint32_t src1_stride,
+                                  const uint8_t* mask,
+                                  int w,
+                                  int h,
+                                  int bd);
+#define aom_highbd_blend_a64_vmask aom_highbd_blend_a64_vmask_c
+
+void aom_highbd_convolve8_horiz_c(const uint8_t* src,
+                                  ptrdiff_t src_stride,
+                                  uint8_t* dst,
+                                  ptrdiff_t dst_stride,
+                                  const int16_t* filter_x,
+                                  int x_step_q4,
+                                  const int16_t* filter_y,
+                                  int y_step_q4,
+                                  int w,
+                                  int h,
+                                  int bps);
+#define aom_highbd_convolve8_horiz aom_highbd_convolve8_horiz_c
+
+void aom_highbd_convolve8_vert_c(const uint8_t* src,
+                                 ptrdiff_t src_stride,
+                                 uint8_t* dst,
+                                 ptrdiff_t dst_stride,
+                                 const int16_t* filter_x,
+                                 int x_step_q4,
+                                 const int16_t* filter_y,
+                                 int y_step_q4,
+                                 int w,
+                                 int h,
+                                 int bps);
+#define aom_highbd_convolve8_vert aom_highbd_convolve8_vert_c
+
+void aom_highbd_convolve_copy_c(const uint8_t* src,
+                                ptrdiff_t src_stride,
+                                uint8_t* dst,
+                                ptrdiff_t dst_stride,
+                                const int16_t* filter_x,
+                                int x_step_q4,
+                                const int16_t* filter_y,
+                                int y_step_q4,
+                                int w,
+                                int h,
+                                int bps);
+#define aom_highbd_convolve_copy aom_highbd_convolve_copy_c
+
+void aom_highbd_dc_128_predictor_16x16_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_dc_128_predictor_16x16 aom_highbd_dc_128_predictor_16x16_c
+
+void aom_highbd_dc_128_predictor_16x32_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_dc_128_predictor_16x32 aom_highbd_dc_128_predictor_16x32_c
+
+void aom_highbd_dc_128_predictor_16x4_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_dc_128_predictor_16x4 aom_highbd_dc_128_predictor_16x4_c
+
+void aom_highbd_dc_128_predictor_16x64_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_dc_128_predictor_16x64 aom_highbd_dc_128_predictor_16x64_c
+
+void aom_highbd_dc_128_predictor_16x8_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_dc_128_predictor_16x8 aom_highbd_dc_128_predictor_16x8_c
+
+void aom_highbd_dc_128_predictor_2x2_c(uint16_t* dst,
+                                       ptrdiff_t y_stride,
+                                       const uint16_t* above,
+                                       const uint16_t* left,
+                                       int bd);
+#define aom_highbd_dc_128_predictor_2x2 aom_highbd_dc_128_predictor_2x2_c
+
+void aom_highbd_dc_128_predictor_32x16_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_dc_128_predictor_32x16 aom_highbd_dc_128_predictor_32x16_c
+
+void aom_highbd_dc_128_predictor_32x32_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_dc_128_predictor_32x32 aom_highbd_dc_128_predictor_32x32_c
+
+void aom_highbd_dc_128_predictor_32x64_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_dc_128_predictor_32x64 aom_highbd_dc_128_predictor_32x64_c
+
+void aom_highbd_dc_128_predictor_32x8_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_dc_128_predictor_32x8 aom_highbd_dc_128_predictor_32x8_c
+
+void aom_highbd_dc_128_predictor_4x16_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_dc_128_predictor_4x16 aom_highbd_dc_128_predictor_4x16_c
+
+void aom_highbd_dc_128_predictor_4x4_c(uint16_t* dst,
+                                       ptrdiff_t y_stride,
+                                       const uint16_t* above,
+                                       const uint16_t* left,
+                                       int bd);
+#define aom_highbd_dc_128_predictor_4x4 aom_highbd_dc_128_predictor_4x4_c
+
+void aom_highbd_dc_128_predictor_4x8_c(uint16_t* dst,
+                                       ptrdiff_t y_stride,
+                                       const uint16_t* above,
+                                       const uint16_t* left,
+                                       int bd);
+#define aom_highbd_dc_128_predictor_4x8 aom_highbd_dc_128_predictor_4x8_c
+
+void aom_highbd_dc_128_predictor_64x16_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_dc_128_predictor_64x16 aom_highbd_dc_128_predictor_64x16_c
+
+void aom_highbd_dc_128_predictor_64x32_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_dc_128_predictor_64x32 aom_highbd_dc_128_predictor_64x32_c
+
+void aom_highbd_dc_128_predictor_64x64_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_dc_128_predictor_64x64 aom_highbd_dc_128_predictor_64x64_c
+
+void aom_highbd_dc_128_predictor_8x16_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_dc_128_predictor_8x16 aom_highbd_dc_128_predictor_8x16_c
+
+void aom_highbd_dc_128_predictor_8x32_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_dc_128_predictor_8x32 aom_highbd_dc_128_predictor_8x32_c
+
+void aom_highbd_dc_128_predictor_8x4_c(uint16_t* dst,
+                                       ptrdiff_t y_stride,
+                                       const uint16_t* above,
+                                       const uint16_t* left,
+                                       int bd);
+#define aom_highbd_dc_128_predictor_8x4 aom_highbd_dc_128_predictor_8x4_c
+
+void aom_highbd_dc_128_predictor_8x8_c(uint16_t* dst,
+                                       ptrdiff_t y_stride,
+                                       const uint16_t* above,
+                                       const uint16_t* left,
+                                       int bd);
+#define aom_highbd_dc_128_predictor_8x8 aom_highbd_dc_128_predictor_8x8_c
+
+void aom_highbd_dc_left_predictor_16x16_c(uint16_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint16_t* above,
+                                          const uint16_t* left,
+                                          int bd);
+#define aom_highbd_dc_left_predictor_16x16 aom_highbd_dc_left_predictor_16x16_c
+
+void aom_highbd_dc_left_predictor_16x32_c(uint16_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint16_t* above,
+                                          const uint16_t* left,
+                                          int bd);
+#define aom_highbd_dc_left_predictor_16x32 aom_highbd_dc_left_predictor_16x32_c
+
+void aom_highbd_dc_left_predictor_16x4_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_dc_left_predictor_16x4 aom_highbd_dc_left_predictor_16x4_c
+
+void aom_highbd_dc_left_predictor_16x64_c(uint16_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint16_t* above,
+                                          const uint16_t* left,
+                                          int bd);
+#define aom_highbd_dc_left_predictor_16x64 aom_highbd_dc_left_predictor_16x64_c
+
+void aom_highbd_dc_left_predictor_16x8_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_dc_left_predictor_16x8 aom_highbd_dc_left_predictor_16x8_c
+
+void aom_highbd_dc_left_predictor_2x2_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_dc_left_predictor_2x2 aom_highbd_dc_left_predictor_2x2_c
+
+void aom_highbd_dc_left_predictor_32x16_c(uint16_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint16_t* above,
+                                          const uint16_t* left,
+                                          int bd);
+#define aom_highbd_dc_left_predictor_32x16 aom_highbd_dc_left_predictor_32x16_c
+
+void aom_highbd_dc_left_predictor_32x32_c(uint16_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint16_t* above,
+                                          const uint16_t* left,
+                                          int bd);
+#define aom_highbd_dc_left_predictor_32x32 aom_highbd_dc_left_predictor_32x32_c
+
+void aom_highbd_dc_left_predictor_32x64_c(uint16_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint16_t* above,
+                                          const uint16_t* left,
+                                          int bd);
+#define aom_highbd_dc_left_predictor_32x64 aom_highbd_dc_left_predictor_32x64_c
+
+void aom_highbd_dc_left_predictor_32x8_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_dc_left_predictor_32x8 aom_highbd_dc_left_predictor_32x8_c
+
+void aom_highbd_dc_left_predictor_4x16_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_dc_left_predictor_4x16 aom_highbd_dc_left_predictor_4x16_c
+
+void aom_highbd_dc_left_predictor_4x4_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_dc_left_predictor_4x4 aom_highbd_dc_left_predictor_4x4_c
+
+void aom_highbd_dc_left_predictor_4x8_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_dc_left_predictor_4x8 aom_highbd_dc_left_predictor_4x8_c
+
+void aom_highbd_dc_left_predictor_64x16_c(uint16_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint16_t* above,
+                                          const uint16_t* left,
+                                          int bd);
+#define aom_highbd_dc_left_predictor_64x16 aom_highbd_dc_left_predictor_64x16_c
+
+void aom_highbd_dc_left_predictor_64x32_c(uint16_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint16_t* above,
+                                          const uint16_t* left,
+                                          int bd);
+#define aom_highbd_dc_left_predictor_64x32 aom_highbd_dc_left_predictor_64x32_c
+
+void aom_highbd_dc_left_predictor_64x64_c(uint16_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint16_t* above,
+                                          const uint16_t* left,
+                                          int bd);
+#define aom_highbd_dc_left_predictor_64x64 aom_highbd_dc_left_predictor_64x64_c
+
+void aom_highbd_dc_left_predictor_8x16_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_dc_left_predictor_8x16 aom_highbd_dc_left_predictor_8x16_c
+
+void aom_highbd_dc_left_predictor_8x32_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_dc_left_predictor_8x32 aom_highbd_dc_left_predictor_8x32_c
+
+void aom_highbd_dc_left_predictor_8x4_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_dc_left_predictor_8x4 aom_highbd_dc_left_predictor_8x4_c
+
+void aom_highbd_dc_left_predictor_8x8_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_dc_left_predictor_8x8 aom_highbd_dc_left_predictor_8x8_c
+
+void aom_highbd_dc_predictor_16x16_c(uint16_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint16_t* above,
+                                     const uint16_t* left,
+                                     int bd);
+void aom_highbd_dc_predictor_16x16_neon(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_dc_predictor_16x16 aom_highbd_dc_predictor_16x16_neon
+
+void aom_highbd_dc_predictor_16x32_c(uint16_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint16_t* above,
+                                     const uint16_t* left,
+                                     int bd);
+#define aom_highbd_dc_predictor_16x32 aom_highbd_dc_predictor_16x32_c
+
+void aom_highbd_dc_predictor_16x4_c(uint16_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint16_t* above,
+                                    const uint16_t* left,
+                                    int bd);
+#define aom_highbd_dc_predictor_16x4 aom_highbd_dc_predictor_16x4_c
+
+void aom_highbd_dc_predictor_16x64_c(uint16_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint16_t* above,
+                                     const uint16_t* left,
+                                     int bd);
+#define aom_highbd_dc_predictor_16x64 aom_highbd_dc_predictor_16x64_c
+
+void aom_highbd_dc_predictor_16x8_c(uint16_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint16_t* above,
+                                    const uint16_t* left,
+                                    int bd);
+#define aom_highbd_dc_predictor_16x8 aom_highbd_dc_predictor_16x8_c
+
+void aom_highbd_dc_predictor_2x2_c(uint16_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint16_t* above,
+                                   const uint16_t* left,
+                                   int bd);
+#define aom_highbd_dc_predictor_2x2 aom_highbd_dc_predictor_2x2_c
+
+void aom_highbd_dc_predictor_32x16_c(uint16_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint16_t* above,
+                                     const uint16_t* left,
+                                     int bd);
+#define aom_highbd_dc_predictor_32x16 aom_highbd_dc_predictor_32x16_c
+
+void aom_highbd_dc_predictor_32x32_c(uint16_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint16_t* above,
+                                     const uint16_t* left,
+                                     int bd);
+void aom_highbd_dc_predictor_32x32_neon(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_dc_predictor_32x32 aom_highbd_dc_predictor_32x32_neon
+
+void aom_highbd_dc_predictor_32x64_c(uint16_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint16_t* above,
+                                     const uint16_t* left,
+                                     int bd);
+#define aom_highbd_dc_predictor_32x64 aom_highbd_dc_predictor_32x64_c
+
+void aom_highbd_dc_predictor_32x8_c(uint16_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint16_t* above,
+                                    const uint16_t* left,
+                                    int bd);
+#define aom_highbd_dc_predictor_32x8 aom_highbd_dc_predictor_32x8_c
+
+void aom_highbd_dc_predictor_4x16_c(uint16_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint16_t* above,
+                                    const uint16_t* left,
+                                    int bd);
+#define aom_highbd_dc_predictor_4x16 aom_highbd_dc_predictor_4x16_c
+
+void aom_highbd_dc_predictor_4x4_c(uint16_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint16_t* above,
+                                   const uint16_t* left,
+                                   int bd);
+void aom_highbd_dc_predictor_4x4_neon(uint16_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint16_t* above,
+                                      const uint16_t* left,
+                                      int bd);
+#define aom_highbd_dc_predictor_4x4 aom_highbd_dc_predictor_4x4_neon
+
+void aom_highbd_dc_predictor_4x8_c(uint16_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint16_t* above,
+                                   const uint16_t* left,
+                                   int bd);
+#define aom_highbd_dc_predictor_4x8 aom_highbd_dc_predictor_4x8_c
+
+void aom_highbd_dc_predictor_64x16_c(uint16_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint16_t* above,
+                                     const uint16_t* left,
+                                     int bd);
+#define aom_highbd_dc_predictor_64x16 aom_highbd_dc_predictor_64x16_c
+
+void aom_highbd_dc_predictor_64x32_c(uint16_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint16_t* above,
+                                     const uint16_t* left,
+                                     int bd);
+#define aom_highbd_dc_predictor_64x32 aom_highbd_dc_predictor_64x32_c
+
+void aom_highbd_dc_predictor_64x64_c(uint16_t* dst,
+                                     ptrdiff_t y_stride,
+                                     const uint16_t* above,
+                                     const uint16_t* left,
+                                     int bd);
+void aom_highbd_dc_predictor_64x64_neon(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_dc_predictor_64x64 aom_highbd_dc_predictor_64x64_neon
+
+void aom_highbd_dc_predictor_8x16_c(uint16_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint16_t* above,
+                                    const uint16_t* left,
+                                    int bd);
+#define aom_highbd_dc_predictor_8x16 aom_highbd_dc_predictor_8x16_c
+
+void aom_highbd_dc_predictor_8x32_c(uint16_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint16_t* above,
+                                    const uint16_t* left,
+                                    int bd);
+#define aom_highbd_dc_predictor_8x32 aom_highbd_dc_predictor_8x32_c
+
+void aom_highbd_dc_predictor_8x4_c(uint16_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint16_t* above,
+                                   const uint16_t* left,
+                                   int bd);
+#define aom_highbd_dc_predictor_8x4 aom_highbd_dc_predictor_8x4_c
+
+void aom_highbd_dc_predictor_8x8_c(uint16_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint16_t* above,
+                                   const uint16_t* left,
+                                   int bd);
+void aom_highbd_dc_predictor_8x8_neon(uint16_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint16_t* above,
+                                      const uint16_t* left,
+                                      int bd);
+#define aom_highbd_dc_predictor_8x8 aom_highbd_dc_predictor_8x8_neon
+
+void aom_highbd_dc_top_predictor_16x16_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_dc_top_predictor_16x16 aom_highbd_dc_top_predictor_16x16_c
+
+void aom_highbd_dc_top_predictor_16x32_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_dc_top_predictor_16x32 aom_highbd_dc_top_predictor_16x32_c
+
+void aom_highbd_dc_top_predictor_16x4_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_dc_top_predictor_16x4 aom_highbd_dc_top_predictor_16x4_c
+
+void aom_highbd_dc_top_predictor_16x64_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_dc_top_predictor_16x64 aom_highbd_dc_top_predictor_16x64_c
+
+void aom_highbd_dc_top_predictor_16x8_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_dc_top_predictor_16x8 aom_highbd_dc_top_predictor_16x8_c
+
+void aom_highbd_dc_top_predictor_2x2_c(uint16_t* dst,
+                                       ptrdiff_t y_stride,
+                                       const uint16_t* above,
+                                       const uint16_t* left,
+                                       int bd);
+#define aom_highbd_dc_top_predictor_2x2 aom_highbd_dc_top_predictor_2x2_c
+
+void aom_highbd_dc_top_predictor_32x16_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_dc_top_predictor_32x16 aom_highbd_dc_top_predictor_32x16_c
+
+void aom_highbd_dc_top_predictor_32x32_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_dc_top_predictor_32x32 aom_highbd_dc_top_predictor_32x32_c
+
+void aom_highbd_dc_top_predictor_32x64_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_dc_top_predictor_32x64 aom_highbd_dc_top_predictor_32x64_c
+
+void aom_highbd_dc_top_predictor_32x8_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_dc_top_predictor_32x8 aom_highbd_dc_top_predictor_32x8_c
+
+void aom_highbd_dc_top_predictor_4x16_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_dc_top_predictor_4x16 aom_highbd_dc_top_predictor_4x16_c
+
+void aom_highbd_dc_top_predictor_4x4_c(uint16_t* dst,
+                                       ptrdiff_t y_stride,
+                                       const uint16_t* above,
+                                       const uint16_t* left,
+                                       int bd);
+#define aom_highbd_dc_top_predictor_4x4 aom_highbd_dc_top_predictor_4x4_c
+
+void aom_highbd_dc_top_predictor_4x8_c(uint16_t* dst,
+                                       ptrdiff_t y_stride,
+                                       const uint16_t* above,
+                                       const uint16_t* left,
+                                       int bd);
+#define aom_highbd_dc_top_predictor_4x8 aom_highbd_dc_top_predictor_4x8_c
+
+void aom_highbd_dc_top_predictor_64x16_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_dc_top_predictor_64x16 aom_highbd_dc_top_predictor_64x16_c
+
+void aom_highbd_dc_top_predictor_64x32_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_dc_top_predictor_64x32 aom_highbd_dc_top_predictor_64x32_c
+
+void aom_highbd_dc_top_predictor_64x64_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_dc_top_predictor_64x64 aom_highbd_dc_top_predictor_64x64_c
+
+void aom_highbd_dc_top_predictor_8x16_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_dc_top_predictor_8x16 aom_highbd_dc_top_predictor_8x16_c
+
+void aom_highbd_dc_top_predictor_8x32_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_dc_top_predictor_8x32 aom_highbd_dc_top_predictor_8x32_c
+
+void aom_highbd_dc_top_predictor_8x4_c(uint16_t* dst,
+                                       ptrdiff_t y_stride,
+                                       const uint16_t* above,
+                                       const uint16_t* left,
+                                       int bd);
+#define aom_highbd_dc_top_predictor_8x4 aom_highbd_dc_top_predictor_8x4_c
+
+void aom_highbd_dc_top_predictor_8x8_c(uint16_t* dst,
+                                       ptrdiff_t y_stride,
+                                       const uint16_t* above,
+                                       const uint16_t* left,
+                                       int bd);
+#define aom_highbd_dc_top_predictor_8x8 aom_highbd_dc_top_predictor_8x8_c
+
+void aom_highbd_h_predictor_16x16_c(uint16_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint16_t* above,
+                                    const uint16_t* left,
+                                    int bd);
+#define aom_highbd_h_predictor_16x16 aom_highbd_h_predictor_16x16_c
+
+void aom_highbd_h_predictor_16x32_c(uint16_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint16_t* above,
+                                    const uint16_t* left,
+                                    int bd);
+#define aom_highbd_h_predictor_16x32 aom_highbd_h_predictor_16x32_c
+
+void aom_highbd_h_predictor_16x4_c(uint16_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint16_t* above,
+                                   const uint16_t* left,
+                                   int bd);
+#define aom_highbd_h_predictor_16x4 aom_highbd_h_predictor_16x4_c
+
+void aom_highbd_h_predictor_16x64_c(uint16_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint16_t* above,
+                                    const uint16_t* left,
+                                    int bd);
+#define aom_highbd_h_predictor_16x64 aom_highbd_h_predictor_16x64_c
+
+void aom_highbd_h_predictor_16x8_c(uint16_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint16_t* above,
+                                   const uint16_t* left,
+                                   int bd);
+#define aom_highbd_h_predictor_16x8 aom_highbd_h_predictor_16x8_c
+
+void aom_highbd_h_predictor_2x2_c(uint16_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint16_t* above,
+                                  const uint16_t* left,
+                                  int bd);
+#define aom_highbd_h_predictor_2x2 aom_highbd_h_predictor_2x2_c
+
+void aom_highbd_h_predictor_32x16_c(uint16_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint16_t* above,
+                                    const uint16_t* left,
+                                    int bd);
+#define aom_highbd_h_predictor_32x16 aom_highbd_h_predictor_32x16_c
+
+void aom_highbd_h_predictor_32x32_c(uint16_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint16_t* above,
+                                    const uint16_t* left,
+                                    int bd);
+#define aom_highbd_h_predictor_32x32 aom_highbd_h_predictor_32x32_c
+
+void aom_highbd_h_predictor_32x64_c(uint16_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint16_t* above,
+                                    const uint16_t* left,
+                                    int bd);
+#define aom_highbd_h_predictor_32x64 aom_highbd_h_predictor_32x64_c
+
+void aom_highbd_h_predictor_32x8_c(uint16_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint16_t* above,
+                                   const uint16_t* left,
+                                   int bd);
+#define aom_highbd_h_predictor_32x8 aom_highbd_h_predictor_32x8_c
+
+void aom_highbd_h_predictor_4x16_c(uint16_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint16_t* above,
+                                   const uint16_t* left,
+                                   int bd);
+#define aom_highbd_h_predictor_4x16 aom_highbd_h_predictor_4x16_c
+
+void aom_highbd_h_predictor_4x4_c(uint16_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint16_t* above,
+                                  const uint16_t* left,
+                                  int bd);
+#define aom_highbd_h_predictor_4x4 aom_highbd_h_predictor_4x4_c
+
+void aom_highbd_h_predictor_4x8_c(uint16_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint16_t* above,
+                                  const uint16_t* left,
+                                  int bd);
+#define aom_highbd_h_predictor_4x8 aom_highbd_h_predictor_4x8_c
+
+void aom_highbd_h_predictor_64x16_c(uint16_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint16_t* above,
+                                    const uint16_t* left,
+                                    int bd);
+#define aom_highbd_h_predictor_64x16 aom_highbd_h_predictor_64x16_c
+
+void aom_highbd_h_predictor_64x32_c(uint16_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint16_t* above,
+                                    const uint16_t* left,
+                                    int bd);
+#define aom_highbd_h_predictor_64x32 aom_highbd_h_predictor_64x32_c
+
+void aom_highbd_h_predictor_64x64_c(uint16_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint16_t* above,
+                                    const uint16_t* left,
+                                    int bd);
+#define aom_highbd_h_predictor_64x64 aom_highbd_h_predictor_64x64_c
+
+void aom_highbd_h_predictor_8x16_c(uint16_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint16_t* above,
+                                   const uint16_t* left,
+                                   int bd);
+#define aom_highbd_h_predictor_8x16 aom_highbd_h_predictor_8x16_c
+
+void aom_highbd_h_predictor_8x32_c(uint16_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint16_t* above,
+                                   const uint16_t* left,
+                                   int bd);
+#define aom_highbd_h_predictor_8x32 aom_highbd_h_predictor_8x32_c
+
+void aom_highbd_h_predictor_8x4_c(uint16_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint16_t* above,
+                                  const uint16_t* left,
+                                  int bd);
+#define aom_highbd_h_predictor_8x4 aom_highbd_h_predictor_8x4_c
+
+void aom_highbd_h_predictor_8x8_c(uint16_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint16_t* above,
+                                  const uint16_t* left,
+                                  int bd);
+#define aom_highbd_h_predictor_8x8 aom_highbd_h_predictor_8x8_c
+
+void aom_highbd_lpf_horizontal_14_c(uint16_t* s,
+                                    int pitch,
+                                    const uint8_t* blimit,
+                                    const uint8_t* limit,
+                                    const uint8_t* thresh,
+                                    int bd);
+#define aom_highbd_lpf_horizontal_14 aom_highbd_lpf_horizontal_14_c
+
+void aom_highbd_lpf_horizontal_14_dual_c(uint16_t* s,
+                                         int pitch,
+                                         const uint8_t* blimit0,
+                                         const uint8_t* limit0,
+                                         const uint8_t* thresh0,
+                                         const uint8_t* blimit1,
+                                         const uint8_t* limt1,
+                                         const uint8_t* thresh1,
+                                         int bd);
+#define aom_highbd_lpf_horizontal_14_dual aom_highbd_lpf_horizontal_14_dual_c
+
+void aom_highbd_lpf_horizontal_4_c(uint16_t* s,
+                                   int pitch,
+                                   const uint8_t* blimit,
+                                   const uint8_t* limit,
+                                   const uint8_t* thresh,
+                                   int bd);
+#define aom_highbd_lpf_horizontal_4 aom_highbd_lpf_horizontal_4_c
+
+void aom_highbd_lpf_horizontal_4_dual_c(uint16_t* s,
+                                        int pitch,
+                                        const uint8_t* blimit0,
+                                        const uint8_t* limit0,
+                                        const uint8_t* thresh0,
+                                        const uint8_t* blimit1,
+                                        const uint8_t* limit1,
+                                        const uint8_t* thresh1,
+                                        int bd);
+#define aom_highbd_lpf_horizontal_4_dual aom_highbd_lpf_horizontal_4_dual_c
+
+void aom_highbd_lpf_horizontal_6_c(uint16_t* s,
+                                   int pitch,
+                                   const uint8_t* blimit,
+                                   const uint8_t* limit,
+                                   const uint8_t* thresh,
+                                   int bd);
+#define aom_highbd_lpf_horizontal_6 aom_highbd_lpf_horizontal_6_c
+
+void aom_highbd_lpf_horizontal_6_dual_c(uint16_t* s,
+                                        int pitch,
+                                        const uint8_t* blimit0,
+                                        const uint8_t* limit0,
+                                        const uint8_t* thresh0,
+                                        const uint8_t* blimit1,
+                                        const uint8_t* limit1,
+                                        const uint8_t* thresh1,
+                                        int bd);
+#define aom_highbd_lpf_horizontal_6_dual aom_highbd_lpf_horizontal_6_dual_c
+
+void aom_highbd_lpf_horizontal_8_c(uint16_t* s,
+                                   int pitch,
+                                   const uint8_t* blimit,
+                                   const uint8_t* limit,
+                                   const uint8_t* thresh,
+                                   int bd);
+#define aom_highbd_lpf_horizontal_8 aom_highbd_lpf_horizontal_8_c
+
+void aom_highbd_lpf_horizontal_8_dual_c(uint16_t* s,
+                                        int pitch,
+                                        const uint8_t* blimit0,
+                                        const uint8_t* limit0,
+                                        const uint8_t* thresh0,
+                                        const uint8_t* blimit1,
+                                        const uint8_t* limit1,
+                                        const uint8_t* thresh1,
+                                        int bd);
+#define aom_highbd_lpf_horizontal_8_dual aom_highbd_lpf_horizontal_8_dual_c
+
+void aom_highbd_lpf_vertical_14_c(uint16_t* s,
+                                  int pitch,
+                                  const uint8_t* blimit,
+                                  const uint8_t* limit,
+                                  const uint8_t* thresh,
+                                  int bd);
+#define aom_highbd_lpf_vertical_14 aom_highbd_lpf_vertical_14_c
+
+void aom_highbd_lpf_vertical_14_dual_c(uint16_t* s,
+                                       int pitch,
+                                       const uint8_t* blimit0,
+                                       const uint8_t* limit0,
+                                       const uint8_t* thresh0,
+                                       const uint8_t* blimit1,
+                                       const uint8_t* limit1,
+                                       const uint8_t* thresh1,
+                                       int bd);
+#define aom_highbd_lpf_vertical_14_dual aom_highbd_lpf_vertical_14_dual_c
+
+void aom_highbd_lpf_vertical_4_c(uint16_t* s,
+                                 int pitch,
+                                 const uint8_t* blimit,
+                                 const uint8_t* limit,
+                                 const uint8_t* thresh,
+                                 int bd);
+#define aom_highbd_lpf_vertical_4 aom_highbd_lpf_vertical_4_c
+
+void aom_highbd_lpf_vertical_4_dual_c(uint16_t* s,
+                                      int pitch,
+                                      const uint8_t* blimit0,
+                                      const uint8_t* limit0,
+                                      const uint8_t* thresh0,
+                                      const uint8_t* blimit1,
+                                      const uint8_t* limit1,
+                                      const uint8_t* thresh1,
+                                      int bd);
+#define aom_highbd_lpf_vertical_4_dual aom_highbd_lpf_vertical_4_dual_c
+
+void aom_highbd_lpf_vertical_6_c(uint16_t* s,
+                                 int pitch,
+                                 const uint8_t* blimit,
+                                 const uint8_t* limit,
+                                 const uint8_t* thresh,
+                                 int bd);
+#define aom_highbd_lpf_vertical_6 aom_highbd_lpf_vertical_6_c
+
+void aom_highbd_lpf_vertical_6_dual_c(uint16_t* s,
+                                      int pitch,
+                                      const uint8_t* blimit0,
+                                      const uint8_t* limit0,
+                                      const uint8_t* thresh0,
+                                      const uint8_t* blimit1,
+                                      const uint8_t* limit1,
+                                      const uint8_t* thresh1,
+                                      int bd);
+#define aom_highbd_lpf_vertical_6_dual aom_highbd_lpf_vertical_6_dual_c
+
+void aom_highbd_lpf_vertical_8_c(uint16_t* s,
+                                 int pitch,
+                                 const uint8_t* blimit,
+                                 const uint8_t* limit,
+                                 const uint8_t* thresh,
+                                 int bd);
+#define aom_highbd_lpf_vertical_8 aom_highbd_lpf_vertical_8_c
+
+void aom_highbd_lpf_vertical_8_dual_c(uint16_t* s,
+                                      int pitch,
+                                      const uint8_t* blimit0,
+                                      const uint8_t* limit0,
+                                      const uint8_t* thresh0,
+                                      const uint8_t* blimit1,
+                                      const uint8_t* limit1,
+                                      const uint8_t* thresh1,
+                                      int bd);
+#define aom_highbd_lpf_vertical_8_dual aom_highbd_lpf_vertical_8_dual_c
+
+void aom_highbd_paeth_predictor_16x16_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_paeth_predictor_16x16 aom_highbd_paeth_predictor_16x16_c
+
+void aom_highbd_paeth_predictor_16x32_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_paeth_predictor_16x32 aom_highbd_paeth_predictor_16x32_c
+
+void aom_highbd_paeth_predictor_16x4_c(uint16_t* dst,
+                                       ptrdiff_t y_stride,
+                                       const uint16_t* above,
+                                       const uint16_t* left,
+                                       int bd);
+#define aom_highbd_paeth_predictor_16x4 aom_highbd_paeth_predictor_16x4_c
+
+void aom_highbd_paeth_predictor_16x64_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_paeth_predictor_16x64 aom_highbd_paeth_predictor_16x64_c
+
+void aom_highbd_paeth_predictor_16x8_c(uint16_t* dst,
+                                       ptrdiff_t y_stride,
+                                       const uint16_t* above,
+                                       const uint16_t* left,
+                                       int bd);
+#define aom_highbd_paeth_predictor_16x8 aom_highbd_paeth_predictor_16x8_c
+
+void aom_highbd_paeth_predictor_2x2_c(uint16_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint16_t* above,
+                                      const uint16_t* left,
+                                      int bd);
+#define aom_highbd_paeth_predictor_2x2 aom_highbd_paeth_predictor_2x2_c
+
+void aom_highbd_paeth_predictor_32x16_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_paeth_predictor_32x16 aom_highbd_paeth_predictor_32x16_c
+
+void aom_highbd_paeth_predictor_32x32_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_paeth_predictor_32x32 aom_highbd_paeth_predictor_32x32_c
+
+void aom_highbd_paeth_predictor_32x64_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_paeth_predictor_32x64 aom_highbd_paeth_predictor_32x64_c
+
+void aom_highbd_paeth_predictor_32x8_c(uint16_t* dst,
+                                       ptrdiff_t y_stride,
+                                       const uint16_t* above,
+                                       const uint16_t* left,
+                                       int bd);
+#define aom_highbd_paeth_predictor_32x8 aom_highbd_paeth_predictor_32x8_c
+
+void aom_highbd_paeth_predictor_4x16_c(uint16_t* dst,
+                                       ptrdiff_t y_stride,
+                                       const uint16_t* above,
+                                       const uint16_t* left,
+                                       int bd);
+#define aom_highbd_paeth_predictor_4x16 aom_highbd_paeth_predictor_4x16_c
+
+void aom_highbd_paeth_predictor_4x4_c(uint16_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint16_t* above,
+                                      const uint16_t* left,
+                                      int bd);
+#define aom_highbd_paeth_predictor_4x4 aom_highbd_paeth_predictor_4x4_c
+
+void aom_highbd_paeth_predictor_4x8_c(uint16_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint16_t* above,
+                                      const uint16_t* left,
+                                      int bd);
+#define aom_highbd_paeth_predictor_4x8 aom_highbd_paeth_predictor_4x8_c
+
+void aom_highbd_paeth_predictor_64x16_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_paeth_predictor_64x16 aom_highbd_paeth_predictor_64x16_c
+
+void aom_highbd_paeth_predictor_64x32_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_paeth_predictor_64x32 aom_highbd_paeth_predictor_64x32_c
+
+void aom_highbd_paeth_predictor_64x64_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_paeth_predictor_64x64 aom_highbd_paeth_predictor_64x64_c
+
+void aom_highbd_paeth_predictor_8x16_c(uint16_t* dst,
+                                       ptrdiff_t y_stride,
+                                       const uint16_t* above,
+                                       const uint16_t* left,
+                                       int bd);
+#define aom_highbd_paeth_predictor_8x16 aom_highbd_paeth_predictor_8x16_c
+
+void aom_highbd_paeth_predictor_8x32_c(uint16_t* dst,
+                                       ptrdiff_t y_stride,
+                                       const uint16_t* above,
+                                       const uint16_t* left,
+                                       int bd);
+#define aom_highbd_paeth_predictor_8x32 aom_highbd_paeth_predictor_8x32_c
+
+void aom_highbd_paeth_predictor_8x4_c(uint16_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint16_t* above,
+                                      const uint16_t* left,
+                                      int bd);
+#define aom_highbd_paeth_predictor_8x4 aom_highbd_paeth_predictor_8x4_c
+
+void aom_highbd_paeth_predictor_8x8_c(uint16_t* dst,
+                                      ptrdiff_t y_stride,
+                                      const uint16_t* above,
+                                      const uint16_t* left,
+                                      int bd);
+#define aom_highbd_paeth_predictor_8x8 aom_highbd_paeth_predictor_8x8_c
+
+void aom_highbd_smooth_h_predictor_16x16_c(uint16_t* dst,
+                                           ptrdiff_t y_stride,
+                                           const uint16_t* above,
+                                           const uint16_t* left,
+                                           int bd);
+#define aom_highbd_smooth_h_predictor_16x16 \
+  aom_highbd_smooth_h_predictor_16x16_c
+
+void aom_highbd_smooth_h_predictor_16x32_c(uint16_t* dst,
+                                           ptrdiff_t y_stride,
+                                           const uint16_t* above,
+                                           const uint16_t* left,
+                                           int bd);
+#define aom_highbd_smooth_h_predictor_16x32 \
+  aom_highbd_smooth_h_predictor_16x32_c
+
+void aom_highbd_smooth_h_predictor_16x4_c(uint16_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint16_t* above,
+                                          const uint16_t* left,
+                                          int bd);
+#define aom_highbd_smooth_h_predictor_16x4 aom_highbd_smooth_h_predictor_16x4_c
+
+void aom_highbd_smooth_h_predictor_16x64_c(uint16_t* dst,
+                                           ptrdiff_t y_stride,
+                                           const uint16_t* above,
+                                           const uint16_t* left,
+                                           int bd);
+#define aom_highbd_smooth_h_predictor_16x64 \
+  aom_highbd_smooth_h_predictor_16x64_c
+
+void aom_highbd_smooth_h_predictor_16x8_c(uint16_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint16_t* above,
+                                          const uint16_t* left,
+                                          int bd);
+#define aom_highbd_smooth_h_predictor_16x8 aom_highbd_smooth_h_predictor_16x8_c
+
+void aom_highbd_smooth_h_predictor_2x2_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_smooth_h_predictor_2x2 aom_highbd_smooth_h_predictor_2x2_c
+
+void aom_highbd_smooth_h_predictor_32x16_c(uint16_t* dst,
+                                           ptrdiff_t y_stride,
+                                           const uint16_t* above,
+                                           const uint16_t* left,
+                                           int bd);
+#define aom_highbd_smooth_h_predictor_32x16 \
+  aom_highbd_smooth_h_predictor_32x16_c
+
+void aom_highbd_smooth_h_predictor_32x32_c(uint16_t* dst,
+                                           ptrdiff_t y_stride,
+                                           const uint16_t* above,
+                                           const uint16_t* left,
+                                           int bd);
+#define aom_highbd_smooth_h_predictor_32x32 \
+  aom_highbd_smooth_h_predictor_32x32_c
+
+void aom_highbd_smooth_h_predictor_32x64_c(uint16_t* dst,
+                                           ptrdiff_t y_stride,
+                                           const uint16_t* above,
+                                           const uint16_t* left,
+                                           int bd);
+#define aom_highbd_smooth_h_predictor_32x64 \
+  aom_highbd_smooth_h_predictor_32x64_c
+
+void aom_highbd_smooth_h_predictor_32x8_c(uint16_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint16_t* above,
+                                          const uint16_t* left,
+                                          int bd);
+#define aom_highbd_smooth_h_predictor_32x8 aom_highbd_smooth_h_predictor_32x8_c
+
+void aom_highbd_smooth_h_predictor_4x16_c(uint16_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint16_t* above,
+                                          const uint16_t* left,
+                                          int bd);
+#define aom_highbd_smooth_h_predictor_4x16 aom_highbd_smooth_h_predictor_4x16_c
+
+void aom_highbd_smooth_h_predictor_4x4_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_smooth_h_predictor_4x4 aom_highbd_smooth_h_predictor_4x4_c
+
+void aom_highbd_smooth_h_predictor_4x8_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_smooth_h_predictor_4x8 aom_highbd_smooth_h_predictor_4x8_c
+
+void aom_highbd_smooth_h_predictor_64x16_c(uint16_t* dst,
+                                           ptrdiff_t y_stride,
+                                           const uint16_t* above,
+                                           const uint16_t* left,
+                                           int bd);
+#define aom_highbd_smooth_h_predictor_64x16 \
+  aom_highbd_smooth_h_predictor_64x16_c
+
+void aom_highbd_smooth_h_predictor_64x32_c(uint16_t* dst,
+                                           ptrdiff_t y_stride,
+                                           const uint16_t* above,
+                                           const uint16_t* left,
+                                           int bd);
+#define aom_highbd_smooth_h_predictor_64x32 \
+  aom_highbd_smooth_h_predictor_64x32_c
+
+void aom_highbd_smooth_h_predictor_64x64_c(uint16_t* dst,
+                                           ptrdiff_t y_stride,
+                                           const uint16_t* above,
+                                           const uint16_t* left,
+                                           int bd);
+#define aom_highbd_smooth_h_predictor_64x64 \
+  aom_highbd_smooth_h_predictor_64x64_c
+
+void aom_highbd_smooth_h_predictor_8x16_c(uint16_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint16_t* above,
+                                          const uint16_t* left,
+                                          int bd);
+#define aom_highbd_smooth_h_predictor_8x16 aom_highbd_smooth_h_predictor_8x16_c
+
+void aom_highbd_smooth_h_predictor_8x32_c(uint16_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint16_t* above,
+                                          const uint16_t* left,
+                                          int bd);
+#define aom_highbd_smooth_h_predictor_8x32 aom_highbd_smooth_h_predictor_8x32_c
+
+void aom_highbd_smooth_h_predictor_8x4_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_smooth_h_predictor_8x4 aom_highbd_smooth_h_predictor_8x4_c
+
+void aom_highbd_smooth_h_predictor_8x8_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_smooth_h_predictor_8x8 aom_highbd_smooth_h_predictor_8x8_c
+
+void aom_highbd_smooth_predictor_16x16_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_smooth_predictor_16x16 aom_highbd_smooth_predictor_16x16_c
+
+void aom_highbd_smooth_predictor_16x32_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_smooth_predictor_16x32 aom_highbd_smooth_predictor_16x32_c
+
+void aom_highbd_smooth_predictor_16x4_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_smooth_predictor_16x4 aom_highbd_smooth_predictor_16x4_c
+
+void aom_highbd_smooth_predictor_16x64_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_smooth_predictor_16x64 aom_highbd_smooth_predictor_16x64_c
+
+void aom_highbd_smooth_predictor_16x8_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_smooth_predictor_16x8 aom_highbd_smooth_predictor_16x8_c
+
+void aom_highbd_smooth_predictor_2x2_c(uint16_t* dst,
+                                       ptrdiff_t y_stride,
+                                       const uint16_t* above,
+                                       const uint16_t* left,
+                                       int bd);
+#define aom_highbd_smooth_predictor_2x2 aom_highbd_smooth_predictor_2x2_c
+
+void aom_highbd_smooth_predictor_32x16_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_smooth_predictor_32x16 aom_highbd_smooth_predictor_32x16_c
+
+void aom_highbd_smooth_predictor_32x32_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_smooth_predictor_32x32 aom_highbd_smooth_predictor_32x32_c
+
+void aom_highbd_smooth_predictor_32x64_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_smooth_predictor_32x64 aom_highbd_smooth_predictor_32x64_c
+
+void aom_highbd_smooth_predictor_32x8_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_smooth_predictor_32x8 aom_highbd_smooth_predictor_32x8_c
+
+void aom_highbd_smooth_predictor_4x16_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_smooth_predictor_4x16 aom_highbd_smooth_predictor_4x16_c
+
+void aom_highbd_smooth_predictor_4x4_c(uint16_t* dst,
+                                       ptrdiff_t y_stride,
+                                       const uint16_t* above,
+                                       const uint16_t* left,
+                                       int bd);
+#define aom_highbd_smooth_predictor_4x4 aom_highbd_smooth_predictor_4x4_c
+
+void aom_highbd_smooth_predictor_4x8_c(uint16_t* dst,
+                                       ptrdiff_t y_stride,
+                                       const uint16_t* above,
+                                       const uint16_t* left,
+                                       int bd);
+#define aom_highbd_smooth_predictor_4x8 aom_highbd_smooth_predictor_4x8_c
+
+void aom_highbd_smooth_predictor_64x16_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_smooth_predictor_64x16 aom_highbd_smooth_predictor_64x16_c
+
+void aom_highbd_smooth_predictor_64x32_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_smooth_predictor_64x32 aom_highbd_smooth_predictor_64x32_c
+
+void aom_highbd_smooth_predictor_64x64_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_smooth_predictor_64x64 aom_highbd_smooth_predictor_64x64_c
+
+void aom_highbd_smooth_predictor_8x16_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_smooth_predictor_8x16 aom_highbd_smooth_predictor_8x16_c
+
+void aom_highbd_smooth_predictor_8x32_c(uint16_t* dst,
+                                        ptrdiff_t y_stride,
+                                        const uint16_t* above,
+                                        const uint16_t* left,
+                                        int bd);
+#define aom_highbd_smooth_predictor_8x32 aom_highbd_smooth_predictor_8x32_c
+
+void aom_highbd_smooth_predictor_8x4_c(uint16_t* dst,
+                                       ptrdiff_t y_stride,
+                                       const uint16_t* above,
+                                       const uint16_t* left,
+                                       int bd);
+#define aom_highbd_smooth_predictor_8x4 aom_highbd_smooth_predictor_8x4_c
+
+void aom_highbd_smooth_predictor_8x8_c(uint16_t* dst,
+                                       ptrdiff_t y_stride,
+                                       const uint16_t* above,
+                                       const uint16_t* left,
+                                       int bd);
+#define aom_highbd_smooth_predictor_8x8 aom_highbd_smooth_predictor_8x8_c
+
+void aom_highbd_smooth_v_predictor_16x16_c(uint16_t* dst,
+                                           ptrdiff_t y_stride,
+                                           const uint16_t* above,
+                                           const uint16_t* left,
+                                           int bd);
+#define aom_highbd_smooth_v_predictor_16x16 \
+  aom_highbd_smooth_v_predictor_16x16_c
+
+void aom_highbd_smooth_v_predictor_16x32_c(uint16_t* dst,
+                                           ptrdiff_t y_stride,
+                                           const uint16_t* above,
+                                           const uint16_t* left,
+                                           int bd);
+#define aom_highbd_smooth_v_predictor_16x32 \
+  aom_highbd_smooth_v_predictor_16x32_c
+
+void aom_highbd_smooth_v_predictor_16x4_c(uint16_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint16_t* above,
+                                          const uint16_t* left,
+                                          int bd);
+#define aom_highbd_smooth_v_predictor_16x4 aom_highbd_smooth_v_predictor_16x4_c
+
+void aom_highbd_smooth_v_predictor_16x64_c(uint16_t* dst,
+                                           ptrdiff_t y_stride,
+                                           const uint16_t* above,
+                                           const uint16_t* left,
+                                           int bd);
+#define aom_highbd_smooth_v_predictor_16x64 \
+  aom_highbd_smooth_v_predictor_16x64_c
+
+void aom_highbd_smooth_v_predictor_16x8_c(uint16_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint16_t* above,
+                                          const uint16_t* left,
+                                          int bd);
+#define aom_highbd_smooth_v_predictor_16x8 aom_highbd_smooth_v_predictor_16x8_c
+
+void aom_highbd_smooth_v_predictor_2x2_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_smooth_v_predictor_2x2 aom_highbd_smooth_v_predictor_2x2_c
+
+void aom_highbd_smooth_v_predictor_32x16_c(uint16_t* dst,
+                                           ptrdiff_t y_stride,
+                                           const uint16_t* above,
+                                           const uint16_t* left,
+                                           int bd);
+#define aom_highbd_smooth_v_predictor_32x16 \
+  aom_highbd_smooth_v_predictor_32x16_c
+
+void aom_highbd_smooth_v_predictor_32x32_c(uint16_t* dst,
+                                           ptrdiff_t y_stride,
+                                           const uint16_t* above,
+                                           const uint16_t* left,
+                                           int bd);
+#define aom_highbd_smooth_v_predictor_32x32 \
+  aom_highbd_smooth_v_predictor_32x32_c
+
+void aom_highbd_smooth_v_predictor_32x64_c(uint16_t* dst,
+                                           ptrdiff_t y_stride,
+                                           const uint16_t* above,
+                                           const uint16_t* left,
+                                           int bd);
+#define aom_highbd_smooth_v_predictor_32x64 \
+  aom_highbd_smooth_v_predictor_32x64_c
+
+void aom_highbd_smooth_v_predictor_32x8_c(uint16_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint16_t* above,
+                                          const uint16_t* left,
+                                          int bd);
+#define aom_highbd_smooth_v_predictor_32x8 aom_highbd_smooth_v_predictor_32x8_c
+
+void aom_highbd_smooth_v_predictor_4x16_c(uint16_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint16_t* above,
+                                          const uint16_t* left,
+                                          int bd);
+#define aom_highbd_smooth_v_predictor_4x16 aom_highbd_smooth_v_predictor_4x16_c
+
+void aom_highbd_smooth_v_predictor_4x4_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_smooth_v_predictor_4x4 aom_highbd_smooth_v_predictor_4x4_c
+
+void aom_highbd_smooth_v_predictor_4x8_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_smooth_v_predictor_4x8 aom_highbd_smooth_v_predictor_4x8_c
+
+void aom_highbd_smooth_v_predictor_64x16_c(uint16_t* dst,
+                                           ptrdiff_t y_stride,
+                                           const uint16_t* above,
+                                           const uint16_t* left,
+                                           int bd);
+#define aom_highbd_smooth_v_predictor_64x16 \
+  aom_highbd_smooth_v_predictor_64x16_c
+
+void aom_highbd_smooth_v_predictor_64x32_c(uint16_t* dst,
+                                           ptrdiff_t y_stride,
+                                           const uint16_t* above,
+                                           const uint16_t* left,
+                                           int bd);
+#define aom_highbd_smooth_v_predictor_64x32 \
+  aom_highbd_smooth_v_predictor_64x32_c
+
+void aom_highbd_smooth_v_predictor_64x64_c(uint16_t* dst,
+                                           ptrdiff_t y_stride,
+                                           const uint16_t* above,
+                                           const uint16_t* left,
+                                           int bd);
+#define aom_highbd_smooth_v_predictor_64x64 \
+  aom_highbd_smooth_v_predictor_64x64_c
+
+void aom_highbd_smooth_v_predictor_8x16_c(uint16_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint16_t* above,
+                                          const uint16_t* left,
+                                          int bd);
+#define aom_highbd_smooth_v_predictor_8x16 aom_highbd_smooth_v_predictor_8x16_c
+
+void aom_highbd_smooth_v_predictor_8x32_c(uint16_t* dst,
+                                          ptrdiff_t y_stride,
+                                          const uint16_t* above,
+                                          const uint16_t* left,
+                                          int bd);
+#define aom_highbd_smooth_v_predictor_8x32 aom_highbd_smooth_v_predictor_8x32_c
+
+void aom_highbd_smooth_v_predictor_8x4_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_smooth_v_predictor_8x4 aom_highbd_smooth_v_predictor_8x4_c
+
+void aom_highbd_smooth_v_predictor_8x8_c(uint16_t* dst,
+                                         ptrdiff_t y_stride,
+                                         const uint16_t* above,
+                                         const uint16_t* left,
+                                         int bd);
+#define aom_highbd_smooth_v_predictor_8x8 aom_highbd_smooth_v_predictor_8x8_c
+
+void aom_highbd_v_predictor_16x16_c(uint16_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint16_t* above,
+                                    const uint16_t* left,
+                                    int bd);
+#define aom_highbd_v_predictor_16x16 aom_highbd_v_predictor_16x16_c
+
+void aom_highbd_v_predictor_16x32_c(uint16_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint16_t* above,
+                                    const uint16_t* left,
+                                    int bd);
+#define aom_highbd_v_predictor_16x32 aom_highbd_v_predictor_16x32_c
+
+void aom_highbd_v_predictor_16x4_c(uint16_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint16_t* above,
+                                   const uint16_t* left,
+                                   int bd);
+#define aom_highbd_v_predictor_16x4 aom_highbd_v_predictor_16x4_c
+
+void aom_highbd_v_predictor_16x64_c(uint16_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint16_t* above,
+                                    const uint16_t* left,
+                                    int bd);
+#define aom_highbd_v_predictor_16x64 aom_highbd_v_predictor_16x64_c
+
+void aom_highbd_v_predictor_16x8_c(uint16_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint16_t* above,
+                                   const uint16_t* left,
+                                   int bd);
+#define aom_highbd_v_predictor_16x8 aom_highbd_v_predictor_16x8_c
+
+void aom_highbd_v_predictor_2x2_c(uint16_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint16_t* above,
+                                  const uint16_t* left,
+                                  int bd);
+#define aom_highbd_v_predictor_2x2 aom_highbd_v_predictor_2x2_c
+
+void aom_highbd_v_predictor_32x16_c(uint16_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint16_t* above,
+                                    const uint16_t* left,
+                                    int bd);
+#define aom_highbd_v_predictor_32x16 aom_highbd_v_predictor_32x16_c
+
+void aom_highbd_v_predictor_32x32_c(uint16_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint16_t* above,
+                                    const uint16_t* left,
+                                    int bd);
+#define aom_highbd_v_predictor_32x32 aom_highbd_v_predictor_32x32_c
+
+void aom_highbd_v_predictor_32x64_c(uint16_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint16_t* above,
+                                    const uint16_t* left,
+                                    int bd);
+#define aom_highbd_v_predictor_32x64 aom_highbd_v_predictor_32x64_c
+
+void aom_highbd_v_predictor_32x8_c(uint16_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint16_t* above,
+                                   const uint16_t* left,
+                                   int bd);
+#define aom_highbd_v_predictor_32x8 aom_highbd_v_predictor_32x8_c
+
+void aom_highbd_v_predictor_4x16_c(uint16_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint16_t* above,
+                                   const uint16_t* left,
+                                   int bd);
+#define aom_highbd_v_predictor_4x16 aom_highbd_v_predictor_4x16_c
+
+void aom_highbd_v_predictor_4x4_c(uint16_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint16_t* above,
+                                  const uint16_t* left,
+                                  int bd);
+#define aom_highbd_v_predictor_4x4 aom_highbd_v_predictor_4x4_c
+
+void aom_highbd_v_predictor_4x8_c(uint16_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint16_t* above,
+                                  const uint16_t* left,
+                                  int bd);
+#define aom_highbd_v_predictor_4x8 aom_highbd_v_predictor_4x8_c
+
+void aom_highbd_v_predictor_64x16_c(uint16_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint16_t* above,
+                                    const uint16_t* left,
+                                    int bd);
+#define aom_highbd_v_predictor_64x16 aom_highbd_v_predictor_64x16_c
+
+void aom_highbd_v_predictor_64x32_c(uint16_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint16_t* above,
+                                    const uint16_t* left,
+                                    int bd);
+#define aom_highbd_v_predictor_64x32 aom_highbd_v_predictor_64x32_c
+
+void aom_highbd_v_predictor_64x64_c(uint16_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint16_t* above,
+                                    const uint16_t* left,
+                                    int bd);
+#define aom_highbd_v_predictor_64x64 aom_highbd_v_predictor_64x64_c
+
+void aom_highbd_v_predictor_8x16_c(uint16_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint16_t* above,
+                                   const uint16_t* left,
+                                   int bd);
+#define aom_highbd_v_predictor_8x16 aom_highbd_v_predictor_8x16_c
+
+void aom_highbd_v_predictor_8x32_c(uint16_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint16_t* above,
+                                   const uint16_t* left,
+                                   int bd);
+#define aom_highbd_v_predictor_8x32 aom_highbd_v_predictor_8x32_c
+
+void aom_highbd_v_predictor_8x4_c(uint16_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint16_t* above,
+                                  const uint16_t* left,
+                                  int bd);
+#define aom_highbd_v_predictor_8x4 aom_highbd_v_predictor_8x4_c
+
+void aom_highbd_v_predictor_8x8_c(uint16_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint16_t* above,
+                                  const uint16_t* left,
+                                  int bd);
+#define aom_highbd_v_predictor_8x8 aom_highbd_v_predictor_8x8_c
+
+void aom_lowbd_blend_a64_d16_mask_c(uint8_t* dst,
+                                    uint32_t dst_stride,
+                                    const CONV_BUF_TYPE* src0,
+                                    uint32_t src0_stride,
+                                    const CONV_BUF_TYPE* src1,
+                                    uint32_t src1_stride,
+                                    const uint8_t* mask,
+                                    uint32_t mask_stride,
+                                    int w,
+                                    int h,
+                                    int subx,
+                                    int suby,
+                                    ConvolveParams* conv_params);
+void aom_lowbd_blend_a64_d16_mask_neon(uint8_t* dst,
+                                       uint32_t dst_stride,
+                                       const CONV_BUF_TYPE* src0,
+                                       uint32_t src0_stride,
+                                       const CONV_BUF_TYPE* src1,
+                                       uint32_t src1_stride,
+                                       const uint8_t* mask,
+                                       uint32_t mask_stride,
+                                       int w,
+                                       int h,
+                                       int subx,
+                                       int suby,
+                                       ConvolveParams* conv_params);
+#define aom_lowbd_blend_a64_d16_mask aom_lowbd_blend_a64_d16_mask_neon
+
+void aom_lpf_horizontal_14_c(uint8_t* s,
+                             int pitch,
+                             const uint8_t* blimit,
+                             const uint8_t* limit,
+                             const uint8_t* thresh);
+void aom_lpf_horizontal_14_neon(uint8_t* s,
+                                int pitch,
+                                const uint8_t* blimit,
+                                const uint8_t* limit,
+                                const uint8_t* thresh);
+#define aom_lpf_horizontal_14 aom_lpf_horizontal_14_neon
+
+void aom_lpf_horizontal_14_dual_c(uint8_t* s,
+                                  int pitch,
+                                  const uint8_t* blimit0,
+                                  const uint8_t* limit0,
+                                  const uint8_t* thresh0,
+                                  const uint8_t* blimit1,
+                                  const uint8_t* limit1,
+                                  const uint8_t* thresh1);
+#define aom_lpf_horizontal_14_dual aom_lpf_horizontal_14_dual_c
+
+void aom_lpf_horizontal_4_c(uint8_t* s,
+                            int pitch,
+                            const uint8_t* blimit,
+                            const uint8_t* limit,
+                            const uint8_t* thresh);
+void aom_lpf_horizontal_4_neon(uint8_t* s,
+                               int pitch,
+                               const uint8_t* blimit,
+                               const uint8_t* limit,
+                               const uint8_t* thresh);
+#define aom_lpf_horizontal_4 aom_lpf_horizontal_4_neon
+
+void aom_lpf_horizontal_4_dual_c(uint8_t* s,
+                                 int pitch,
+                                 const uint8_t* blimit0,
+                                 const uint8_t* limit0,
+                                 const uint8_t* thresh0,
+                                 const uint8_t* blimit1,
+                                 const uint8_t* limit1,
+                                 const uint8_t* thresh1);
+#define aom_lpf_horizontal_4_dual aom_lpf_horizontal_4_dual_c
+
+void aom_lpf_horizontal_6_c(uint8_t* s,
+                            int pitch,
+                            const uint8_t* blimit,
+                            const uint8_t* limit,
+                            const uint8_t* thresh);
+void aom_lpf_horizontal_6_neon(uint8_t* s,
+                               int pitch,
+                               const uint8_t* blimit,
+                               const uint8_t* limit,
+                               const uint8_t* thresh);
+#define aom_lpf_horizontal_6 aom_lpf_horizontal_6_neon
+
+void aom_lpf_horizontal_6_dual_c(uint8_t* s,
+                                 int pitch,
+                                 const uint8_t* blimit0,
+                                 const uint8_t* limit0,
+                                 const uint8_t* thresh0,
+                                 const uint8_t* blimit1,
+                                 const uint8_t* limit1,
+                                 const uint8_t* thresh1);
+#define aom_lpf_horizontal_6_dual aom_lpf_horizontal_6_dual_c
+
+void aom_lpf_horizontal_8_c(uint8_t* s,
+                            int pitch,
+                            const uint8_t* blimit,
+                            const uint8_t* limit,
+                            const uint8_t* thresh);
+void aom_lpf_horizontal_8_neon(uint8_t* s,
+                               int pitch,
+                               const uint8_t* blimit,
+                               const uint8_t* limit,
+                               const uint8_t* thresh);
+#define aom_lpf_horizontal_8 aom_lpf_horizontal_8_neon
+
+void aom_lpf_horizontal_8_dual_c(uint8_t* s,
+                                 int pitch,
+                                 const uint8_t* blimit0,
+                                 const uint8_t* limit0,
+                                 const uint8_t* thresh0,
+                                 const uint8_t* blimit1,
+                                 const uint8_t* limit1,
+                                 const uint8_t* thresh1);
+#define aom_lpf_horizontal_8_dual aom_lpf_horizontal_8_dual_c
+
+void aom_lpf_vertical_14_c(uint8_t* s,
+                           int pitch,
+                           const uint8_t* blimit,
+                           const uint8_t* limit,
+                           const uint8_t* thresh);
+void aom_lpf_vertical_14_neon(uint8_t* s,
+                              int pitch,
+                              const uint8_t* blimit,
+                              const uint8_t* limit,
+                              const uint8_t* thresh);
+#define aom_lpf_vertical_14 aom_lpf_vertical_14_neon
+
+void aom_lpf_vertical_14_dual_c(uint8_t* s,
+                                int pitch,
+                                const uint8_t* blimit0,
+                                const uint8_t* limit0,
+                                const uint8_t* thresh0,
+                                const uint8_t* blimit1,
+                                const uint8_t* limit1,
+                                const uint8_t* thresh1);
+#define aom_lpf_vertical_14_dual aom_lpf_vertical_14_dual_c
+
+void aom_lpf_vertical_4_c(uint8_t* s,
+                          int pitch,
+                          const uint8_t* blimit,
+                          const uint8_t* limit,
+                          const uint8_t* thresh);
+void aom_lpf_vertical_4_neon(uint8_t* s,
+                             int pitch,
+                             const uint8_t* blimit,
+                             const uint8_t* limit,
+                             const uint8_t* thresh);
+#define aom_lpf_vertical_4 aom_lpf_vertical_4_neon
+
+void aom_lpf_vertical_4_dual_c(uint8_t* s,
+                               int pitch,
+                               const uint8_t* blimit0,
+                               const uint8_t* limit0,
+                               const uint8_t* thresh0,
+                               const uint8_t* blimit1,
+                               const uint8_t* limit1,
+                               const uint8_t* thresh1);
+#define aom_lpf_vertical_4_dual aom_lpf_vertical_4_dual_c
+
+void aom_lpf_vertical_6_c(uint8_t* s,
+                          int pitch,
+                          const uint8_t* blimit,
+                          const uint8_t* limit,
+                          const uint8_t* thresh);
+void aom_lpf_vertical_6_neon(uint8_t* s,
+                             int pitch,
+                             const uint8_t* blimit,
+                             const uint8_t* limit,
+                             const uint8_t* thresh);
+#define aom_lpf_vertical_6 aom_lpf_vertical_6_neon
+
+void aom_lpf_vertical_6_dual_c(uint8_t* s,
+                               int pitch,
+                               const uint8_t* blimit0,
+                               const uint8_t* limit0,
+                               const uint8_t* thresh0,
+                               const uint8_t* blimit1,
+                               const uint8_t* limit1,
+                               const uint8_t* thresh1);
+#define aom_lpf_vertical_6_dual aom_lpf_vertical_6_dual_c
+
+void aom_lpf_vertical_8_c(uint8_t* s,
+                          int pitch,
+                          const uint8_t* blimit,
+                          const uint8_t* limit,
+                          const uint8_t* thresh);
+void aom_lpf_vertical_8_neon(uint8_t* s,
+                             int pitch,
+                             const uint8_t* blimit,
+                             const uint8_t* limit,
+                             const uint8_t* thresh);
+#define aom_lpf_vertical_8 aom_lpf_vertical_8_neon
+
+void aom_lpf_vertical_8_dual_c(uint8_t* s,
+                               int pitch,
+                               const uint8_t* blimit0,
+                               const uint8_t* limit0,
+                               const uint8_t* thresh0,
+                               const uint8_t* blimit1,
+                               const uint8_t* limit1,
+                               const uint8_t* thresh1);
+#define aom_lpf_vertical_8_dual aom_lpf_vertical_8_dual_c
+
+void aom_paeth_predictor_16x16_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_paeth_predictor_16x16 aom_paeth_predictor_16x16_c
+
+void aom_paeth_predictor_16x32_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_paeth_predictor_16x32 aom_paeth_predictor_16x32_c
+
+void aom_paeth_predictor_16x4_c(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_paeth_predictor_16x4 aom_paeth_predictor_16x4_c
+
+void aom_paeth_predictor_16x64_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_paeth_predictor_16x64 aom_paeth_predictor_16x64_c
+
+void aom_paeth_predictor_16x8_c(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_paeth_predictor_16x8 aom_paeth_predictor_16x8_c
+
+void aom_paeth_predictor_2x2_c(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_paeth_predictor_2x2 aom_paeth_predictor_2x2_c
+
+void aom_paeth_predictor_32x16_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_paeth_predictor_32x16 aom_paeth_predictor_32x16_c
+
+void aom_paeth_predictor_32x32_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_paeth_predictor_32x32 aom_paeth_predictor_32x32_c
+
+void aom_paeth_predictor_32x64_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_paeth_predictor_32x64 aom_paeth_predictor_32x64_c
+
+void aom_paeth_predictor_32x8_c(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_paeth_predictor_32x8 aom_paeth_predictor_32x8_c
+
+void aom_paeth_predictor_4x16_c(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_paeth_predictor_4x16 aom_paeth_predictor_4x16_c
+
+void aom_paeth_predictor_4x4_c(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_paeth_predictor_4x4 aom_paeth_predictor_4x4_c
+
+void aom_paeth_predictor_4x8_c(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_paeth_predictor_4x8 aom_paeth_predictor_4x8_c
+
+void aom_paeth_predictor_64x16_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_paeth_predictor_64x16 aom_paeth_predictor_64x16_c
+
+void aom_paeth_predictor_64x32_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_paeth_predictor_64x32 aom_paeth_predictor_64x32_c
+
+void aom_paeth_predictor_64x64_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_paeth_predictor_64x64 aom_paeth_predictor_64x64_c
+
+void aom_paeth_predictor_8x16_c(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_paeth_predictor_8x16 aom_paeth_predictor_8x16_c
+
+void aom_paeth_predictor_8x32_c(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_paeth_predictor_8x32 aom_paeth_predictor_8x32_c
+
+void aom_paeth_predictor_8x4_c(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_paeth_predictor_8x4 aom_paeth_predictor_8x4_c
+
+void aom_paeth_predictor_8x8_c(uint8_t* dst,
+                               ptrdiff_t y_stride,
+                               const uint8_t* above,
+                               const uint8_t* left);
+#define aom_paeth_predictor_8x8 aom_paeth_predictor_8x8_c
+
+void aom_smooth_h_predictor_16x16_c(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_smooth_h_predictor_16x16 aom_smooth_h_predictor_16x16_c
+
+void aom_smooth_h_predictor_16x32_c(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_smooth_h_predictor_16x32 aom_smooth_h_predictor_16x32_c
+
+void aom_smooth_h_predictor_16x4_c(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_smooth_h_predictor_16x4 aom_smooth_h_predictor_16x4_c
+
+void aom_smooth_h_predictor_16x64_c(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_smooth_h_predictor_16x64 aom_smooth_h_predictor_16x64_c
+
+void aom_smooth_h_predictor_16x8_c(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_smooth_h_predictor_16x8 aom_smooth_h_predictor_16x8_c
+
+void aom_smooth_h_predictor_2x2_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_smooth_h_predictor_2x2 aom_smooth_h_predictor_2x2_c
+
+void aom_smooth_h_predictor_32x16_c(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_smooth_h_predictor_32x16 aom_smooth_h_predictor_32x16_c
+
+void aom_smooth_h_predictor_32x32_c(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_smooth_h_predictor_32x32 aom_smooth_h_predictor_32x32_c
+
+void aom_smooth_h_predictor_32x64_c(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_smooth_h_predictor_32x64 aom_smooth_h_predictor_32x64_c
+
+void aom_smooth_h_predictor_32x8_c(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_smooth_h_predictor_32x8 aom_smooth_h_predictor_32x8_c
+
+void aom_smooth_h_predictor_4x16_c(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_smooth_h_predictor_4x16 aom_smooth_h_predictor_4x16_c
+
+void aom_smooth_h_predictor_4x4_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_smooth_h_predictor_4x4 aom_smooth_h_predictor_4x4_c
+
+void aom_smooth_h_predictor_4x8_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_smooth_h_predictor_4x8 aom_smooth_h_predictor_4x8_c
+
+void aom_smooth_h_predictor_64x16_c(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_smooth_h_predictor_64x16 aom_smooth_h_predictor_64x16_c
+
+void aom_smooth_h_predictor_64x32_c(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_smooth_h_predictor_64x32 aom_smooth_h_predictor_64x32_c
+
+void aom_smooth_h_predictor_64x64_c(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_smooth_h_predictor_64x64 aom_smooth_h_predictor_64x64_c
+
+void aom_smooth_h_predictor_8x16_c(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_smooth_h_predictor_8x16 aom_smooth_h_predictor_8x16_c
+
+void aom_smooth_h_predictor_8x32_c(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_smooth_h_predictor_8x32 aom_smooth_h_predictor_8x32_c
+
+void aom_smooth_h_predictor_8x4_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_smooth_h_predictor_8x4 aom_smooth_h_predictor_8x4_c
+
+void aom_smooth_h_predictor_8x8_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_smooth_h_predictor_8x8 aom_smooth_h_predictor_8x8_c
+
+void aom_smooth_predictor_16x16_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_smooth_predictor_16x16 aom_smooth_predictor_16x16_c
+
+void aom_smooth_predictor_16x32_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_smooth_predictor_16x32 aom_smooth_predictor_16x32_c
+
+void aom_smooth_predictor_16x4_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_smooth_predictor_16x4 aom_smooth_predictor_16x4_c
+
+void aom_smooth_predictor_16x64_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_smooth_predictor_16x64 aom_smooth_predictor_16x64_c
+
+void aom_smooth_predictor_16x8_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_smooth_predictor_16x8 aom_smooth_predictor_16x8_c
+
+void aom_smooth_predictor_2x2_c(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_smooth_predictor_2x2 aom_smooth_predictor_2x2_c
+
+void aom_smooth_predictor_32x16_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_smooth_predictor_32x16 aom_smooth_predictor_32x16_c
+
+void aom_smooth_predictor_32x32_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_smooth_predictor_32x32 aom_smooth_predictor_32x32_c
+
+void aom_smooth_predictor_32x64_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_smooth_predictor_32x64 aom_smooth_predictor_32x64_c
+
+void aom_smooth_predictor_32x8_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_smooth_predictor_32x8 aom_smooth_predictor_32x8_c
+
+void aom_smooth_predictor_4x16_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_smooth_predictor_4x16 aom_smooth_predictor_4x16_c
+
+void aom_smooth_predictor_4x4_c(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_smooth_predictor_4x4 aom_smooth_predictor_4x4_c
+
+void aom_smooth_predictor_4x8_c(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_smooth_predictor_4x8 aom_smooth_predictor_4x8_c
+
+void aom_smooth_predictor_64x16_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_smooth_predictor_64x16 aom_smooth_predictor_64x16_c
+
+void aom_smooth_predictor_64x32_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_smooth_predictor_64x32 aom_smooth_predictor_64x32_c
+
+void aom_smooth_predictor_64x64_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_smooth_predictor_64x64 aom_smooth_predictor_64x64_c
+
+void aom_smooth_predictor_8x16_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_smooth_predictor_8x16 aom_smooth_predictor_8x16_c
+
+void aom_smooth_predictor_8x32_c(uint8_t* dst,
+                                 ptrdiff_t y_stride,
+                                 const uint8_t* above,
+                                 const uint8_t* left);
+#define aom_smooth_predictor_8x32 aom_smooth_predictor_8x32_c
+
+void aom_smooth_predictor_8x4_c(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_smooth_predictor_8x4 aom_smooth_predictor_8x4_c
+
+void aom_smooth_predictor_8x8_c(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_smooth_predictor_8x8 aom_smooth_predictor_8x8_c
+
+void aom_smooth_v_predictor_16x16_c(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_smooth_v_predictor_16x16 aom_smooth_v_predictor_16x16_c
+
+void aom_smooth_v_predictor_16x32_c(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_smooth_v_predictor_16x32 aom_smooth_v_predictor_16x32_c
+
+void aom_smooth_v_predictor_16x4_c(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_smooth_v_predictor_16x4 aom_smooth_v_predictor_16x4_c
+
+void aom_smooth_v_predictor_16x64_c(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_smooth_v_predictor_16x64 aom_smooth_v_predictor_16x64_c
+
+void aom_smooth_v_predictor_16x8_c(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_smooth_v_predictor_16x8 aom_smooth_v_predictor_16x8_c
+
+void aom_smooth_v_predictor_2x2_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_smooth_v_predictor_2x2 aom_smooth_v_predictor_2x2_c
+
+void aom_smooth_v_predictor_32x16_c(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_smooth_v_predictor_32x16 aom_smooth_v_predictor_32x16_c
+
+void aom_smooth_v_predictor_32x32_c(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_smooth_v_predictor_32x32 aom_smooth_v_predictor_32x32_c
+
+void aom_smooth_v_predictor_32x64_c(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_smooth_v_predictor_32x64 aom_smooth_v_predictor_32x64_c
+
+void aom_smooth_v_predictor_32x8_c(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_smooth_v_predictor_32x8 aom_smooth_v_predictor_32x8_c
+
+void aom_smooth_v_predictor_4x16_c(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_smooth_v_predictor_4x16 aom_smooth_v_predictor_4x16_c
+
+void aom_smooth_v_predictor_4x4_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_smooth_v_predictor_4x4 aom_smooth_v_predictor_4x4_c
+
+void aom_smooth_v_predictor_4x8_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_smooth_v_predictor_4x8 aom_smooth_v_predictor_4x8_c
+
+void aom_smooth_v_predictor_64x16_c(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_smooth_v_predictor_64x16 aom_smooth_v_predictor_64x16_c
+
+void aom_smooth_v_predictor_64x32_c(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_smooth_v_predictor_64x32 aom_smooth_v_predictor_64x32_c
+
+void aom_smooth_v_predictor_64x64_c(uint8_t* dst,
+                                    ptrdiff_t y_stride,
+                                    const uint8_t* above,
+                                    const uint8_t* left);
+#define aom_smooth_v_predictor_64x64 aom_smooth_v_predictor_64x64_c
+
+void aom_smooth_v_predictor_8x16_c(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_smooth_v_predictor_8x16 aom_smooth_v_predictor_8x16_c
+
+void aom_smooth_v_predictor_8x32_c(uint8_t* dst,
+                                   ptrdiff_t y_stride,
+                                   const uint8_t* above,
+                                   const uint8_t* left);
+#define aom_smooth_v_predictor_8x32 aom_smooth_v_predictor_8x32_c
+
+void aom_smooth_v_predictor_8x4_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_smooth_v_predictor_8x4 aom_smooth_v_predictor_8x4_c
+
+void aom_smooth_v_predictor_8x8_c(uint8_t* dst,
+                                  ptrdiff_t y_stride,
+                                  const uint8_t* above,
+                                  const uint8_t* left);
+#define aom_smooth_v_predictor_8x8 aom_smooth_v_predictor_8x8_c
+
+void aom_v_predictor_16x16_c(uint8_t* dst,
+                             ptrdiff_t y_stride,
+                             const uint8_t* above,
+                             const uint8_t* left);
+void aom_v_predictor_16x16_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_16x16 aom_v_predictor_16x16_neon
+
+void aom_v_predictor_16x32_c(uint8_t* dst,
+                             ptrdiff_t y_stride,
+                             const uint8_t* above,
+                             const uint8_t* left);
+#define aom_v_predictor_16x32 aom_v_predictor_16x32_c
+
+void aom_v_predictor_16x4_c(uint8_t* dst,
+                            ptrdiff_t y_stride,
+                            const uint8_t* above,
+                            const uint8_t* left);
+#define aom_v_predictor_16x4 aom_v_predictor_16x4_c
+
+void aom_v_predictor_16x64_c(uint8_t* dst,
+                             ptrdiff_t y_stride,
+                             const uint8_t* above,
+                             const uint8_t* left);
+#define aom_v_predictor_16x64 aom_v_predictor_16x64_c
+
+void aom_v_predictor_16x8_c(uint8_t* dst,
+                            ptrdiff_t y_stride,
+                            const uint8_t* above,
+                            const uint8_t* left);
+#define aom_v_predictor_16x8 aom_v_predictor_16x8_c
+
+void aom_v_predictor_2x2_c(uint8_t* dst,
+                           ptrdiff_t y_stride,
+                           const uint8_t* above,
+                           const uint8_t* left);
+#define aom_v_predictor_2x2 aom_v_predictor_2x2_c
+
+void aom_v_predictor_32x16_c(uint8_t* dst,
+                             ptrdiff_t y_stride,
+                             const uint8_t* above,
+                             const uint8_t* left);
+#define aom_v_predictor_32x16 aom_v_predictor_32x16_c
+
+void aom_v_predictor_32x32_c(uint8_t* dst,
+                             ptrdiff_t y_stride,
+                             const uint8_t* above,
+                             const uint8_t* left);
+void aom_v_predictor_32x32_neon(uint8_t* dst,
+                                ptrdiff_t y_stride,
+                                const uint8_t* above,
+                                const uint8_t* left);
+#define aom_v_predictor_32x32 aom_v_predictor_32x32_neon
+
+void aom_v_predictor_32x64_c(uint8_t* dst,
+                             ptrdiff_t y_stride,
+                             const uint8_t* above,
+                             const uint8_t* left);
+#define aom_v_predictor_32x64 aom_v_predictor_32x64_c
+
+void aom_v_predictor_32x8_c(uint8_t* dst,
+                            ptrdiff_t y_stride,
+                            const uint8_t* above,
+                            const uint8_t* left);
+#define aom_v_predictor_32x8 aom_v_predictor_32x8_c
+
+void aom_v_predictor_4x16_c(uint8_t* dst,
+                            ptrdiff_t y_stride,
+                            const uint8_t* above,
+                            const uint8_t* left);
+#define aom_v_predictor_4x16 aom_v_predictor_4x16_c
+
+void aom_v_predictor_4x4_c(uint8_t* dst,
+                           ptrdiff_t y_stride,
+                           const uint8_t* above,
+                           const uint8_t* left);
+void aom_v_predictor_4x4_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_v_predictor_4x4 aom_v_predictor_4x4_neon
+
+void aom_v_predictor_4x8_c(uint8_t* dst,
+                           ptrdiff_t y_stride,
+                           const uint8_t* above,
+                           const uint8_t* left);
+#define aom_v_predictor_4x8 aom_v_predictor_4x8_c
+
+void aom_v_predictor_64x16_c(uint8_t* dst,
+                             ptrdiff_t y_stride,
+                             const uint8_t* above,
+                             const uint8_t* left);
+#define aom_v_predictor_64x16 aom_v_predictor_64x16_c
+
+void aom_v_predictor_64x32_c(uint8_t* dst,
+                             ptrdiff_t y_stride,
+                             const uint8_t* above,
+                             const uint8_t* left);
+#define aom_v_predictor_64x32 aom_v_predictor_64x32_c
+
+void aom_v_predictor_64x64_c(uint8_t* dst,
+                             ptrdiff_t y_stride,
+                             const uint8_t* above,
+                             const uint8_t* left);
+#define aom_v_predictor_64x64 aom_v_predictor_64x64_c
+
+void aom_v_predictor_8x16_c(uint8_t* dst,
+                            ptrdiff_t y_stride,
+                            const uint8_t* above,
+                            const uint8_t* left);
+#define aom_v_predictor_8x16 aom_v_predictor_8x16_c
+
+void aom_v_predictor_8x32_c(uint8_t* dst,
+                            ptrdiff_t y_stride,
+                            const uint8_t* above,
+                            const uint8_t* left);
+#define aom_v_predictor_8x32 aom_v_predictor_8x32_c
+
+void aom_v_predictor_8x4_c(uint8_t* dst,
+                           ptrdiff_t y_stride,
+                           const uint8_t* above,
+                           const uint8_t* left);
+#define aom_v_predictor_8x4 aom_v_predictor_8x4_c
+
+void aom_v_predictor_8x8_c(uint8_t* dst,
+                           ptrdiff_t y_stride,
+                           const uint8_t* above,
+                           const uint8_t* left);
+void aom_v_predictor_8x8_neon(uint8_t* dst,
+                              ptrdiff_t y_stride,
+                              const uint8_t* above,
+                              const uint8_t* left);
+#define aom_v_predictor_8x8 aom_v_predictor_8x8_neon
+
+void aom_dsp_rtcd(void);
+
+#include "config/aom_config.h"
+
+#ifdef RTCD_C
+#include "aom_ports/arm.h"
+static void setup_rtcd_internal(void) {
+  int flags = aom_arm_cpu_caps();
+
+  (void)flags;
+}
+#endif
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif
diff --git a/third_party/libaom/source/config/win/arm64/config/aom_scale_rtcd.h b/third_party/libaom/source/config/win/arm64/config/aom_scale_rtcd.h
new file mode 100644
index 0000000..c8fa3a4
--- /dev/null
+++ b/third_party/libaom/source/config/win/arm64/config/aom_scale_rtcd.h
@@ -0,0 +1,166 @@
+// This file is generated. Do not edit.
+#ifndef AOM_SCALE_RTCD_H_
+#define AOM_SCALE_RTCD_H_
+
+#ifdef RTCD_C
+#define RTCD_EXTERN
+#else
+#define RTCD_EXTERN extern
+#endif
+
+struct yv12_buffer_config;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void aom_extend_frame_borders_c(struct yv12_buffer_config* ybf,
+                                const int num_planes);
+#define aom_extend_frame_borders aom_extend_frame_borders_c
+
+void aom_extend_frame_borders_y_c(struct yv12_buffer_config* ybf);
+#define aom_extend_frame_borders_y aom_extend_frame_borders_y_c
+
+void aom_extend_frame_inner_borders_c(struct yv12_buffer_config* ybf,
+                                      const int num_planes);
+#define aom_extend_frame_inner_borders aom_extend_frame_inner_borders_c
+
+void aom_horizontal_line_2_1_scale_c(const unsigned char* source,
+                                     unsigned int source_width,
+                                     unsigned char* dest,
+                                     unsigned int dest_width);
+#define aom_horizontal_line_2_1_scale aom_horizontal_line_2_1_scale_c
+
+void aom_horizontal_line_5_3_scale_c(const unsigned char* source,
+                                     unsigned int source_width,
+                                     unsigned char* dest,
+                                     unsigned int dest_width);
+#define aom_horizontal_line_5_3_scale aom_horizontal_line_5_3_scale_c
+
+void aom_horizontal_line_5_4_scale_c(const unsigned char* source,
+                                     unsigned int source_width,
+                                     unsigned char* dest,
+                                     unsigned int dest_width);
+#define aom_horizontal_line_5_4_scale aom_horizontal_line_5_4_scale_c
+
+void aom_vertical_band_2_1_scale_c(unsigned char* source,
+                                   int src_pitch,
+                                   unsigned char* dest,
+                                   int dest_pitch,
+                                   unsigned int dest_width);
+#define aom_vertical_band_2_1_scale aom_vertical_band_2_1_scale_c
+
+void aom_vertical_band_2_1_scale_i_c(unsigned char* source,
+                                     int src_pitch,
+                                     unsigned char* dest,
+                                     int dest_pitch,
+                                     unsigned int dest_width);
+#define aom_vertical_band_2_1_scale_i aom_vertical_band_2_1_scale_i_c
+
+void aom_vertical_band_5_3_scale_c(unsigned char* source,
+                                   int src_pitch,
+                                   unsigned char* dest,
+                                   int dest_pitch,
+                                   unsigned int dest_width);
+#define aom_vertical_band_5_3_scale aom_vertical_band_5_3_scale_c
+
+void aom_vertical_band_5_4_scale_c(unsigned char* source,
+                                   int src_pitch,
+                                   unsigned char* dest,
+                                   int dest_pitch,
+                                   unsigned int dest_width);
+#define aom_vertical_band_5_4_scale aom_vertical_band_5_4_scale_c
+
+void aom_yv12_copy_frame_c(const struct yv12_buffer_config* src_bc,
+                           struct yv12_buffer_config* dst_bc,
+                           const int num_planes);
+#define aom_yv12_copy_frame aom_yv12_copy_frame_c
+
+void aom_yv12_copy_u_c(const struct yv12_buffer_config* src_bc,
+                       struct yv12_buffer_config* dst_bc);
+#define aom_yv12_copy_u aom_yv12_copy_u_c
+
+void aom_yv12_copy_v_c(const struct yv12_buffer_config* src_bc,
+                       struct yv12_buffer_config* dst_bc);
+#define aom_yv12_copy_v aom_yv12_copy_v_c
+
+void aom_yv12_copy_y_c(const struct yv12_buffer_config* src_ybc,
+                       struct yv12_buffer_config* dst_ybc);
+#define aom_yv12_copy_y aom_yv12_copy_y_c
+
+void aom_yv12_extend_frame_borders_c(struct yv12_buffer_config* ybf,
+                                     const int num_planes);
+#define aom_yv12_extend_frame_borders aom_yv12_extend_frame_borders_c
+
+void aom_yv12_partial_coloc_copy_u_c(const struct yv12_buffer_config* src_bc,
+                                     struct yv12_buffer_config* dst_bc,
+                                     int hstart,
+                                     int hend,
+                                     int vstart,
+                                     int vend);
+#define aom_yv12_partial_coloc_copy_u aom_yv12_partial_coloc_copy_u_c
+
+void aom_yv12_partial_coloc_copy_v_c(const struct yv12_buffer_config* src_bc,
+                                     struct yv12_buffer_config* dst_bc,
+                                     int hstart,
+                                     int hend,
+                                     int vstart,
+                                     int vend);
+#define aom_yv12_partial_coloc_copy_v aom_yv12_partial_coloc_copy_v_c
+
+void aom_yv12_partial_coloc_copy_y_c(const struct yv12_buffer_config* src_ybc,
+                                     struct yv12_buffer_config* dst_ybc,
+                                     int hstart,
+                                     int hend,
+                                     int vstart,
+                                     int vend);
+#define aom_yv12_partial_coloc_copy_y aom_yv12_partial_coloc_copy_y_c
+
+void aom_yv12_partial_copy_u_c(const struct yv12_buffer_config* src_bc,
+                               int hstart1,
+                               int hend1,
+                               int vstart1,
+                               int vend1,
+                               struct yv12_buffer_config* dst_bc,
+                               int hstart2,
+                               int vstart2);
+#define aom_yv12_partial_copy_u aom_yv12_partial_copy_u_c
+
+void aom_yv12_partial_copy_v_c(const struct yv12_buffer_config* src_bc,
+                               int hstart1,
+                               int hend1,
+                               int vstart1,
+                               int vend1,
+                               struct yv12_buffer_config* dst_bc,
+                               int hstart2,
+                               int vstart2);
+#define aom_yv12_partial_copy_v aom_yv12_partial_copy_v_c
+
+void aom_yv12_partial_copy_y_c(const struct yv12_buffer_config* src_ybc,
+                               int hstart1,
+                               int hend1,
+                               int vstart1,
+                               int vend1,
+                               struct yv12_buffer_config* dst_ybc,
+                               int hstart2,
+                               int vstart2);
+#define aom_yv12_partial_copy_y aom_yv12_partial_copy_y_c
+
+void aom_scale_rtcd(void);
+
+#include "config/aom_config.h"
+
+#ifdef RTCD_C
+#include "aom_ports/arm.h"
+static void setup_rtcd_internal(void) {
+  int flags = aom_arm_cpu_caps();
+
+  (void)flags;
+}
+#endif
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif
diff --git a/third_party/libaom/source/config/win/arm64/config/av1_rtcd.h b/third_party/libaom/source/config/win/arm64/config/av1_rtcd.h
new file mode 100644
index 0000000..f66c096
--- /dev/null
+++ b/third_party/libaom/source/config/win/arm64/config/av1_rtcd.h
@@ -0,0 +1,1085 @@
+// This file is generated. Do not edit.
+#ifndef AV1_RTCD_H_
+#define AV1_RTCD_H_
+
+#ifdef RTCD_C
+#define RTCD_EXTERN
+#else
+#define RTCD_EXTERN extern
+#endif
+
+/*
+ * AV1
+ */
+
+#include "aom/aom_integer.h"
+#include "aom_dsp/txfm_common.h"
+#include "av1/common/av1_txfm.h"
+#include "av1/common/common.h"
+#include "av1/common/convolve.h"
+#include "av1/common/enums.h"
+#include "av1/common/filter.h"
+#include "av1/common/odintrin.h"
+#include "av1/common/quant_common.h"
+#include "av1/common/restoration.h"
+
+struct macroblockd;
+
+/* Encoder forward decls */
+struct macroblock;
+struct txfm_param;
+struct aom_variance_vtable;
+struct search_site_config;
+struct yv12_buffer_config;
+struct NN_CONFIG;
+typedef struct NN_CONFIG NN_CONFIG;
+
+/* Function pointers return by CfL functions */
+typedef void (*cfl_subsample_lbd_fn)(const uint8_t* input,
+                                     int input_stride,
+                                     uint16_t* output_q3);
+
+typedef void (*cfl_subsample_hbd_fn)(const uint16_t* input,
+                                     int input_stride,
+                                     uint16_t* output_q3);
+
+typedef void (*cfl_subtract_average_fn)(const uint16_t* src, int16_t* dst);
+
+typedef void (*cfl_predict_lbd_fn)(const int16_t* src,
+                                   uint8_t* dst,
+                                   int dst_stride,
+                                   int alpha_q3);
+
+typedef void (*cfl_predict_hbd_fn)(const int16_t* src,
+                                   uint16_t* dst,
+                                   int dst_stride,
+                                   int alpha_q3,
+                                   int bd);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void apply_selfguided_restoration_c(const uint8_t* dat,
+                                    int width,
+                                    int height,
+                                    int stride,
+                                    int eps,
+                                    const int* xqd,
+                                    uint8_t* dst,
+                                    int dst_stride,
+                                    int32_t* tmpbuf,
+                                    int bit_depth,
+                                    int highbd);
+void apply_selfguided_restoration_neon(const uint8_t* dat,
+                                       int width,
+                                       int height,
+                                       int stride,
+                                       int eps,
+                                       const int* xqd,
+                                       uint8_t* dst,
+                                       int dst_stride,
+                                       int32_t* tmpbuf,
+                                       int bit_depth,
+                                       int highbd);
+#define apply_selfguided_restoration apply_selfguided_restoration_neon
+
+void av1_build_compound_diffwtd_mask_c(uint8_t* mask,
+                                       DIFFWTD_MASK_TYPE mask_type,
+                                       const uint8_t* src0,
+                                       int src0_stride,
+                                       const uint8_t* src1,
+                                       int src1_stride,
+                                       int h,
+                                       int w);
+#define av1_build_compound_diffwtd_mask av1_build_compound_diffwtd_mask_c
+
+void av1_build_compound_diffwtd_mask_d16_c(uint8_t* mask,
+                                           DIFFWTD_MASK_TYPE mask_type,
+                                           const CONV_BUF_TYPE* src0,
+                                           int src0_stride,
+                                           const CONV_BUF_TYPE* src1,
+                                           int src1_stride,
+                                           int h,
+                                           int w,
+                                           ConvolveParams* conv_params,
+                                           int bd);
+void av1_build_compound_diffwtd_mask_d16_neon(uint8_t* mask,
+                                              DIFFWTD_MASK_TYPE mask_type,
+                                              const CONV_BUF_TYPE* src0,
+                                              int src0_stride,
+                                              const CONV_BUF_TYPE* src1,
+                                              int src1_stride,
+                                              int h,
+                                              int w,
+                                              ConvolveParams* conv_params,
+                                              int bd);
+#define av1_build_compound_diffwtd_mask_d16 \
+  av1_build_compound_diffwtd_mask_d16_neon
+
+void av1_build_compound_diffwtd_mask_highbd_c(uint8_t* mask,
+                                              DIFFWTD_MASK_TYPE mask_type,
+                                              const uint8_t* src0,
+                                              int src0_stride,
+                                              const uint8_t* src1,
+                                              int src1_stride,
+                                              int h,
+                                              int w,
+                                              int bd);
+#define av1_build_compound_diffwtd_mask_highbd \
+  av1_build_compound_diffwtd_mask_highbd_c
+
+void av1_convolve_2d_copy_sr_c(const uint8_t* src,
+                               int src_stride,
+                               uint8_t* dst,
+                               int dst_stride,
+                               int w,
+                               int h,
+                               const InterpFilterParams* filter_params_x,
+                               const InterpFilterParams* filter_params_y,
+                               const int subpel_x_q4,
+                               const int subpel_y_q4,
+                               ConvolveParams* conv_params);
+void av1_convolve_2d_copy_sr_neon(const uint8_t* src,
+                                  int src_stride,
+                                  uint8_t* dst,
+                                  int dst_stride,
+                                  int w,
+                                  int h,
+                                  const InterpFilterParams* filter_params_x,
+                                  const InterpFilterParams* filter_params_y,
+                                  const int subpel_x_q4,
+                                  const int subpel_y_q4,
+                                  ConvolveParams* conv_params);
+#define av1_convolve_2d_copy_sr av1_convolve_2d_copy_sr_neon
+
+void av1_convolve_2d_scale_c(const uint8_t* src,
+                             int src_stride,
+                             uint8_t* dst,
+                             int dst_stride,
+                             int w,
+                             int h,
+                             const InterpFilterParams* filter_params_x,
+                             const InterpFilterParams* filter_params_y,
+                             const int subpel_x_qn,
+                             const int x_step_qn,
+                             const int subpel_y_q4,
+                             const int y_step_qn,
+                             ConvolveParams* conv_params);
+#define av1_convolve_2d_scale av1_convolve_2d_scale_c
+
+void av1_convolve_2d_sr_c(const uint8_t* src,
+                          int src_stride,
+                          uint8_t* dst,
+                          int dst_stride,
+                          int w,
+                          int h,
+                          const InterpFilterParams* filter_params_x,
+                          const InterpFilterParams* filter_params_y,
+                          const int subpel_x_q4,
+                          const int subpel_y_q4,
+                          ConvolveParams* conv_params);
+void av1_convolve_2d_sr_neon(const uint8_t* src,
+                             int src_stride,
+                             uint8_t* dst,
+                             int dst_stride,
+                             int w,
+                             int h,
+                             const InterpFilterParams* filter_params_x,
+                             const InterpFilterParams* filter_params_y,
+                             const int subpel_x_q4,
+                             const int subpel_y_q4,
+                             ConvolveParams* conv_params);
+#define av1_convolve_2d_sr av1_convolve_2d_sr_neon
+
+void av1_convolve_horiz_rs_c(const uint8_t* src,
+                             int src_stride,
+                             uint8_t* dst,
+                             int dst_stride,
+                             int w,
+                             int h,
+                             const int16_t* x_filters,
+                             int x0_qn,
+                             int x_step_qn);
+#define av1_convolve_horiz_rs av1_convolve_horiz_rs_c
+
+void av1_convolve_x_sr_c(const uint8_t* src,
+                         int src_stride,
+                         uint8_t* dst,
+                         int dst_stride,
+                         int w,
+                         int h,
+                         const InterpFilterParams* filter_params_x,
+                         const InterpFilterParams* filter_params_y,
+                         const int subpel_x_q4,
+                         const int subpel_y_q4,
+                         ConvolveParams* conv_params);
+void av1_convolve_x_sr_neon(const uint8_t* src,
+                            int src_stride,
+                            uint8_t* dst,
+                            int dst_stride,
+                            int w,
+                            int h,
+                            const InterpFilterParams* filter_params_x,
+                            const InterpFilterParams* filter_params_y,
+                            const int subpel_x_q4,
+                            const int subpel_y_q4,
+                            ConvolveParams* conv_params);
+#define av1_convolve_x_sr av1_convolve_x_sr_neon
+
+void av1_convolve_y_sr_c(const uint8_t* src,
+                         int src_stride,
+                         uint8_t* dst,
+                         int dst_stride,
+                         int w,
+                         int h,
+                         const InterpFilterParams* filter_params_x,
+                         const InterpFilterParams* filter_params_y,
+                         const int subpel_x_q4,
+                         const int subpel_y_q4,
+                         ConvolveParams* conv_params);
+void av1_convolve_y_sr_neon(const uint8_t* src,
+                            int src_stride,
+                            uint8_t* dst,
+                            int dst_stride,
+                            int w,
+                            int h,
+                            const InterpFilterParams* filter_params_x,
+                            const InterpFilterParams* filter_params_y,
+                            const int subpel_x_q4,
+                            const int subpel_y_q4,
+                            ConvolveParams* conv_params);
+#define av1_convolve_y_sr av1_convolve_y_sr_neon
+
+void av1_dist_wtd_convolve_2d_c(const uint8_t* src,
+                                int src_stride,
+                                uint8_t* dst,
+                                int dst_stride,
+                                int w,
+                                int h,
+                                const InterpFilterParams* filter_params_x,
+                                const InterpFilterParams* filter_params_y,
+                                const int subpel_x_q4,
+                                const int subpel_y_q4,
+                                ConvolveParams* conv_params);
+void av1_dist_wtd_convolve_2d_neon(const uint8_t* src,
+                                   int src_stride,
+                                   uint8_t* dst,
+                                   int dst_stride,
+                                   int w,
+                                   int h,
+                                   const InterpFilterParams* filter_params_x,
+                                   const InterpFilterParams* filter_params_y,
+                                   const int subpel_x_q4,
+                                   const int subpel_y_q4,
+                                   ConvolveParams* conv_params);
+#define av1_dist_wtd_convolve_2d av1_dist_wtd_convolve_2d_neon
+
+void av1_dist_wtd_convolve_2d_copy_c(const uint8_t* src,
+                                     int src_stride,
+                                     uint8_t* dst,
+                                     int dst_stride,
+                                     int w,
+                                     int h,
+                                     const InterpFilterParams* filter_params_x,
+                                     const InterpFilterParams* filter_params_y,
+                                     const int subpel_x_q4,
+                                     const int subpel_y_q4,
+                                     ConvolveParams* conv_params);
+void av1_dist_wtd_convolve_2d_copy_neon(
+    const uint8_t* src,
+    int src_stride,
+    uint8_t* dst,
+    int dst_stride,
+    int w,
+    int h,
+    const InterpFilterParams* filter_params_x,
+    const InterpFilterParams* filter_params_y,
+    const int subpel_x_q4,
+    const int subpel_y_q4,
+    ConvolveParams* conv_params);
+#define av1_dist_wtd_convolve_2d_copy av1_dist_wtd_convolve_2d_copy_neon
+
+void av1_dist_wtd_convolve_x_c(const uint8_t* src,
+                               int src_stride,
+                               uint8_t* dst,
+                               int dst_stride,
+                               int w,
+                               int h,
+                               const InterpFilterParams* filter_params_x,
+                               const InterpFilterParams* filter_params_y,
+                               const int subpel_x_q4,
+                               const int subpel_y_q4,
+                               ConvolveParams* conv_params);
+void av1_dist_wtd_convolve_x_neon(const uint8_t* src,
+                                  int src_stride,
+                                  uint8_t* dst,
+                                  int dst_stride,
+                                  int w,
+                                  int h,
+                                  const InterpFilterParams* filter_params_x,
+                                  const InterpFilterParams* filter_params_y,
+                                  const int subpel_x_q4,
+                                  const int subpel_y_q4,
+                                  ConvolveParams* conv_params);
+#define av1_dist_wtd_convolve_x av1_dist_wtd_convolve_x_neon
+
+void av1_dist_wtd_convolve_y_c(const uint8_t* src,
+                               int src_stride,
+                               uint8_t* dst,
+                               int dst_stride,
+                               int w,
+                               int h,
+                               const InterpFilterParams* filter_params_x,
+                               const InterpFilterParams* filter_params_y,
+                               const int subpel_x_q4,
+                               const int subpel_y_q4,
+                               ConvolveParams* conv_params);
+void av1_dist_wtd_convolve_y_neon(const uint8_t* src,
+                                  int src_stride,
+                                  uint8_t* dst,
+                                  int dst_stride,
+                                  int w,
+                                  int h,
+                                  const InterpFilterParams* filter_params_x,
+                                  const InterpFilterParams* filter_params_y,
+                                  const int subpel_x_q4,
+                                  const int subpel_y_q4,
+                                  ConvolveParams* conv_params);
+#define av1_dist_wtd_convolve_y av1_dist_wtd_convolve_y_neon
+
+void av1_dr_prediction_z1_c(uint8_t* dst,
+                            ptrdiff_t stride,
+                            int bw,
+                            int bh,
+                            const uint8_t* above,
+                            const uint8_t* left,
+                            int upsample_above,
+                            int dx,
+                            int dy);
+#define av1_dr_prediction_z1 av1_dr_prediction_z1_c
+
+void av1_dr_prediction_z2_c(uint8_t* dst,
+                            ptrdiff_t stride,
+                            int bw,
+                            int bh,
+                            const uint8_t* above,
+                            const uint8_t* left,
+                            int upsample_above,
+                            int upsample_left,
+                            int dx,
+                            int dy);
+#define av1_dr_prediction_z2 av1_dr_prediction_z2_c
+
+void av1_dr_prediction_z3_c(uint8_t* dst,
+                            ptrdiff_t stride,
+                            int bw,
+                            int bh,
+                            const uint8_t* above,
+                            const uint8_t* left,
+                            int upsample_left,
+                            int dx,
+                            int dy);
+#define av1_dr_prediction_z3 av1_dr_prediction_z3_c
+
+void av1_filter_intra_edge_c(uint8_t* p, int sz, int strength);
+#define av1_filter_intra_edge av1_filter_intra_edge_c
+
+void av1_filter_intra_edge_high_c(uint16_t* p, int sz, int strength);
+#define av1_filter_intra_edge_high av1_filter_intra_edge_high_c
+
+void av1_filter_intra_predictor_c(uint8_t* dst,
+                                  ptrdiff_t stride,
+                                  TX_SIZE tx_size,
+                                  const uint8_t* above,
+                                  const uint8_t* left,
+                                  int mode);
+#define av1_filter_intra_predictor av1_filter_intra_predictor_c
+
+void av1_highbd_convolve8_c(const uint8_t* src,
+                            ptrdiff_t src_stride,
+                            uint8_t* dst,
+                            ptrdiff_t dst_stride,
+                            const int16_t* filter_x,
+                            int x_step_q4,
+                            const int16_t* filter_y,
+                            int y_step_q4,
+                            int w,
+                            int h,
+                            int bps);
+#define av1_highbd_convolve8 av1_highbd_convolve8_c
+
+void av1_highbd_convolve8_horiz_c(const uint8_t* src,
+                                  ptrdiff_t src_stride,
+                                  uint8_t* dst,
+                                  ptrdiff_t dst_stride,
+                                  const int16_t* filter_x,
+                                  int x_step_q4,
+                                  const int16_t* filter_y,
+                                  int y_step_q4,
+                                  int w,
+                                  int h,
+                                  int bps);
+#define av1_highbd_convolve8_horiz av1_highbd_convolve8_horiz_c
+
+void av1_highbd_convolve8_vert_c(const uint8_t* src,
+                                 ptrdiff_t src_stride,
+                                 uint8_t* dst,
+                                 ptrdiff_t dst_stride,
+                                 const int16_t* filter_x,
+                                 int x_step_q4,
+                                 const int16_t* filter_y,
+                                 int y_step_q4,
+                                 int w,
+                                 int h,
+                                 int bps);
+#define av1_highbd_convolve8_vert av1_highbd_convolve8_vert_c
+
+void av1_highbd_convolve_2d_copy_sr_c(const uint16_t* src,
+                                      int src_stride,
+                                      uint16_t* dst,
+                                      int dst_stride,
+                                      int w,
+                                      int h,
+                                      const InterpFilterParams* filter_params_x,
+                                      const InterpFilterParams* filter_params_y,
+                                      const int subpel_x_q4,
+                                      const int subpel_y_q4,
+                                      ConvolveParams* conv_params,
+                                      int bd);
+#define av1_highbd_convolve_2d_copy_sr av1_highbd_convolve_2d_copy_sr_c
+
+void av1_highbd_convolve_2d_scale_c(const uint16_t* src,
+                                    int src_stride,
+                                    uint16_t* dst,
+                                    int dst_stride,
+                                    int w,
+                                    int h,
+                                    const InterpFilterParams* filter_params_x,
+                                    const InterpFilterParams* filter_params_y,
+                                    const int subpel_x_q4,
+                                    const int x_step_qn,
+                                    const int subpel_y_q4,
+                                    const int y_step_qn,
+                                    ConvolveParams* conv_params,
+                                    int bd);
+#define av1_highbd_convolve_2d_scale av1_highbd_convolve_2d_scale_c
+
+void av1_highbd_convolve_2d_sr_c(const uint16_t* src,
+                                 int src_stride,
+                                 uint16_t* dst,
+                                 int dst_stride,
+                                 int w,
+                                 int h,
+                                 const InterpFilterParams* filter_params_x,
+                                 const InterpFilterParams* filter_params_y,
+                                 const int subpel_x_q4,
+                                 const int subpel_y_q4,
+                                 ConvolveParams* conv_params,
+                                 int bd);
+#define av1_highbd_convolve_2d_sr av1_highbd_convolve_2d_sr_c
+
+void av1_highbd_convolve_avg_c(const uint8_t* src,
+                               ptrdiff_t src_stride,
+                               uint8_t* dst,
+                               ptrdiff_t dst_stride,
+                               const int16_t* filter_x,
+                               int x_step_q4,
+                               const int16_t* filter_y,
+                               int y_step_q4,
+                               int w,
+                               int h,
+                               int bps);
+#define av1_highbd_convolve_avg av1_highbd_convolve_avg_c
+
+void av1_highbd_convolve_copy_c(const uint8_t* src,
+                                ptrdiff_t src_stride,
+                                uint8_t* dst,
+                                ptrdiff_t dst_stride,
+                                const int16_t* filter_x,
+                                int x_step_q4,
+                                const int16_t* filter_y,
+                                int y_step_q4,
+                                int w,
+                                int h,
+                                int bps);
+#define av1_highbd_convolve_copy av1_highbd_convolve_copy_c
+
+void av1_highbd_convolve_horiz_rs_c(const uint16_t* src,
+                                    int src_stride,
+                                    uint16_t* dst,
+                                    int dst_stride,
+                                    int w,
+                                    int h,
+                                    const int16_t* x_filters,
+                                    int x0_qn,
+                                    int x_step_qn,
+                                    int bd);
+#define av1_highbd_convolve_horiz_rs av1_highbd_convolve_horiz_rs_c
+
+void av1_highbd_convolve_x_sr_c(const uint16_t* src,
+                                int src_stride,
+                                uint16_t* dst,
+                                int dst_stride,
+                                int w,
+                                int h,
+                                const InterpFilterParams* filter_params_x,
+                                const InterpFilterParams* filter_params_y,
+                                const int subpel_x_q4,
+                                const int subpel_y_q4,
+                                ConvolveParams* conv_params,
+                                int bd);
+#define av1_highbd_convolve_x_sr av1_highbd_convolve_x_sr_c
+
+void av1_highbd_convolve_y_sr_c(const uint16_t* src,
+                                int src_stride,
+                                uint16_t* dst,
+                                int dst_stride,
+                                int w,
+                                int h,
+                                const InterpFilterParams* filter_params_x,
+                                const InterpFilterParams* filter_params_y,
+                                const int subpel_x_q4,
+                                const int subpel_y_q4,
+                                ConvolveParams* conv_params,
+                                int bd);
+#define av1_highbd_convolve_y_sr av1_highbd_convolve_y_sr_c
+
+void av1_highbd_dist_wtd_convolve_2d_c(
+    const uint16_t* src,
+    int src_stride,
+    uint16_t* dst,
+    int dst_stride,
+    int w,
+    int h,
+    const InterpFilterParams* filter_params_x,
+    const InterpFilterParams* filter_params_y,
+    const int subpel_x_q4,
+    const int subpel_y_q4,
+    ConvolveParams* conv_params,
+    int bd);
+#define av1_highbd_dist_wtd_convolve_2d av1_highbd_dist_wtd_convolve_2d_c
+
+void av1_highbd_dist_wtd_convolve_2d_copy_c(
+    const uint16_t* src,
+    int src_stride,
+    uint16_t* dst,
+    int dst_stride,
+    int w,
+    int h,
+    const InterpFilterParams* filter_params_x,
+    const InterpFilterParams* filter_params_y,
+    const int subpel_x_q4,
+    const int subpel_y_q4,
+    ConvolveParams* conv_params,
+    int bd);
+#define av1_highbd_dist_wtd_convolve_2d_copy \
+  av1_highbd_dist_wtd_convolve_2d_copy_c
+
+void av1_highbd_dist_wtd_convolve_x_c(const uint16_t* src,
+                                      int src_stride,
+                                      uint16_t* dst,
+                                      int dst_stride,
+                                      int w,
+                                      int h,
+                                      const InterpFilterParams* filter_params_x,
+                                      const InterpFilterParams* filter_params_y,
+                                      const int subpel_x_q4,
+                                      const int subpel_y_q4,
+                                      ConvolveParams* conv_params,
+                                      int bd);
+#define av1_highbd_dist_wtd_convolve_x av1_highbd_dist_wtd_convolve_x_c
+
+void av1_highbd_dist_wtd_convolve_y_c(const uint16_t* src,
+                                      int src_stride,
+                                      uint16_t* dst,
+                                      int dst_stride,
+                                      int w,
+                                      int h,
+                                      const InterpFilterParams* filter_params_x,
+                                      const InterpFilterParams* filter_params_y,
+                                      const int subpel_x_q4,
+                                      const int subpel_y_q4,
+                                      ConvolveParams* conv_params,
+                                      int bd);
+#define av1_highbd_dist_wtd_convolve_y av1_highbd_dist_wtd_convolve_y_c
+
+void av1_highbd_dr_prediction_z1_c(uint16_t* dst,
+                                   ptrdiff_t stride,
+                                   int bw,
+                                   int bh,
+                                   const uint16_t* above,
+                                   const uint16_t* left,
+                                   int upsample_above,
+                                   int dx,
+                                   int dy,
+                                   int bd);
+#define av1_highbd_dr_prediction_z1 av1_highbd_dr_prediction_z1_c
+
+void av1_highbd_dr_prediction_z2_c(uint16_t* dst,
+                                   ptrdiff_t stride,
+                                   int bw,
+                                   int bh,
+                                   const uint16_t* above,
+                                   const uint16_t* left,
+                                   int upsample_above,
+                                   int upsample_left,
+                                   int dx,
+                                   int dy,
+                                   int bd);
+#define av1_highbd_dr_prediction_z2 av1_highbd_dr_prediction_z2_c
+
+void av1_highbd_dr_prediction_z3_c(uint16_t* dst,
+                                   ptrdiff_t stride,
+                                   int bw,
+                                   int bh,
+                                   const uint16_t* above,
+                                   const uint16_t* left,
+                                   int upsample_left,
+                                   int dx,
+                                   int dy,
+                                   int bd);
+#define av1_highbd_dr_prediction_z3 av1_highbd_dr_prediction_z3_c
+
+void av1_highbd_inv_txfm_add_c(const tran_low_t* dqcoeff,
+                               uint8_t* dst,
+                               int stride,
+                               const TxfmParam* txfm_param);
+#define av1_highbd_inv_txfm_add av1_highbd_inv_txfm_add_c
+
+void av1_highbd_inv_txfm_add_16x4_c(const tran_low_t* dqcoeff,
+                                    uint8_t* dst,
+                                    int stride,
+                                    const TxfmParam* txfm_param);
+#define av1_highbd_inv_txfm_add_16x4 av1_highbd_inv_txfm_add_16x4_c
+
+void av1_highbd_inv_txfm_add_4x16_c(const tran_low_t* dqcoeff,
+                                    uint8_t* dst,
+                                    int stride,
+                                    const TxfmParam* txfm_param);
+#define av1_highbd_inv_txfm_add_4x16 av1_highbd_inv_txfm_add_4x16_c
+
+void av1_highbd_inv_txfm_add_4x4_c(const tran_low_t* dqcoeff,
+                                   uint8_t* dst,
+                                   int stride,
+                                   const TxfmParam* txfm_param);
+#define av1_highbd_inv_txfm_add_4x4 av1_highbd_inv_txfm_add_4x4_c
+
+void av1_highbd_inv_txfm_add_4x8_c(const tran_low_t* dqcoeff,
+                                   uint8_t* dst,
+                                   int stride,
+                                   const TxfmParam* txfm_param);
+#define av1_highbd_inv_txfm_add_4x8 av1_highbd_inv_txfm_add_4x8_c
+
+void av1_highbd_inv_txfm_add_8x4_c(const tran_low_t* dqcoeff,
+                                   uint8_t* dst,
+                                   int stride,
+                                   const TxfmParam* txfm_param);
+#define av1_highbd_inv_txfm_add_8x4 av1_highbd_inv_txfm_add_8x4_c
+
+void av1_highbd_inv_txfm_add_8x8_c(const tran_low_t* dqcoeff,
+                                   uint8_t* dst,
+                                   int stride,
+                                   const TxfmParam* txfm_param);
+#define av1_highbd_inv_txfm_add_8x8 av1_highbd_inv_txfm_add_8x8_c
+
+void av1_highbd_iwht4x4_16_add_c(const tran_low_t* input,
+                                 uint8_t* dest,
+                                 int dest_stride,
+                                 int bd);
+#define av1_highbd_iwht4x4_16_add av1_highbd_iwht4x4_16_add_c
+
+void av1_highbd_iwht4x4_1_add_c(const tran_low_t* input,
+                                uint8_t* dest,
+                                int dest_stride,
+                                int bd);
+#define av1_highbd_iwht4x4_1_add av1_highbd_iwht4x4_1_add_c
+
+void av1_highbd_warp_affine_c(const int32_t* mat,
+                              const uint16_t* ref,
+                              int width,
+                              int height,
+                              int stride,
+                              uint16_t* pred,
+                              int p_col,
+                              int p_row,
+                              int p_width,
+                              int p_height,
+                              int p_stride,
+                              int subsampling_x,
+                              int subsampling_y,
+                              int bd,
+                              ConvolveParams* conv_params,
+                              int16_t alpha,
+                              int16_t beta,
+                              int16_t gamma,
+                              int16_t delta);
+#define av1_highbd_warp_affine av1_highbd_warp_affine_c
+
+void av1_highbd_wiener_convolve_add_src_c(const uint8_t* src,
+                                          ptrdiff_t src_stride,
+                                          uint8_t* dst,
+                                          ptrdiff_t dst_stride,
+                                          const int16_t* filter_x,
+                                          int x_step_q4,
+                                          const int16_t* filter_y,
+                                          int y_step_q4,
+                                          int w,
+                                          int h,
+                                          const ConvolveParams* conv_params,
+                                          int bps);
+#define av1_highbd_wiener_convolve_add_src av1_highbd_wiener_convolve_add_src_c
+
+void av1_inv_txfm2d_add_16x16_c(const int32_t* input,
+                                uint16_t* output,
+                                int stride,
+                                TX_TYPE tx_type,
+                                int bd);
+#define av1_inv_txfm2d_add_16x16 av1_inv_txfm2d_add_16x16_c
+
+void av1_inv_txfm2d_add_16x32_c(const int32_t* input,
+                                uint16_t* output,
+                                int stride,
+                                TX_TYPE tx_type,
+                                int bd);
+#define av1_inv_txfm2d_add_16x32 av1_inv_txfm2d_add_16x32_c
+
+void av1_inv_txfm2d_add_16x4_c(const int32_t* input,
+                               uint16_t* output,
+                               int stride,
+                               TX_TYPE tx_type,
+                               int bd);
+#define av1_inv_txfm2d_add_16x4 av1_inv_txfm2d_add_16x4_c
+
+void av1_inv_txfm2d_add_16x64_c(const int32_t* input,
+                                uint16_t* output,
+                                int stride,
+                                TX_TYPE tx_type,
+                                int bd);
+#define av1_inv_txfm2d_add_16x64 av1_inv_txfm2d_add_16x64_c
+
+void av1_inv_txfm2d_add_16x8_c(const int32_t* input,
+                               uint16_t* output,
+                               int stride,
+                               TX_TYPE tx_type,
+                               int bd);
+#define av1_inv_txfm2d_add_16x8 av1_inv_txfm2d_add_16x8_c
+
+void av1_inv_txfm2d_add_32x16_c(const int32_t* input,
+                                uint16_t* output,
+                                int stride,
+                                TX_TYPE tx_type,
+                                int bd);
+#define av1_inv_txfm2d_add_32x16 av1_inv_txfm2d_add_32x16_c
+
+void av1_inv_txfm2d_add_32x32_c(const int32_t* input,
+                                uint16_t* output,
+                                int stride,
+                                TX_TYPE tx_type,
+                                int bd);
+#define av1_inv_txfm2d_add_32x32 av1_inv_txfm2d_add_32x32_c
+
+void av1_inv_txfm2d_add_32x64_c(const int32_t* input,
+                                uint16_t* output,
+                                int stride,
+                                TX_TYPE tx_type,
+                                int bd);
+#define av1_inv_txfm2d_add_32x64 av1_inv_txfm2d_add_32x64_c
+
+void av1_inv_txfm2d_add_32x8_c(const int32_t* input,
+                               uint16_t* output,
+                               int stride,
+                               TX_TYPE tx_type,
+                               int bd);
+#define av1_inv_txfm2d_add_32x8 av1_inv_txfm2d_add_32x8_c
+
+void av1_inv_txfm2d_add_4x16_c(const int32_t* input,
+                               uint16_t* output,
+                               int stride,
+                               TX_TYPE tx_type,
+                               int bd);
+#define av1_inv_txfm2d_add_4x16 av1_inv_txfm2d_add_4x16_c
+
+void av1_inv_txfm2d_add_4x4_c(const int32_t* input,
+                              uint16_t* output,
+                              int stride,
+                              TX_TYPE tx_type,
+                              int bd);
+#define av1_inv_txfm2d_add_4x4 av1_inv_txfm2d_add_4x4_c
+
+void av1_inv_txfm2d_add_4x8_c(const int32_t* input,
+                              uint16_t* output,
+                              int stride,
+                              TX_TYPE tx_type,
+                              int bd);
+#define av1_inv_txfm2d_add_4x8 av1_inv_txfm2d_add_4x8_c
+
+void av1_inv_txfm2d_add_64x16_c(const int32_t* input,
+                                uint16_t* output,
+                                int stride,
+                                TX_TYPE tx_type,
+                                int bd);
+#define av1_inv_txfm2d_add_64x16 av1_inv_txfm2d_add_64x16_c
+
+void av1_inv_txfm2d_add_64x32_c(const int32_t* input,
+                                uint16_t* output,
+                                int stride,
+                                TX_TYPE tx_type,
+                                int bd);
+#define av1_inv_txfm2d_add_64x32 av1_inv_txfm2d_add_64x32_c
+
+void av1_inv_txfm2d_add_64x64_c(const int32_t* input,
+                                uint16_t* output,
+                                int stride,
+                                TX_TYPE tx_type,
+                                int bd);
+#define av1_inv_txfm2d_add_64x64 av1_inv_txfm2d_add_64x64_c
+
+void av1_inv_txfm2d_add_8x16_c(const int32_t* input,
+                               uint16_t* output,
+                               int stride,
+                               TX_TYPE tx_type,
+                               int bd);
+#define av1_inv_txfm2d_add_8x16 av1_inv_txfm2d_add_8x16_c
+
+void av1_inv_txfm2d_add_8x32_c(const int32_t* input,
+                               uint16_t* output,
+                               int stride,
+                               TX_TYPE tx_type,
+                               int bd);
+#define av1_inv_txfm2d_add_8x32 av1_inv_txfm2d_add_8x32_c
+
+void av1_inv_txfm2d_add_8x4_c(const int32_t* input,
+                              uint16_t* output,
+                              int stride,
+                              TX_TYPE tx_type,
+                              int bd);
+#define av1_inv_txfm2d_add_8x4 av1_inv_txfm2d_add_8x4_c
+
+void av1_inv_txfm2d_add_8x8_c(const int32_t* input,
+                              uint16_t* output,
+                              int stride,
+                              TX_TYPE tx_type,
+                              int bd);
+#define av1_inv_txfm2d_add_8x8 av1_inv_txfm2d_add_8x8_c
+
+void av1_inv_txfm_add_c(const tran_low_t* dqcoeff,
+                        uint8_t* dst,
+                        int stride,
+                        const TxfmParam* txfm_param);
+void av1_inv_txfm_add_neon(const tran_low_t* dqcoeff,
+                           uint8_t* dst,
+                           int stride,
+                           const TxfmParam* txfm_param);
+#define av1_inv_txfm_add av1_inv_txfm_add_neon
+
+void av1_round_shift_array_c(int32_t* arr, int size, int bit);
+void av1_round_shift_array_neon(int32_t* arr, int size, int bit);
+#define av1_round_shift_array av1_round_shift_array_neon
+
+int av1_selfguided_restoration_c(const uint8_t* dgd8,
+                                 int width,
+                                 int height,
+                                 int dgd_stride,
+                                 int32_t* flt0,
+                                 int32_t* flt1,
+                                 int flt_stride,
+                                 int sgr_params_idx,
+                                 int bit_depth,
+                                 int highbd);
+int av1_selfguided_restoration_neon(const uint8_t* dgd8,
+                                    int width,
+                                    int height,
+                                    int dgd_stride,
+                                    int32_t* flt0,
+                                    int32_t* flt1,
+                                    int flt_stride,
+                                    int sgr_params_idx,
+                                    int bit_depth,
+                                    int highbd);
+#define av1_selfguided_restoration av1_selfguided_restoration_neon
+
+void av1_upsample_intra_edge_c(uint8_t* p, int sz);
+#define av1_upsample_intra_edge av1_upsample_intra_edge_c
+
+void av1_upsample_intra_edge_high_c(uint16_t* p, int sz, int bd);
+#define av1_upsample_intra_edge_high av1_upsample_intra_edge_high_c
+
+void av1_warp_affine_c(const int32_t* mat,
+                       const uint8_t* ref,
+                       int width,
+                       int height,
+                       int stride,
+                       uint8_t* pred,
+                       int p_col,
+                       int p_row,
+                       int p_width,
+                       int p_height,
+                       int p_stride,
+                       int subsampling_x,
+                       int subsampling_y,
+                       ConvolveParams* conv_params,
+                       int16_t alpha,
+                       int16_t beta,
+                       int16_t gamma,
+                       int16_t delta);
+void av1_warp_affine_neon(const int32_t* mat,
+                          const uint8_t* ref,
+                          int width,
+                          int height,
+                          int stride,
+                          uint8_t* pred,
+                          int p_col,
+                          int p_row,
+                          int p_width,
+                          int p_height,
+                          int p_stride,
+                          int subsampling_x,
+                          int subsampling_y,
+                          ConvolveParams* conv_params,
+                          int16_t alpha,
+                          int16_t beta,
+                          int16_t gamma,
+                          int16_t delta);
+#define av1_warp_affine av1_warp_affine_neon
+
+void av1_wiener_convolve_add_src_c(const uint8_t* src,
+                                   ptrdiff_t src_stride,
+                                   uint8_t* dst,
+                                   ptrdiff_t dst_stride,
+                                   const int16_t* filter_x,
+                                   int x_step_q4,
+                                   const int16_t* filter_y,
+                                   int y_step_q4,
+                                   int w,
+                                   int h,
+                                   const ConvolveParams* conv_params);
+void av1_wiener_convolve_add_src_neon(const uint8_t* src,
+                                      ptrdiff_t src_stride,
+                                      uint8_t* dst,
+                                      ptrdiff_t dst_stride,
+                                      const int16_t* filter_x,
+                                      int x_step_q4,
+                                      const int16_t* filter_y,
+                                      int y_step_q4,
+                                      int w,
+                                      int h,
+                                      const ConvolveParams* conv_params);
+#define av1_wiener_convolve_add_src av1_wiener_convolve_add_src_neon
+
+void cdef_filter_block_c(uint8_t* dst8,
+                         uint16_t* dst16,
+                         int dstride,
+                         const uint16_t* in,
+                         int pri_strength,
+                         int sec_strength,
+                         int dir,
+                         int pri_damping,
+                         int sec_damping,
+                         int bsize,
+                         int coeff_shift);
+void cdef_filter_block_neon(uint8_t* dst8,
+                            uint16_t* dst16,
+                            int dstride,
+                            const uint16_t* in,
+                            int pri_strength,
+                            int sec_strength,
+                            int dir,
+                            int pri_damping,
+                            int sec_damping,
+                            int bsize,
+                            int coeff_shift);
+#define cdef_filter_block cdef_filter_block_neon
+
+int cdef_find_dir_c(const uint16_t* img,
+                    int stride,
+                    int32_t* var,
+                    int coeff_shift);
+int cdef_find_dir_neon(const uint16_t* img,
+                       int stride,
+                       int32_t* var,
+                       int coeff_shift);
+#define cdef_find_dir cdef_find_dir_neon
+
+cfl_subsample_hbd_fn cfl_get_luma_subsampling_420_hbd_c(TX_SIZE tx_size);
+cfl_subsample_hbd_fn cfl_get_luma_subsampling_420_hbd_neon(TX_SIZE tx_size);
+#define cfl_get_luma_subsampling_420_hbd cfl_get_luma_subsampling_420_hbd_neon
+
+cfl_subsample_lbd_fn cfl_get_luma_subsampling_420_lbd_c(TX_SIZE tx_size);
+cfl_subsample_lbd_fn cfl_get_luma_subsampling_420_lbd_neon(TX_SIZE tx_size);
+#define cfl_get_luma_subsampling_420_lbd cfl_get_luma_subsampling_420_lbd_neon
+
+cfl_subsample_hbd_fn cfl_get_luma_subsampling_422_hbd_c(TX_SIZE tx_size);
+cfl_subsample_hbd_fn cfl_get_luma_subsampling_422_hbd_neon(TX_SIZE tx_size);
+#define cfl_get_luma_subsampling_422_hbd cfl_get_luma_subsampling_422_hbd_neon
+
+cfl_subsample_lbd_fn cfl_get_luma_subsampling_422_lbd_c(TX_SIZE tx_size);
+cfl_subsample_lbd_fn cfl_get_luma_subsampling_422_lbd_neon(TX_SIZE tx_size);
+#define cfl_get_luma_subsampling_422_lbd cfl_get_luma_subsampling_422_lbd_neon
+
+cfl_subsample_hbd_fn cfl_get_luma_subsampling_444_hbd_c(TX_SIZE tx_size);
+cfl_subsample_hbd_fn cfl_get_luma_subsampling_444_hbd_neon(TX_SIZE tx_size);
+#define cfl_get_luma_subsampling_444_hbd cfl_get_luma_subsampling_444_hbd_neon
+
+cfl_subsample_lbd_fn cfl_get_luma_subsampling_444_lbd_c(TX_SIZE tx_size);
+cfl_subsample_lbd_fn cfl_get_luma_subsampling_444_lbd_neon(TX_SIZE tx_size);
+#define cfl_get_luma_subsampling_444_lbd cfl_get_luma_subsampling_444_lbd_neon
+
+void copy_rect8_16bit_to_16bit_c(uint16_t* dst,
+                                 int dstride,
+                                 const uint16_t* src,
+                                 int sstride,
+                                 int v,
+                                 int h);
+void copy_rect8_16bit_to_16bit_neon(uint16_t* dst,
+                                    int dstride,
+                                    const uint16_t* src,
+                                    int sstride,
+                                    int v,
+                                    int h);
+#define copy_rect8_16bit_to_16bit copy_rect8_16bit_to_16bit_neon
+
+void copy_rect8_8bit_to_16bit_c(uint16_t* dst,
+                                int dstride,
+                                const uint8_t* src,
+                                int sstride,
+                                int v,
+                                int h);
+void copy_rect8_8bit_to_16bit_neon(uint16_t* dst,
+                                   int dstride,
+                                   const uint8_t* src,
+                                   int sstride,
+                                   int v,
+                                   int h);
+#define copy_rect8_8bit_to_16bit copy_rect8_8bit_to_16bit_neon
+
+cfl_predict_hbd_fn get_predict_hbd_fn_c(TX_SIZE tx_size);
+cfl_predict_hbd_fn get_predict_hbd_fn_neon(TX_SIZE tx_size);
+#define get_predict_hbd_fn get_predict_hbd_fn_neon
+
+cfl_predict_lbd_fn get_predict_lbd_fn_c(TX_SIZE tx_size);
+cfl_predict_lbd_fn get_predict_lbd_fn_neon(TX_SIZE tx_size);
+#define get_predict_lbd_fn get_predict_lbd_fn_neon
+
+cfl_subtract_average_fn get_subtract_average_fn_c(TX_SIZE tx_size);
+cfl_subtract_average_fn get_subtract_average_fn_neon(TX_SIZE tx_size);
+#define get_subtract_average_fn get_subtract_average_fn_neon
+
+void av1_rtcd(void);
+
+#include "config/aom_config.h"
+
+#ifdef RTCD_C
+#include "aom_ports/arm.h"
+static void setup_rtcd_internal(void) {
+  int flags = aom_arm_cpu_caps();
+
+  (void)flags;
+}
+#endif
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif
diff --git a/tools/binary_size/libsupersize/archive.py b/tools/binary_size/libsupersize/archive.py
index f272539e..3f5ba8df 100644
--- a/tools/binary_size/libsupersize/archive.py
+++ b/tools/binary_size/libsupersize/archive.py
@@ -111,32 +111,6 @@
   return open(path, 'rb')
 
 
-def _StripLinkerAddedSymbolPrefixes(raw_symbols):
-  """Removes prefixes sometimes added to symbol names during link
-
-  Removing prefixes make symbol names match up with those found in .o files.
-  """
-  for symbol in raw_symbols:
-    full_name = symbol.full_name
-    if full_name.startswith('startup.'):
-      symbol.flags |= models.FLAG_STARTUP
-      symbol.full_name = full_name[8:]
-    elif full_name.startswith('unlikely.'):
-      symbol.flags |= models.FLAG_UNLIKELY
-      symbol.full_name = full_name[9:]
-    elif full_name.startswith('rel.local.'):
-      symbol.flags |= models.FLAG_REL_LOCAL
-      symbol.full_name = full_name[10:]
-    elif full_name.startswith('rel.'):
-      symbol.flags |= models.FLAG_REL
-      symbol.full_name = full_name[4:]
-    elif full_name.startswith('hot.'):
-      symbol.flags |= models.FLAG_HOT
-      symbol.full_name = full_name[4:]
-    elif full_name.startswith('.L.str'):
-      symbol.full_name = models.STRING_LITERAL_NAME
-
-
 def _NormalizeNames(raw_symbols):
   """Ensures that all names are formatted in a useful way.
 
@@ -911,8 +885,6 @@
       string_ranges = [(s.address, s.size) for s in merge_string_syms]
       bulk_analyzer.AnalyzeStringLiterals(elf_path, string_ranges)
 
-  logging.info('Stripping linker prefixes from symbol names')
-  _StripLinkerAddedSymbolPrefixes(raw_symbols)
   # Map file for some reason doesn't demangle all names.
   # Demangle prints its own log statement.
   demangle.DemangleRemainingSymbols(raw_symbols, tool_prefix)
@@ -958,7 +930,9 @@
             # is fast enough since len(merge_string_syms) < 10.
             raw_symbols[idx:idx + 1] = literal_syms
 
-  return section_sizes, raw_symbols, object_paths_by_name, linker_map_extras
+  linker_map_parser.DeduceObjectPathsFromThinMap(raw_symbols, linker_map_extras)
+
+  return section_sizes, raw_symbols, object_paths_by_name
 
 
 def _ComputePakFileSymbols(
@@ -1315,8 +1289,7 @@
         source_mapper=source_mapper,
         thin_archives=thin_archives)
 
-  (section_sizes, raw_symbols, object_paths_by_name,
-   linker_map_extras) = _ParseElfInfo(
+  section_sizes, raw_symbols, object_paths_by_name = _ParseElfInfo(
        map_path,
        elf_path,
        tool_prefix,
@@ -1360,7 +1333,6 @@
     raw_symbols.extend(pak_raw_symbols)
 
   _ExtractSourcePathsAndNormalizeObjectPaths(raw_symbols, source_mapper)
-  linker_map_parser.DeduceObjectPathsFromThinMap(raw_symbols, linker_map_extras)
   _PopulateComponents(raw_symbols, knobs)
   logging.info('Converting excessive aliases into shared-path symbols')
   _CompactLargeAliasesIntoSharedSymbols(raw_symbols, knobs)
@@ -1484,7 +1456,7 @@
   elif args.f.endswith('.apk'):
     args.apk_file = args.f
     logging.info('Auto-identified --apk-file.')
-  elif args.f.endswith('.so') or '.' not in args.f:
+  elif args.f.endswith('.so') or '.' not in os.path.basename(args.f):
     logging.info('Auto-identified --elf-file.')
     args.elf_file = args.f
   elif args.f.endswith('.map') or args.f.endswith('.map.gz'):
@@ -1579,7 +1551,7 @@
   if map_path:
     if not map_path.endswith('.map') and not map_path.endswith('.map.gz'):
       parser.error('Expected --map-file to end with .map or .map.gz')
-  else:
+  elif elf_path:
     map_path = elf_path + '.map'
     if not os.path.exists(map_path):
       map_path += '.gz'
@@ -1587,14 +1559,17 @@
       parser.error('Could not find .map(.gz)? file. Ensure you have built with '
                    'is_official_build=true and generate_linker_map=true, or '
                    'use --map-file to point me a linker map file.')
+  tool_prefix = None
+  if map_path:
+    linker_name = _DetectLinkerName(map_path)
+    logging.info('Linker name: %s' % linker_name)
 
-  linker_name = _DetectLinkerName(map_path)
-  logging.info('Linker name: %s' % linker_name)
-  tool_prefix_finder = path_util.ToolPrefixFinder(
-      value=args.tool_prefix,
-      output_directory_finder=output_directory_finder,
-      linker_name=linker_name)
-  tool_prefix = tool_prefix_finder.Finalized()
+    tool_prefix_finder = path_util.ToolPrefixFinder(
+        value=args.tool_prefix,
+        output_directory_finder=output_directory_finder,
+        linker_name=linker_name)
+    tool_prefix = tool_prefix_finder.Finalized()
+
   output_directory = None
   if not args.no_source_paths:
     output_directory = output_directory_finder.Finalized()
diff --git a/tools/binary_size/libsupersize/console.py b/tools/binary_size/libsupersize/console.py
index 455314b..2d4bc76 100644
--- a/tools/binary_size/libsupersize/console.py
+++ b/tools/binary_size/libsupersize/console.py
@@ -76,6 +76,7 @@
         'ReadStringLiterals': self._ReadStringLiterals,
         'Disassemble': self._DisassembleFunc,
         'ExpandRegex': match_util.ExpandRegexIdentifierPlaceholder,
+        'SizeStats': self._SizeStats,
         'ShowExamples': self._ShowExamplesFunc,
         'canned_queries': canned_queries.CannedQueries(size_infos),
         'printed': self._printed_variables,
@@ -147,14 +148,24 @@
     """Diffs two SizeInfo objects. Returns a DeltaSizeInfo.
 
     Args:
-      before: Defaults to first size_infos[0].
-      after: Defaults to second size_infos[1].
+      before: Defaults to size_infos[0].
+      after: Defaults to size_infos[1].
       sort: When True (default), calls SymbolGroup.Sorted() after diffing.
     """
     before = before if before is not None else self._size_infos[0]
     after = after if after is not None else self._size_infos[1]
     return diff.Diff(before, after, sort=sort)
 
+  def _SizeStats(self, size_info=None):
+    """Prints some statistics for the given size info.
+
+    Args:
+      size_info: Defaults to size_infos[0].
+    """
+    size_info = size_info or self._size_infos[0]
+    describe.WriteLines(
+        describe.DescribeSizeInfoCoverage(size_info), sys.stdout.write)
+
   def _PrintFunc(self, obj=None, verbose=False, summarize=True, recursive=False,
                  use_pager=None, to_file=None):
     """Prints out the given Symbol / SymbolGroup / SizeInfo.
diff --git a/tools/binary_size/libsupersize/describe.py b/tools/binary_size/libsupersize/describe.py
index 487d56b4..13b49dd 100644
--- a/tools/binary_size/libsupersize/describe.py
+++ b/tools/binary_size/libsupersize/describe.py
@@ -261,9 +261,11 @@
         yield '{}@{:<9s}  {}  {}{}'.format(
             sym.section, address, pss_field, sym.name, last_field)
       else:
-        path = sym.source_path or sym.object_path or '{no path}'
-        if sym.generated_source:
+        path = sym.source_path or sym.object_path
+        if path and sym.generated_source:
           path = '$root_gen_dir/' + path
+        path = path or '{no path}'
+
         yield '{}@{:<9s}  {} {}'.format(
             sym.section, address, pss_field, path)
         if sym.name:
@@ -512,64 +514,78 @@
     return itertools.chain(metadata_desc, section_desc, coverage_desc, ('',),
                            group_desc)
 
+
 def DescribeSizeInfoCoverage(size_info):
   """Yields lines describing how accurate |size_info| is."""
   for section, section_name in models.SECTION_TO_SECTION_NAME.iteritems():
-    if section_name not in size_info.section_sizes:
-      continue
-    expected_size = size_info.section_sizes[section_name]
-
+    expected_size = size_info.section_sizes.get(section_name)
     in_section = size_info.raw_symbols.WhereInSection(section_name)
     actual_size = in_section.size
-    size_percent = _Divide(actual_size, expected_size)
-    yield ('Section {}: has {:.1%} of {} bytes accounted for from '
-           '{} symbols. {} bytes are unaccounted for.').format(
-               section_name, size_percent, actual_size, len(in_section),
-               expected_size - actual_size)
 
-    sources_count = sum(1 for s in in_section if s.source_path)
-    sources_fraction = _Divide(sources_count, len(in_section))
-    yield '* {} have source paths assigned ({:.1%})'.format(
-        sources_count, sources_fraction)
+    if expected_size is None:
+      yield 'Section {}: {} bytes from {} symbols.'.format(
+          section_name, actual_size, len(in_section))
+    else:
+      size_percent = _Divide(actual_size, expected_size)
+      yield ('Section {}: has {:.1%} of {} bytes accounted for from '
+             '{} symbols. {} bytes are unaccounted for.').format(
+                 section_name, size_percent, actual_size, len(in_section),
+                 expected_size - actual_size)
 
-    star_syms = in_section.WhereNameMatches(r'^\*')
-    padding = in_section.padding - star_syms.padding
-    anonymous_syms = star_syms.Inverted().WhereHasAnyAttribution().Inverted()
+    padding = in_section.padding
     yield '* Padding accounts for {} bytes ({:.1%})'.format(
-        padding, _Divide(padding, in_section.size))
-    if len(star_syms):
-      yield ('* {} placeholders (symbols that start with **) account for '
-             '{} bytes ({:.1%})').format(
-                 len(star_syms), star_syms.size,
-                 _Divide(star_syms.size,  in_section.size))
-    if anonymous_syms:
-      yield '* {} anonymous symbols account for {} bytes ({:.1%})'.format(
-          len(anonymous_syms), int(anonymous_syms.pss),
-          _Divide(star_syms.size, in_section.size))
+        padding, _Divide(padding, actual_size))
+
+    def size_msg(syms, padding=False):
+      size = syms.size if not padding else syms.size_without_padding
+      size_msg = 'Accounts for {} bytes ({:.1%}).'.format(
+          size, _Divide(size, actual_size))
+      if padding:
+        size_msg = size_msg[:-1] + ' padding is {} bytes.'.format(syms.padding)
+      return size_msg
+
+    syms = in_section.Filter(lambda s: s.source_path)
+    yield '* {} have source paths. {}'.format(len(syms), size_msg(syms))
+
+    syms = in_section.WhereNameMatches(r'^\*')
+    if len(syms):
+      yield '* {} placeholders exist (symbols that start with **). {}'.format(
+          len(syms), size_msg(syms))
+
+    syms = syms.Inverted().WhereHasAnyAttribution().Inverted()
+    if syms:
+      yield '* {} symbols have no name or path. {}'.format(
+          len(syms), size_msg(syms))
 
     if section == 'r':
-      string_literals = in_section.Filter(lambda s: s.IsStringLiteral())
-      yield '* Contains {} string literals. Total size={}, padding={}'.format(
-          len(string_literals), string_literals.size_without_padding,
-          string_literals.padding)
+      syms = in_section.Filter(lambda s: s.IsStringLiteral())
+      yield '* {} string literals exist. {}'.format(
+          len(syms), size_msg(syms, padding=True))
 
-    aliased_symbols = in_section.Filter(lambda s: s.aliases)
-    if len(aliased_symbols):
-      uniques = sum(1 for s in aliased_symbols.IterUniqueSymbols())
+    syms = in_section.Filter(lambda s: s.aliases)
+    if len(syms):
+      uniques = sum(1 for s in syms.IterUniqueSymbols())
       saved = sum(s.size_without_padding * (s.num_aliases - 1)
-                  for s in aliased_symbols.IterUniqueSymbols())
-      yield ('* Contains {} aliases, mapped to {} unique addresses '
-             '({} bytes saved)').format(
-                 len(aliased_symbols), uniques, saved)
-    else:
-      yield '* Contains 0 aliases'
+                  for s in syms.IterUniqueSymbols())
+      yield ('* {} aliases exist, mapped to {} unique addresses '
+             '({} bytes saved)').format(len(syms), uniques, saved)
 
-    inlined_symbols = in_section.WhereObjectPathMatches('{shared}')
-    if len(inlined_symbols):
-      yield '* {} symbols have shared ownership ({} bytes)'.format(
-          len(inlined_symbols), inlined_symbols.size)
+    syms = in_section.WhereObjectPathMatches('{shared}')
+    if len(syms):
+      yield '* {} symbols have shared ownership. {}'.format(
+          len(syms), size_msg(syms))
     else:
-      yield '* 0 symbols have shared ownership'
+      yield '* 0 symbols have shared ownership.'
+
+    for flag, desc in (
+        (models.FLAG_HOT, 'marked as "hot"'),
+        (models.FLAG_UNLIKELY, 'marked as "unlikely"'),
+        (models.FLAG_STARTUP, 'marked as "startup"'),
+        (models.FLAG_CLONE, 'clones'),
+        (models.FLAG_GENERATED_SOURCE, 'from generated sources')):
+      syms = in_section.WhereHasFlag(flag)
+      if len(syms):
+        yield '* {} symbols are {}. {}'.format(len(syms), desc, size_msg(syms))
 
 
 class DescriberCsv(Describer):
diff --git a/tools/binary_size/libsupersize/linker_map_parser.py b/tools/binary_size/libsupersize/linker_map_parser.py
index 6e7038f..14488be6 100755
--- a/tools/binary_size/libsupersize/linker_map_parser.py
+++ b/tools/binary_size/libsupersize/linker_map_parser.py
@@ -39,6 +39,42 @@
 #   whereas "nm" skips over these (they don't account for much though).
 # * The parse time for compressed linker maps is dominated by ungzipping.
 
+_STRIP_NAME_PREFIX = {
+    models.FLAG_STARTUP: 8,
+    models.FLAG_UNLIKELY: 9,
+    models.FLAG_REL_LOCAL: 10,
+    models.FLAG_REL: 4,
+    models.FLAG_HOT: 4,
+}
+
+
+def _FlagsFromMangledName(name):
+  # Currently, lld map files have section = '.text.startup' and put the symbol
+  # name in the section break-down ("level 3 symbols").
+  if name.startswith('startup.') or name == 'startup':
+    return models.FLAG_STARTUP
+  if name.startswith('unlikely.'):
+    return models.FLAG_UNLIKELY
+  if name.startswith('rel.local.'):
+    return models.FLAG_REL_LOCAL
+  if name.startswith('rel.'):
+    return models.FLAG_REL
+  if name.startswith('hot.'):
+    return models.FLAG_HOT
+  return 0
+
+
+def _NormalizeName(name):
+  # Outlined functions have names like OUTLINED_FUNCTION_0, which can
+  # appear 1000+ time, and can cause false aliasing. We treat these as
+  # special cases by designating them as a placeholder symbols and
+  # renaming them to '** outlined function'.
+  if name.startswith('OUTLINED_FUNCTION_'):
+    return '** outlined function'
+  if name.startswith('.L.str'):
+    return models.STRING_LITERAL_NAME
+  return name
+
 
 class MapFileParserGold(object):
   """Parses a linker map file from gold linker."""
@@ -264,28 +300,22 @@
               #  .text.unlikely._ZN4base3CPUC2Ev
               #                 0x003f9d3c       0x48 obj/base/base/cpu.o
               #                 0x003f9d3d                base::CPU::CPU()
-              full_name = name
+              full_name = name or mangled_name
               if mangled_name and (not name or mangled_name.startswith('_Z') or
                                    '._Z' in mangled_name):
                 full_name = mangled_name
-              # Handle outlined functions. These are actual LLD features, but we
-              # handle them here for Gold to facilitate testing.
-              if full_name and full_name.startswith('OUTLINED_FUNCTION_'):
-                full_name = '** outlined function'
+
+              flags = _FlagsFromMangledName(mangled_name)
+              if full_name:
+                if flags:
+                  full_name = full_name[_STRIP_NAME_PREFIX[flags]:]
+                else:
+                  full_name = _NormalizeName(full_name)
 
               sym = models.Symbol(section_name, size, address=address,
-                                  full_name=full_name, object_path=path)
+                                  full_name=full_name, object_path=path,
+                                  flags=flags)
               syms.append(sym)
-          section_end_address = section_address + section_size
-          if section_name != models.SECTION_BSS and (
-              syms[-1].end_address < section_end_address):
-            # Set size=0 so that it will show up as padding.
-            sym = models.Symbol(
-                section_name, 0,
-                address=section_end_address,
-                full_name=(
-                    '** symbol gap %d (end of section)' % symbol_gap_count))
-            syms.append(sym)
           logging.debug('Symbol count for %s: %d', section_name,
                         len(syms) - sym_count_at_start)
       except:
@@ -431,12 +461,10 @@
 # 00000000002010ed 0000000000000071     0                 main
     syms = []
     cur_section = None
-    cur_section_is_useful = None
+    cur_section_is_useful = False
     promoted_name_count = 0
-    # A Level 2 line does not supply |full_name| data (unless '<internal>').
-    # This would be taken from a Level 3 line. |is_partial| indicates that an
-    # eligible Level 3 line should be used to update |syms[-1].full_name|
-    # instead of creating a new symbol.
+    # |is_partial| indicates that an eligible Level 3 line should be used to
+    # update |syms[-1].full_name| instead of creating a new symbol.
     is_partial = False
     # Assembly code can create consecutive Level 3 lines with |size == 0|. These
     # lines can represent
@@ -474,13 +502,12 @@
         # Level 2 data match the "In" column. They specify object paths and
         # section names within objects, or '<internal>:...'.
         if level == 2:
-          # Create a symbol here since there may be no ensuing Level 3 lines.
-          # But if there are, then the symbol can be modified later as sym[-1].
-          syms.append(models.Symbol(cur_section, size, address=address))
           # E.g., 'path.o:(.text._name)' => ['path.o', '(.text._name)'].
           cur_obj, paren_value = tok.split(':')
-          # E.g., '(.text._name)' -> '_name'.
+          # E.g., '(.text.unlikely._name)' -> '_name'.
           mangled_name = paren_value[mangled_start_idx:-1]
+          cur_flags = _FlagsFromMangledName(mangled_name)
+          is_partial = True
           # As of 2017/11 LLD does not distinguish merged strings from other
           # merged data. Feature request is filed under:
           # https://bugs.llvm.org/show_bug.cgi?id=35248
@@ -489,18 +516,24 @@
               # Treat all <internal> sections within .rodata as as string
               # literals. Some may hold numeric constants or other data, but
               # there is currently no way to distinguish them.
-              syms[-1].full_name = '** lld merge strings'
+              mangled_name = '** lld merge strings'
             else:
               # e.g. <internal>:(.text.thunk)
-              syms[-1].full_name = '** ' + mangled_name
+              mangled_name = '** ' + mangled_name
+
+            is_partial = False
             cur_obj = None
           elif cur_obj == 'lto.tmp' or 'thinlto-cache' in cur_obj:
             thin_map[address] = os.path.basename(cur_obj)
             cur_obj = None
-          if cur_obj is not None:
-            syms[-1].object_path = cur_obj
 
-          is_partial = not bool(syms[-1].full_name)
+          # Create a symbol here since there may be no ensuing Level 3 lines.
+          # But if there are, then the symbol can be modified later as sym[-1].
+          sym = models.Symbol(cur_section, size, address=address,
+                              full_name=mangled_name, object_path=cur_obj,
+                              flags=cur_flags)
+          syms.append(sym)
+
           # Level 3 |address| is nested under Level 2, don't add |size|.
           next_usable_address = address
 
@@ -524,16 +557,11 @@
           #   also skips legitimate aliases, but that's desired because nm.py
           #   (downstream) assumes no aliases already exist.
           if span > 0:
-            # Outlined functions have names like OUTLINED_FUNCTION_0, which can
-            # appear 1000+ time, and can cause false aliasing. We treat these as
-            # special cases by designating them as a placeholder symbols and
-            # renaming them to '** outlined function'.
-            if tok.startswith('OUTLINED_FUNCTION_'):
-              tok = '** outlined function'
             stripped_tok = demangle.StripLlvmPromotedGlobalNames(tok)
             if len(tok) != len(stripped_tok):
               promoted_name_count += 1
               tok = stripped_tok
+            tok = _NormalizeName(tok)
 
             # Handle special case where a partial symbol consumes bytes before
             # the first Level 3 symbol.
@@ -552,9 +580,10 @@
             elif address >= next_usable_address:
               # Prefer |size|, and only fall back to |span| if |size == 0|.
               size_to_use = size if size > 0 else span
-              syms.append(
-                  models.Symbol(
-                      cur_section, size_to_use, address=address, full_name=tok))
+              sym = models.Symbol(cur_section, size_to_use, address=address,
+                                  full_name=tok, flags=cur_flags)
+              syms.append(sym)
+
               # Suppress symbols with overlapping |address|. This eliminates
               # labels from assembly sources.
               next_usable_address = address + size_to_use
@@ -671,31 +700,40 @@
       if thin_obj:
         thin_obj_to_object_paths[thin_obj].add(symbol.object_path)
 
-  # For each ".L.ref.tmp" symbol without |object_path|, translate |address| ->
-  # |thin_obj| -> |object_paths|. If unique, then assign to symbol. Stats are
-  # kept, keyed on |len(object_paths)|.
-  logging.info('Assigning object paths to .L.ref.tmp symbols.')
+  # For each symbol without |object_path|, translate |address| -> |thin_obj| ->
+  # |object_paths|. If unique, then assign to symbol. Stats are kept, keyed on
+  # |len(object_paths)|.
+  # Example symbols this happens with: ".L.ref.tmp", "** outlined function".
+  logging.info('Assigning object paths to using ThinLTO paths.')
   ref_tmp_popu = [0] * 3
   ref_tmp_pss = [0] * 3
   for symbol in raw_symbols:
-    if symbol.full_name.startswith('.L.ref.tmp') and not symbol.object_path:
-      thin_obj = thin_map[symbol.address]
-      count = 0
-      if thin_obj in thin_obj_to_object_paths:
-        object_paths = thin_obj_to_object_paths.get(thin_obj, set())
-        count = min(len(object_paths), 2)  # 2+ maps to 2.
-        if count == 1:
-          for object_path in object_paths:  # Get the unique element.
-            symbol.object_path = object_path
-      ref_tmp_popu[count] += 1
-      ref_tmp_pss[count] += symbol.pss
+    if not symbol.object_path:
+      thin_obj = thin_map.get(symbol.address)
+      # Ignore non-native symbols.
+      if thin_obj:
+        count = 0
+        object_paths = thin_obj_to_object_paths.get(thin_obj)
+        if object_paths is not None:
+          count = min(len(object_paths), 2)  # 2+ maps to 2.
+          # We could create path aliases when count > 1, but it wouldn't
+          # necessarily be correct. That occurs when *another* symbol from the
+          # same .o file contains a path alias, but not necessarily this symbol.
+          if count == 1:
+            symbol.object_path = next(iter(object_paths))
+        ref_tmp_popu[count] += 1
+        ref_tmp_pss[count] += symbol.pss
 
-  logging.info('Object path deduction results for .L.ref.tmp symbols:')
-  logging.info('  No match: %d symbols with total PSS = %g', ref_tmp_popu[0],
+  # As of Mar 2019:
+  #   No match: 2 symbols with total PSS = 20
+  #   Assigned (1 object path): 1098 symbols with total PSS = 55454
+  #   Ambiguous (2+ object paths): 2315 symbols with total PSS = 41941
+  logging.info('Object path deduction results for pathless symbols:')
+  logging.info('  No match: %d symbols with total PSS = %d', ref_tmp_popu[0],
                ref_tmp_pss[0])
-  logging.info('  Assigned (1 object path): %d symbols with total PSS = %g',
+  logging.info('  Assigned (1 object path): %d symbols with total PSS = %d',
                ref_tmp_popu[1], ref_tmp_pss[1])
-  logging.info('  Ambiguous (2+ object paths): %d symbols with total PSS = %g',
+  logging.info('  Ambiguous (2+ object paths): %d symbols with total PSS = %d',
                ref_tmp_popu[2], ref_tmp_pss[2])
 
 
diff --git a/tools/binary_size/libsupersize/models.py b/tools/binary_size/libsupersize/models.py
index 0b815598..519405f0 100644
--- a/tools/binary_size/libsupersize/models.py
+++ b/tools/binary_size/libsupersize/models.py
@@ -645,8 +645,10 @@
 
   @property
   def flags(self):
-    first = self._symbols[0].flags if self else 0
-    return first if all(s.flags == first for s in self._symbols) else 0
+    ret = 0
+    for s in self._symbols:
+      ret |= s.flags
+    return ret
 
   @property
   def object_path(self):
@@ -803,6 +805,9 @@
   def WhereIsTemplate(self):
     return self.Filter(lambda s: s.template_name is not s.name)
 
+  def WhereHasFlag(self, flag):
+    return self.Filter(lambda s: s.flags & flag)
+
   def WhereHasComponent(self):
     return self.Filter(lambda s: s.component)
 
diff --git a/tools/binary_size/libsupersize/testdata/Archive.golden b/tools/binary_size/libsupersize/testdata/Archive.golden
index f8164fd..dc5f4f1a 100644
--- a/tools/binary_size/libsupersize/testdata/Archive.golden
+++ b/tools/binary_size/libsupersize/testdata/Archive.golden
@@ -1,43 +1,58 @@
-Section .text: has 100.0% of 35900712 bytes accounted for from 17 symbols. 0 bytes are unaccounted for.
-* 0 have source paths assigned (0.0%)
-* Padding accounts for 48 bytes (0.0%)
-* 5 placeholders (symbols that start with **) account for 35830760 bytes (99.8%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
-Section .rodata: has 100.0% of 5927652 bytes accounted for from 10 symbols. 0 bytes are unaccounted for.
-* 0 have source paths assigned (0.0%)
-* Padding accounts for 675996 bytes (11.4%)
-* 5 placeholders (symbols that start with **) account for 5251524 bytes (88.6%)
-* Contains 0 string literals. Total size=0, padding=0
-* Contains 0 aliases
-* 0 symbols have shared ownership
-Section .data.rel.ro: has 100.0% of 1065224 bytes accounted for from 4 symbols. 0 bytes are unaccounted for.
-* 0 have source paths assigned (0.0%)
+Section .text: has 0.2% of 83792 bytes accounted for from 16 symbols. 35816920 bytes are unaccounted for.
+* Padding accounts for 13808 bytes (16.5%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 4 placeholders exist (symbols that start with **). Accounts for 13840 bytes (16.5%).
+* 0 symbols have shared ownership.
+* 1 symbols are marked as "hot". Accounts for 12 bytes (0.0%).
+* 1 symbols are marked as "unlikely". Accounts for 69124 bytes (82.5%).
+* 4 symbols are marked as "startup". Accounts for 128 bytes (0.2%).
+* 2 symbols are clones. Accounts for 106 bytes (0.1%).
+Section .rodata: has 44.6% of 2641540 bytes accounted for from 9 symbols. 3286112 bytes are unaccounted for.
+* Padding accounts for 2637935 bytes (99.9%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 4 placeholders exist (symbols that start with **). Accounts for 1965412 bytes (74.4%).
+* 0 string literals exist. Accounts for 0 bytes (0.0%) padding is 0 bytes.
+* 0 symbols have shared ownership.
+Section .data.rel.ro: has 0.0% of 92 bytes accounted for from 3 symbols. 1065132 bytes are unaccounted for.
 * Padding accounts for 0 bytes (0.0%)
-* 1 placeholders (symbols that start with **) account for 1065132 bytes (100.0%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
-Section .data: has 100.0% of 101768 bytes accounted for from 6 symbols. 0 bytes are unaccounted for.
-* 0 have source paths assigned (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
+Section .data: has 0.2% of 168 bytes accounted for from 5 symbols. 101600 bytes are unaccounted for.
 * Padding accounts for 0 bytes (0.0%)
-* 1 placeholders (symbols that start with **) account for 101600 bytes (99.8%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
 Section .bss: has 40.3% of 524520 bytes accounted for from 6 symbols. 775936 bytes are unaccounted for.
-* 0 have source paths assigned (0.0%)
 * Padding accounts for 196 bytes (0.0%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
+Section .dex: 0 bytes from 0 symbols.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
+Section .dex.method: 0 bytes from 0 symbols.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
+Section .pak.translations: 0 bytes from 0 symbols.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
+Section .pak.nontranslated: 0 bytes from 0 symbols.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
+Section .other: 0 bytes from 0 symbols.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
 .data@2de7000(size_without_padding=4,padding=0,full_name=google::protobuf::internal::pLinuxKernelCmpxchg,object_path=base/base/page_allocator.o,source_path=,flags={},num_aliases=1,component=)
 .data@2de7004(size_without_padding=4,padding=0,full_name=google::protobuf::internal::pLinuxKernelMemoryBarrier,object_path=third_party/WebKit.a/sub/ContiguousContainer.o,source_path=,flags={},num_aliases=1,component=)
 .data@2de7008(size_without_padding=152,padding=0,full_name=base::android::kBaseRegisteredMethods,object_path=third_party/WebKit.a/sub/ContiguousContainer.o,source_path=,flags={rel},num_aliases=1,component=)
 .data@2de70a0(size_without_padding=4,padding=0,full_name=base::android::g_renderer_histogram_code,object_path=third_party/WebKit.a/sub/ContiguousContainer.o,source_path=,flags={anon},num_aliases=1,component=)
 .data@2de70a4(size_without_padding=4,padding=0,full_name=base::android::g_library_version_number,object_path=third_party/WebKit.a/sub/ContiguousContainer.o,source_path=,flags={anon,rel.loc},num_aliases=1,component=)
-.data@2dffd88(size_without_padding=0,padding=101600,full_name=** symbol gap 0 (end of section),object_path=,source_path=,flags={},num_aliases=1,component=)
 .data.rel.ro@2cd8500(size_without_padding=56,padding=0,full_name=ChromeMainDelegateAndroid [vtable],object_path=third_party/WebKit.a/./../third_party/sub/PaintChunker.o,source_path=,flags={},num_aliases=1,component=)
 .data.rel.ro@2cd8538(size_without_padding=24,padding=0,full_name=mojo::MessageReceiver [vtable],object_path=base/base/page_allocator.o,source_path=,flags={},num_aliases=1,component=)
 .data.rel.ro@2cd8550(size_without_padding=12,padding=0,full_name=kMethodsAnimationFrameTimeHistogram,object_path=base/base/page_allocator.o,source_path=,flags={},num_aliases=1,component=)
-.data.rel.ro@2ddc608(size_without_padding=0,padding=1065132,full_name=** symbol gap 0 (end of section),object_path=,source_path=,flags={},num_aliases=1,component=)
 .data.rel.ro.local@2c176f0(size_without_padding=56,padding=0,full_name=ChromeMainDelegate [vtable],object_path=third_party/icu/icuuc/ucnv_ext.o,source_path=,flags={},num_aliases=1,component=)
 .data.rel.ro.local@2c17728(size_without_padding=24,padding=0,full_name=chrome::mojom::FieldTrialRecorder [vtable],object_path=third_party/icu/icuuc/ucnv_ext.o,source_path=,flags={},num_aliases=1,component=)
 .data.rel.ro.local@2c17740(size_without_padding=789904,padding=0,full_name=chrome::mojom::FieldTrialRecorderProxy [vtable],object_path=third_party/WebKit.a/sub/ContiguousContainer.o,source_path=,flags={},num_aliases=1,component=)
@@ -52,7 +67,6 @@
 .rodata@284e398(size_without_padding=32,padding=0,full_name=chrome::mojom::FilePatcher::Name_,object_path=third_party/WebKit.a/sub/ContiguousContainer.o,source_path=,flags={},num_aliases=1,component=)
 .rodata@28f3450(size_without_padding=48,padding=675992,full_name=kAnimationFrameTimeHistogramClassPath,object_path=third_party/WebKit.a/./../third_party/sub/PaintChunker.o,source_path=,flags={anon},num_aliases=1,component=)
 .rodata@28f3480(size_without_padding=4,padding=0,full_name=blink::CSSValueKeywordsHash::findValueImpl(char const*, unsigned int)::value_word_list,object_path=third_party/WebKit.a/./../third_party/sub/PaintChunker.o,source_path=,flags={anon},num_aliases=1,component=)
-.rodata@2c158e4(size_without_padding=0,padding=3286112,full_name=** symbol gap 1 (end of section),object_path=,source_path=,flags={},num_aliases=1,component=)
 .text@28d900(size_without_padding=16,padding=0,full_name=_GLOBAL__sub_I_page_allocator.cc,object_path=base/base/page_allocator.o,source_path=,flags={startup},num_aliases=1,component=)
 .text@28d910(size_without_padding=56,padding=0,full_name=_GLOBAL__sub_I_bbr_sender.cc,object_path=base/base/page_allocator.o,source_path=,flags={startup},num_aliases=1,component=)
 .text@28d948(size_without_padding=28,padding=0,full_name=_GLOBAL__sub_I_pacing_sender.cc,object_path=base/base/page_allocator.o,source_path=,flags={startup},num_aliases=1,component=)
@@ -69,7 +83,6 @@
 .text@2a1000(size_without_padding=94,padding=0,full_name=blink::PaintChunker::releasePaintChunks(),object_path=third_party/WebKit.a/sub/ContiguousContainer.o,source_path=,flags={anon,clone},num_aliases=1,component=)
 .text@2a2000(size_without_padding=32,padding=4002,full_name=** outlined function,object_path=third_party/WebKit.a/sub/ContiguousContainer.o,source_path=,flags={},num_aliases=1,component=)
 .text@2a2020(size_without_padding=48,padding=0,full_name=** outlined function,object_path=third_party/WebKit.a/sub/ContiguousContainer.o,source_path=,flags={},num_aliases=1,component=)
-.text@24ca628(size_without_padding=0,padding=35816920,full_name=** symbol gap 2 (end of section),object_path=,source_path=,flags={},num_aliases=1,component=)
 .bss@0(size_without_padding=262144,padding=0,full_name=ff_cos_131072,object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_float.o,source_path=,flags={},num_aliases=1,component=)
 .bss@0(size_without_padding=131072,padding=0,full_name=ff_cos_131072_fixed,object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_fixed.o,source_path=,flags={},num_aliases=1,component=)
 .bss@0(size_without_padding=131072,padding=0,full_name=ff_cos_65536,object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_float.o,source_path=,flags={},num_aliases=1,component=)
diff --git a/tools/binary_size/libsupersize/testdata/Archive_Apk.golden b/tools/binary_size/libsupersize/testdata/Archive_Apk.golden
index e80d31eb..b01038a 100644
--- a/tools/binary_size/libsupersize/testdata/Archive_Apk.golden
+++ b/tools/binary_size/libsupersize/testdata/Archive_Apk.golden
@@ -9,67 +9,69 @@
 linker_name=gold
 map_file_name=../../../test.map
 tool_prefix=tools/binary_size/libsupersize/testdata/mock_toolchain/
-Section .text: has 100.0% of 35900712 bytes accounted for from 22 symbols. 0 bytes are unaccounted for.
-* 16 have source paths assigned (72.7%)
-* Padding accounts for 48 bytes (0.0%)
-* 5 placeholders (symbols that start with **) account for 35830760 bytes (99.8%)
-* Contains 8 aliases, mapped to 3 unique addresses (100 bytes saved)
-* 0 symbols have shared ownership
-Section .rodata: has 100.0% of 5927652 bytes accounted for from 12 symbols. 0 bytes are unaccounted for.
-* 8 have source paths assigned (66.7%)
-* Padding accounts for 675996 bytes (11.4%)
-* 4 placeholders (symbols that start with **) account for 5251503 bytes (88.6%)
-* Contains 3 string literals. Total size=21, padding=0
-* Contains 2 aliases, mapped to 1 unique addresses (5 bytes saved)
-* 0 symbols have shared ownership
-Section .data.rel.ro: has 100.0% of 1065224 bytes accounted for from 4 symbols. 0 bytes are unaccounted for.
-* 3 have source paths assigned (75.0%)
+Section .text: has 0.2% of 83792 bytes accounted for from 21 symbols. 35816920 bytes are unaccounted for.
+* Padding accounts for 13808 bytes (16.5%)
+* 16 have source paths. Accounts for 73986 bytes (88.3%).
+* 4 placeholders exist (symbols that start with **). Accounts for 13840 bytes (16.5%).
+* 8 aliases exist, mapped to 3 unique addresses (100 bytes saved)
+* 0 symbols have shared ownership.
+* 1 symbols are marked as "unlikely". Accounts for 69124 bytes (82.5%).
+* 4 symbols are marked as "startup". Accounts for 128 bytes (0.2%).
+* 3 symbols are clones. Accounts for 106 bytes (0.1%).
+* 5 symbols are from generated sources. Accounts for 69660 bytes (83.1%).
+Section .rodata: has 44.6% of 2641540 bytes accounted for from 11 symbols. 3286112 bytes are unaccounted for.
+* Padding accounts for 2637946 bytes (99.9%)
+* 8 have source paths. Accounts for 676149 bytes (25.6%).
+* 3 placeholders exist (symbols that start with **). Accounts for 1965391 bytes (74.4%).
+* 3 string literals exist. Accounts for 21 bytes (0.0%) padding is 0 bytes.
+* 2 aliases exist, mapped to 1 unique addresses (5 bytes saved)
+* 0 symbols have shared ownership.
+* 2 symbols are from generated sources. Accounts for 21 bytes (0.0%).
+Section .data.rel.ro: has 0.0% of 92 bytes accounted for from 3 symbols. 1065132 bytes are unaccounted for.
 * Padding accounts for 0 bytes (0.0%)
-* 1 placeholders (symbols that start with **) account for 1065132 bytes (100.0%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
-Section .data: has 100.0% of 101768 bytes accounted for from 6 symbols. 0 bytes are unaccounted for.
-* 5 have source paths assigned (83.3%)
+* 3 have source paths. Accounts for 92 bytes (100.0%).
+* 0 symbols have shared ownership.
+Section .data: has 0.2% of 168 bytes accounted for from 5 symbols. 101600 bytes are unaccounted for.
 * Padding accounts for 0 bytes (0.0%)
-* 1 placeholders (symbols that start with **) account for 101600 bytes (99.8%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
+* 5 have source paths. Accounts for 168 bytes (100.0%).
+* 0 symbols have shared ownership.
 Section .bss: has 40.3% of 524520 bytes accounted for from 6 symbols. 775936 bytes are unaccounted for.
-* 6 have source paths assigned (100.0%)
 * Padding accounts for 196 bytes (0.0%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
+* 6 have source paths. Accounts for 524520 bytes (100.0%).
+* 0 symbols have shared ownership.
+* 3 symbols are from generated sources. Accounts for 232 bytes (0.0%).
 Section .dex: has 99.7% of 8365003 bytes accounted for from 93 symbols. 23605 bytes are unaccounted for.
-* 83 have source paths assigned (89.2%)
 * Padding accounts for 0 bytes (0.0%)
-* 1 placeholders (symbols that start with **) account for 4616803 bytes (55.2%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
+* 83 have source paths. Accounts for 926 bytes (0.0%).
+* 1 placeholders exist (symbols that start with **). Accounts for 4616803 bytes (55.2%).
+* 0 symbols have shared ownership.
+Section .dex.method: 23605 bytes from 100 symbols.
+* Padding accounts for 0 bytes (0.0%)
+* 90 have source paths. Accounts for 21154 bytes (89.6%).
+* 0 symbols have shared ownership.
 Section .pak.translations: has 99.9% of 6821 bytes accounted for from 208 symbols. 9 bytes are unaccounted for.
-* 3 have source paths assigned (1.4%)
 * Padding accounts for 18 bytes (0.3%)
-* Contains 2 aliases, mapped to 1 unique addresses (9 bytes saved)
-* 0 symbols have shared ownership
+* 3 have source paths. Accounts for 23 bytes (0.3%).
+* 2 aliases exist, mapped to 1 unique addresses (9 bytes saved)
+* 0 symbols have shared ownership.
+* 2 symbols are from generated sources. Accounts for 23 bytes (0.3%).
 Section .pak.nontranslated: has 100.0% of 737 bytes accounted for from 3 symbols. 0 bytes are unaccounted for.
-* 0 have source paths assigned (0.0%)
 * Padding accounts for 18 bytes (2.4%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
 Section .other: has 100.0% of 39228839 bytes accounted for from 5 symbols. 0 bytes are unaccounted for.
-* 3 have source paths assigned (60.0%)
 * Padding accounts for 33984935 bytes (86.6%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
+* 3 have source paths. Accounts for 5243904 bytes (13.4%).
+* 0 symbols have shared ownership.
+* 1 symbols are from generated sources. Accounts for 4194304 bytes (10.7%).
 .data@2de7000(size_without_padding=4,padding=0,full_name=google::protobuf::internal::pLinuxKernelCmpxchg,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={},num_aliases=1,component=Blink>Internal)
 .data@2de7004(size_without_padding=4,padding=0,full_name=google::protobuf::internal::pLinuxKernelMemoryBarrier,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={},num_aliases=1,component=UI>Browser)
 .data@2de7008(size_without_padding=152,padding=0,full_name=base::android::kBaseRegisteredMethods,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={rel},num_aliases=1,component=UI>Browser)
 .data@2de70a0(size_without_padding=4,padding=0,full_name=base::android::g_renderer_histogram_code,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={anon},num_aliases=1,component=UI>Browser)
 .data@2de70a4(size_without_padding=4,padding=0,full_name=base::android::g_library_version_number,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={anon,rel.loc},num_aliases=1,component=UI>Browser)
-.data@2dffd88(size_without_padding=0,padding=101600,full_name=** symbol gap 0 (end of section),object_path=,source_path=,flags={},num_aliases=1,component=)
 .data.rel.ro@2cd8500(size_without_padding=56,padding=0,full_name=ChromeMainDelegateAndroid [vtable],object_path=third_party/sub/PaintChunker.o,source_path=third_party/paint.cc,flags={},num_aliases=1,component=Internal>Android)
 .data.rel.ro@2cd8538(size_without_padding=24,padding=0,full_name=mojo::MessageReceiver [vtable],object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={},num_aliases=1,component=Blink>Internal)
 .data.rel.ro@2cd8550(size_without_padding=12,padding=0,full_name=kMethodsAnimationFrameTimeHistogram,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={},num_aliases=1,component=Blink>Internal)
-.data.rel.ro@2ddc608(size_without_padding=0,padding=1065132,full_name=** symbol gap 0 (end of section),object_path=,source_path=,flags={},num_aliases=1,component=)
 .data.rel.ro.local@2c176f0(size_without_padding=56,padding=0,full_name=ChromeMainDelegate [vtable],object_path=third_party/icu/icuuc/ucnv_ext.o,source_path=third_party/icu/ucnv_ext.c,flags={gen},num_aliases=1,component=Internal>Android)
 .data.rel.ro.local@2c17728(size_without_padding=24,padding=0,full_name=chrome::mojom::FieldTrialRecorder [vtable],object_path=third_party/icu/icuuc/ucnv_ext.o,source_path=third_party/icu/ucnv_ext.c,flags={gen},num_aliases=1,component=Internal>Android)
 .data.rel.ro.local@2c17740(size_without_padding=789904,padding=0,full_name=chrome::mojom::FieldTrialRecorderProxy [vtable],object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={},num_aliases=1,component=UI>Browser)
@@ -284,7 +286,6 @@
 .rodata@284e398(size_without_padding=32,padding=0,full_name=chrome::mojom::FilePatcher::Name_,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={},num_aliases=1,component=UI>Browser)
 .rodata@28f3450(size_without_padding=48,padding=675992,full_name=kAnimationFrameTimeHistogramClassPath,object_path=third_party/sub/PaintChunker.o,source_path=third_party/paint.cc,flags={anon},num_aliases=1,component=Internal>Android)
 .rodata@28f3480(size_without_padding=4,padding=0,full_name=blink::CSSValueKeywordsHash::findValueImpl(char const*, unsigned int)::value_word_list,object_path=third_party/sub/PaintChunker.o,source_path=third_party/paint.cc,flags={anon},num_aliases=1,component=Internal>Android)
-.rodata@2c158e4(size_without_padding=0,padding=3286112,full_name=** symbol gap 1 (end of section),object_path=,source_path=,flags={},num_aliases=1,component=)
 .text@28d900(size_without_padding=16,padding=0,full_name=_GLOBAL__sub_I_page_allocator.cc,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={startup},num_aliases=1,component=Blink>Internal)
 .text@28d910(size_without_padding=56,padding=0,full_name=_GLOBAL__sub_I_bbr_sender.cc,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={startup},num_aliases=1,component=Blink>Internal)
 .text@28d948(size_without_padding=28,padding=0,full_name=_GLOBAL__sub_I_pacing_sender.cc,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={startup},num_aliases=1,component=Blink>Internal)
@@ -306,7 +307,6 @@
 .text@2a2000(size_without_padding=32,padding=4002,full_name=** outlined function,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={},num_aliases=1,component=UI>Browser)
 .text@2a2020(size_without_padding=48,padding=0,full_name=** outlined function * 2,object_path=,source_path=,flags={},num_aliases=2,component=)
 .text@2a2020(size_without_padding=48,padding=0,full_name=aliasedWithOutlinedFunction(),object_path=,source_path=,flags={},num_aliases=2,component=)
-.text@24ca628(size_without_padding=0,padding=35816920,full_name=** symbol gap 2 (end of section),object_path=,source_path=,flags={},num_aliases=1,component=)
 .bss@0(size_without_padding=262144,padding=0,full_name=ff_cos_131072,object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_float.o,source_path=third_party/fft_float.cc,flags={},num_aliases=1,component=Internal>Android)
 .bss@0(size_without_padding=131072,padding=0,full_name=ff_cos_131072_fixed,object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_fixed.o,source_path=third_party/fft_fixed.cc,flags={},num_aliases=1,component=Internal>Android)
 .bss@0(size_without_padding=131072,padding=0,full_name=ff_cos_65536,object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_float.o,source_path=third_party/fft_float.cc,flags={},num_aliases=1,component=Internal>Android)
diff --git a/tools/binary_size/libsupersize/testdata/Archive_Elf.golden b/tools/binary_size/libsupersize/testdata/Archive_Elf.golden
index 22dea2fc..2a1a4979 100644
--- a/tools/binary_size/libsupersize/testdata/Archive_Elf.golden
+++ b/tools/binary_size/libsupersize/testdata/Archive_Elf.golden
@@ -7,51 +7,65 @@
 linker_name=gold
 map_file_name=../../../test.map
 tool_prefix=tools/binary_size/libsupersize/testdata/mock_toolchain/
-Section .text: has 100.0% of 35900712 bytes accounted for from 22 symbols. 0 bytes are unaccounted for.
-* 16 have source paths assigned (72.7%)
-* Padding accounts for 48 bytes (0.0%)
-* 5 placeholders (symbols that start with **) account for 35830760 bytes (99.8%)
-* Contains 8 aliases, mapped to 3 unique addresses (100 bytes saved)
-* 0 symbols have shared ownership
-Section .rodata: has 100.0% of 5927652 bytes accounted for from 12 symbols. 0 bytes are unaccounted for.
-* 8 have source paths assigned (66.7%)
-* Padding accounts for 675996 bytes (11.4%)
-* 4 placeholders (symbols that start with **) account for 5251503 bytes (88.6%)
-* Contains 3 string literals. Total size=21, padding=0
-* Contains 2 aliases, mapped to 1 unique addresses (5 bytes saved)
-* 0 symbols have shared ownership
-Section .data.rel.ro: has 100.0% of 1065224 bytes accounted for from 4 symbols. 0 bytes are unaccounted for.
-* 3 have source paths assigned (75.0%)
+Section .text: has 0.2% of 83792 bytes accounted for from 21 symbols. 35816920 bytes are unaccounted for.
+* Padding accounts for 13808 bytes (16.5%)
+* 16 have source paths. Accounts for 73986 bytes (88.3%).
+* 4 placeholders exist (symbols that start with **). Accounts for 13840 bytes (16.5%).
+* 8 aliases exist, mapped to 3 unique addresses (100 bytes saved)
+* 0 symbols have shared ownership.
+* 1 symbols are marked as "unlikely". Accounts for 69124 bytes (82.5%).
+* 4 symbols are marked as "startup". Accounts for 128 bytes (0.2%).
+* 3 symbols are clones. Accounts for 106 bytes (0.1%).
+* 5 symbols are from generated sources. Accounts for 69660 bytes (83.1%).
+Section .rodata: has 44.6% of 2641540 bytes accounted for from 11 symbols. 3286112 bytes are unaccounted for.
+* Padding accounts for 2637946 bytes (99.9%)
+* 8 have source paths. Accounts for 676149 bytes (25.6%).
+* 3 placeholders exist (symbols that start with **). Accounts for 1965391 bytes (74.4%).
+* 3 string literals exist. Accounts for 21 bytes (0.0%) padding is 0 bytes.
+* 2 aliases exist, mapped to 1 unique addresses (5 bytes saved)
+* 0 symbols have shared ownership.
+* 2 symbols are from generated sources. Accounts for 21 bytes (0.0%).
+Section .data.rel.ro: has 0.0% of 92 bytes accounted for from 3 symbols. 1065132 bytes are unaccounted for.
 * Padding accounts for 0 bytes (0.0%)
-* 1 placeholders (symbols that start with **) account for 1065132 bytes (100.0%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
-Section .data: has 100.0% of 101768 bytes accounted for from 6 symbols. 0 bytes are unaccounted for.
-* 5 have source paths assigned (83.3%)
+* 3 have source paths. Accounts for 92 bytes (100.0%).
+* 0 symbols have shared ownership.
+Section .data: has 0.2% of 168 bytes accounted for from 5 symbols. 101600 bytes are unaccounted for.
 * Padding accounts for 0 bytes (0.0%)
-* 1 placeholders (symbols that start with **) account for 101600 bytes (99.8%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
+* 5 have source paths. Accounts for 168 bytes (100.0%).
+* 0 symbols have shared ownership.
 Section .bss: has 40.3% of 524520 bytes accounted for from 6 symbols. 775936 bytes are unaccounted for.
-* 6 have source paths assigned (100.0%)
 * Padding accounts for 196 bytes (0.0%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
+* 6 have source paths. Accounts for 524520 bytes (100.0%).
+* 0 symbols have shared ownership.
+* 3 symbols are from generated sources. Accounts for 232 bytes (0.0%).
+Section .dex: 0 bytes from 0 symbols.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
+Section .dex.method: 0 bytes from 0 symbols.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
+Section .pak.translations: 0 bytes from 0 symbols.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
+Section .pak.nontranslated: 0 bytes from 0 symbols.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
 Section .other: has 100.0% of 33984171 bytes accounted for from 1 symbols. 0 bytes are unaccounted for.
-* 0 have source paths assigned (0.0%)
 * Padding accounts for 33984171 bytes (100.0%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
 .data@2de7000(size_without_padding=4,padding=0,full_name=google::protobuf::internal::pLinuxKernelCmpxchg,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={},num_aliases=1,component=Blink>Internal)
 .data@2de7004(size_without_padding=4,padding=0,full_name=google::protobuf::internal::pLinuxKernelMemoryBarrier,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={},num_aliases=1,component=UI>Browser)
 .data@2de7008(size_without_padding=152,padding=0,full_name=base::android::kBaseRegisteredMethods,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={rel},num_aliases=1,component=UI>Browser)
 .data@2de70a0(size_without_padding=4,padding=0,full_name=base::android::g_renderer_histogram_code,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={anon},num_aliases=1,component=UI>Browser)
 .data@2de70a4(size_without_padding=4,padding=0,full_name=base::android::g_library_version_number,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={anon,rel.loc},num_aliases=1,component=UI>Browser)
-.data@2dffd88(size_without_padding=0,padding=101600,full_name=** symbol gap 0 (end of section),object_path=,source_path=,flags={},num_aliases=1,component=)
 .data.rel.ro@2cd8500(size_without_padding=56,padding=0,full_name=ChromeMainDelegateAndroid [vtable],object_path=third_party/sub/PaintChunker.o,source_path=third_party/paint.cc,flags={},num_aliases=1,component=Internal>Android)
 .data.rel.ro@2cd8538(size_without_padding=24,padding=0,full_name=mojo::MessageReceiver [vtable],object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={},num_aliases=1,component=Blink>Internal)
 .data.rel.ro@2cd8550(size_without_padding=12,padding=0,full_name=kMethodsAnimationFrameTimeHistogram,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={},num_aliases=1,component=Blink>Internal)
-.data.rel.ro@2ddc608(size_without_padding=0,padding=1065132,full_name=** symbol gap 0 (end of section),object_path=,source_path=,flags={},num_aliases=1,component=)
 .data.rel.ro.local@2c176f0(size_without_padding=56,padding=0,full_name=ChromeMainDelegate [vtable],object_path=third_party/icu/icuuc/ucnv_ext.o,source_path=third_party/icu/ucnv_ext.c,flags={gen},num_aliases=1,component=Internal>Android)
 .data.rel.ro.local@2c17728(size_without_padding=24,padding=0,full_name=chrome::mojom::FieldTrialRecorder [vtable],object_path=third_party/icu/icuuc/ucnv_ext.o,source_path=third_party/icu/ucnv_ext.c,flags={gen},num_aliases=1,component=Internal>Android)
 .data.rel.ro.local@2c17740(size_without_padding=789904,padding=0,full_name=chrome::mojom::FieldTrialRecorderProxy [vtable],object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={},num_aliases=1,component=UI>Browser)
@@ -69,7 +83,6 @@
 .rodata@284e398(size_without_padding=32,padding=0,full_name=chrome::mojom::FilePatcher::Name_,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={},num_aliases=1,component=UI>Browser)
 .rodata@28f3450(size_without_padding=48,padding=675992,full_name=kAnimationFrameTimeHistogramClassPath,object_path=third_party/sub/PaintChunker.o,source_path=third_party/paint.cc,flags={anon},num_aliases=1,component=Internal>Android)
 .rodata@28f3480(size_without_padding=4,padding=0,full_name=blink::CSSValueKeywordsHash::findValueImpl(char const*, unsigned int)::value_word_list,object_path=third_party/sub/PaintChunker.o,source_path=third_party/paint.cc,flags={anon},num_aliases=1,component=Internal>Android)
-.rodata@2c158e4(size_without_padding=0,padding=3286112,full_name=** symbol gap 1 (end of section),object_path=,source_path=,flags={},num_aliases=1,component=)
 .text@28d900(size_without_padding=16,padding=0,full_name=_GLOBAL__sub_I_page_allocator.cc,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={startup},num_aliases=1,component=Blink>Internal)
 .text@28d910(size_without_padding=56,padding=0,full_name=_GLOBAL__sub_I_bbr_sender.cc,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={startup},num_aliases=1,component=Blink>Internal)
 .text@28d948(size_without_padding=28,padding=0,full_name=_GLOBAL__sub_I_pacing_sender.cc,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={startup},num_aliases=1,component=Blink>Internal)
@@ -91,7 +104,6 @@
 .text@2a2000(size_without_padding=32,padding=4002,full_name=** outlined function,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={},num_aliases=1,component=UI>Browser)
 .text@2a2020(size_without_padding=48,padding=0,full_name=** outlined function * 2,object_path=,source_path=,flags={},num_aliases=2,component=)
 .text@2a2020(size_without_padding=48,padding=0,full_name=aliasedWithOutlinedFunction(),object_path=,source_path=,flags={},num_aliases=2,component=)
-.text@24ca628(size_without_padding=0,padding=35816920,full_name=** symbol gap 2 (end of section),object_path=,source_path=,flags={},num_aliases=1,component=)
 .bss@0(size_without_padding=262144,padding=0,full_name=ff_cos_131072,object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_float.o,source_path=third_party/fft_float.cc,flags={},num_aliases=1,component=Internal>Android)
 .bss@0(size_without_padding=131072,padding=0,full_name=ff_cos_131072_fixed,object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_fixed.o,source_path=third_party/fft_fixed.cc,flags={},num_aliases=1,component=Internal>Android)
 .bss@0(size_without_padding=131072,padding=0,full_name=ff_cos_65536,object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_float.o,source_path=third_party/fft_float.cc,flags={},num_aliases=1,component=Internal>Android)
diff --git a/tools/binary_size/libsupersize/testdata/Archive_MinimalApks.golden b/tools/binary_size/libsupersize/testdata/Archive_MinimalApks.golden
index 0850e942..bf46882 100644
--- a/tools/binary_size/libsupersize/testdata/Archive_MinimalApks.golden
+++ b/tools/binary_size/libsupersize/testdata/Archive_MinimalApks.golden
@@ -10,67 +10,69 @@
 linker_name=gold
 map_file_name=../../../test.map
 tool_prefix=tools/binary_size/libsupersize/testdata/mock_toolchain/
-Section .text: has 100.0% of 35900712 bytes accounted for from 22 symbols. 0 bytes are unaccounted for.
-* 16 have source paths assigned (72.7%)
-* Padding accounts for 48 bytes (0.0%)
-* 5 placeholders (symbols that start with **) account for 35830760 bytes (99.8%)
-* Contains 8 aliases, mapped to 3 unique addresses (100 bytes saved)
-* 0 symbols have shared ownership
-Section .rodata: has 100.0% of 5927652 bytes accounted for from 12 symbols. 0 bytes are unaccounted for.
-* 8 have source paths assigned (66.7%)
-* Padding accounts for 675996 bytes (11.4%)
-* 4 placeholders (symbols that start with **) account for 5251503 bytes (88.6%)
-* Contains 3 string literals. Total size=21, padding=0
-* Contains 2 aliases, mapped to 1 unique addresses (5 bytes saved)
-* 0 symbols have shared ownership
-Section .data.rel.ro: has 100.0% of 1065224 bytes accounted for from 4 symbols. 0 bytes are unaccounted for.
-* 3 have source paths assigned (75.0%)
+Section .text: has 0.2% of 83792 bytes accounted for from 21 symbols. 35816920 bytes are unaccounted for.
+* Padding accounts for 13808 bytes (16.5%)
+* 16 have source paths. Accounts for 73986 bytes (88.3%).
+* 4 placeholders exist (symbols that start with **). Accounts for 13840 bytes (16.5%).
+* 8 aliases exist, mapped to 3 unique addresses (100 bytes saved)
+* 0 symbols have shared ownership.
+* 1 symbols are marked as "unlikely". Accounts for 69124 bytes (82.5%).
+* 4 symbols are marked as "startup". Accounts for 128 bytes (0.2%).
+* 3 symbols are clones. Accounts for 106 bytes (0.1%).
+* 5 symbols are from generated sources. Accounts for 69660 bytes (83.1%).
+Section .rodata: has 44.6% of 2641540 bytes accounted for from 11 symbols. 3286112 bytes are unaccounted for.
+* Padding accounts for 2637946 bytes (99.9%)
+* 8 have source paths. Accounts for 676149 bytes (25.6%).
+* 3 placeholders exist (symbols that start with **). Accounts for 1965391 bytes (74.4%).
+* 3 string literals exist. Accounts for 21 bytes (0.0%) padding is 0 bytes.
+* 2 aliases exist, mapped to 1 unique addresses (5 bytes saved)
+* 0 symbols have shared ownership.
+* 2 symbols are from generated sources. Accounts for 21 bytes (0.0%).
+Section .data.rel.ro: has 0.0% of 92 bytes accounted for from 3 symbols. 1065132 bytes are unaccounted for.
 * Padding accounts for 0 bytes (0.0%)
-* 1 placeholders (symbols that start with **) account for 1065132 bytes (100.0%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
-Section .data: has 100.0% of 101768 bytes accounted for from 6 symbols. 0 bytes are unaccounted for.
-* 5 have source paths assigned (83.3%)
+* 3 have source paths. Accounts for 92 bytes (100.0%).
+* 0 symbols have shared ownership.
+Section .data: has 0.2% of 168 bytes accounted for from 5 symbols. 101600 bytes are unaccounted for.
 * Padding accounts for 0 bytes (0.0%)
-* 1 placeholders (symbols that start with **) account for 101600 bytes (99.8%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
+* 5 have source paths. Accounts for 168 bytes (100.0%).
+* 0 symbols have shared ownership.
 Section .bss: has 40.3% of 524520 bytes accounted for from 6 symbols. 775936 bytes are unaccounted for.
-* 6 have source paths assigned (100.0%)
 * Padding accounts for 196 bytes (0.0%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
+* 6 have source paths. Accounts for 524520 bytes (100.0%).
+* 0 symbols have shared ownership.
+* 3 symbols are from generated sources. Accounts for 232 bytes (0.0%).
 Section .dex: has 99.7% of 8365003 bytes accounted for from 93 symbols. 23605 bytes are unaccounted for.
-* 83 have source paths assigned (89.2%)
 * Padding accounts for 0 bytes (0.0%)
-* 1 placeholders (symbols that start with **) account for 4616803 bytes (55.2%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
+* 83 have source paths. Accounts for 926 bytes (0.0%).
+* 1 placeholders exist (symbols that start with **). Accounts for 4616803 bytes (55.2%).
+* 0 symbols have shared ownership.
+Section .dex.method: 23605 bytes from 100 symbols.
+* Padding accounts for 0 bytes (0.0%)
+* 90 have source paths. Accounts for 21154 bytes (89.6%).
+* 0 symbols have shared ownership.
 Section .pak.translations: has 99.9% of 6821 bytes accounted for from 208 symbols. 9 bytes are unaccounted for.
-* 3 have source paths assigned (1.4%)
 * Padding accounts for 18 bytes (0.3%)
-* Contains 2 aliases, mapped to 1 unique addresses (9 bytes saved)
-* 0 symbols have shared ownership
+* 3 have source paths. Accounts for 23 bytes (0.3%).
+* 2 aliases exist, mapped to 1 unique addresses (9 bytes saved)
+* 0 symbols have shared ownership.
+* 2 symbols are from generated sources. Accounts for 23 bytes (0.3%).
 Section .pak.nontranslated: has 100.0% of 737 bytes accounted for from 3 symbols. 0 bytes are unaccounted for.
-* 0 have source paths assigned (0.0%)
 * Padding accounts for 18 bytes (2.4%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
 Section .other: has 100.0% of 39228839 bytes accounted for from 5 symbols. 0 bytes are unaccounted for.
-* 3 have source paths assigned (60.0%)
 * Padding accounts for 33984935 bytes (86.6%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
+* 3 have source paths. Accounts for 5243904 bytes (13.4%).
+* 0 symbols have shared ownership.
+* 1 symbols are from generated sources. Accounts for 4194304 bytes (10.7%).
 .data@2de7000(size_without_padding=4,padding=0,full_name=google::protobuf::internal::pLinuxKernelCmpxchg,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={},num_aliases=1,component=Blink>Internal)
 .data@2de7004(size_without_padding=4,padding=0,full_name=google::protobuf::internal::pLinuxKernelMemoryBarrier,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={},num_aliases=1,component=UI>Browser)
 .data@2de7008(size_without_padding=152,padding=0,full_name=base::android::kBaseRegisteredMethods,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={rel},num_aliases=1,component=UI>Browser)
 .data@2de70a0(size_without_padding=4,padding=0,full_name=base::android::g_renderer_histogram_code,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={anon},num_aliases=1,component=UI>Browser)
 .data@2de70a4(size_without_padding=4,padding=0,full_name=base::android::g_library_version_number,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={anon,rel.loc},num_aliases=1,component=UI>Browser)
-.data@2dffd88(size_without_padding=0,padding=101600,full_name=** symbol gap 0 (end of section),object_path=,source_path=,flags={},num_aliases=1,component=)
 .data.rel.ro@2cd8500(size_without_padding=56,padding=0,full_name=ChromeMainDelegateAndroid [vtable],object_path=third_party/sub/PaintChunker.o,source_path=third_party/paint.cc,flags={},num_aliases=1,component=Internal>Android)
 .data.rel.ro@2cd8538(size_without_padding=24,padding=0,full_name=mojo::MessageReceiver [vtable],object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={},num_aliases=1,component=Blink>Internal)
 .data.rel.ro@2cd8550(size_without_padding=12,padding=0,full_name=kMethodsAnimationFrameTimeHistogram,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={},num_aliases=1,component=Blink>Internal)
-.data.rel.ro@2ddc608(size_without_padding=0,padding=1065132,full_name=** symbol gap 0 (end of section),object_path=,source_path=,flags={},num_aliases=1,component=)
 .data.rel.ro.local@2c176f0(size_without_padding=56,padding=0,full_name=ChromeMainDelegate [vtable],object_path=third_party/icu/icuuc/ucnv_ext.o,source_path=third_party/icu/ucnv_ext.c,flags={gen},num_aliases=1,component=Internal>Android)
 .data.rel.ro.local@2c17728(size_without_padding=24,padding=0,full_name=chrome::mojom::FieldTrialRecorder [vtable],object_path=third_party/icu/icuuc/ucnv_ext.o,source_path=third_party/icu/ucnv_ext.c,flags={gen},num_aliases=1,component=Internal>Android)
 .data.rel.ro.local@2c17740(size_without_padding=789904,padding=0,full_name=chrome::mojom::FieldTrialRecorderProxy [vtable],object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={},num_aliases=1,component=UI>Browser)
@@ -285,7 +287,6 @@
 .rodata@284e398(size_without_padding=32,padding=0,full_name=chrome::mojom::FilePatcher::Name_,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={},num_aliases=1,component=UI>Browser)
 .rodata@28f3450(size_without_padding=48,padding=675992,full_name=kAnimationFrameTimeHistogramClassPath,object_path=third_party/sub/PaintChunker.o,source_path=third_party/paint.cc,flags={anon},num_aliases=1,component=Internal>Android)
 .rodata@28f3480(size_without_padding=4,padding=0,full_name=blink::CSSValueKeywordsHash::findValueImpl(char const*, unsigned int)::value_word_list,object_path=third_party/sub/PaintChunker.o,source_path=third_party/paint.cc,flags={anon},num_aliases=1,component=Internal>Android)
-.rodata@2c158e4(size_without_padding=0,padding=3286112,full_name=** symbol gap 1 (end of section),object_path=,source_path=,flags={},num_aliases=1,component=)
 .text@28d900(size_without_padding=16,padding=0,full_name=_GLOBAL__sub_I_page_allocator.cc,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={startup},num_aliases=1,component=Blink>Internal)
 .text@28d910(size_without_padding=56,padding=0,full_name=_GLOBAL__sub_I_bbr_sender.cc,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={startup},num_aliases=1,component=Blink>Internal)
 .text@28d948(size_without_padding=28,padding=0,full_name=_GLOBAL__sub_I_pacing_sender.cc,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={startup},num_aliases=1,component=Blink>Internal)
@@ -307,7 +308,6 @@
 .text@2a2000(size_without_padding=32,padding=4002,full_name=** outlined function,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={},num_aliases=1,component=UI>Browser)
 .text@2a2020(size_without_padding=48,padding=0,full_name=** outlined function * 2,object_path=,source_path=,flags={},num_aliases=2,component=)
 .text@2a2020(size_without_padding=48,padding=0,full_name=aliasedWithOutlinedFunction(),object_path=,source_path=,flags={},num_aliases=2,component=)
-.text@24ca628(size_without_padding=0,padding=35816920,full_name=** symbol gap 2 (end of section),object_path=,source_path=,flags={},num_aliases=1,component=)
 .bss@0(size_without_padding=262144,padding=0,full_name=ff_cos_131072,object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_float.o,source_path=third_party/fft_float.cc,flags={},num_aliases=1,component=Internal>Android)
 .bss@0(size_without_padding=131072,padding=0,full_name=ff_cos_131072_fixed,object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_fixed.o,source_path=third_party/fft_fixed.cc,flags={},num_aliases=1,component=Internal>Android)
 .bss@0(size_without_padding=131072,padding=0,full_name=ff_cos_65536,object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_float.o,source_path=third_party/fft_float.cc,flags={},num_aliases=1,component=Internal>Android)
diff --git a/tools/binary_size/libsupersize/testdata/Archive_OutputDirectory.golden b/tools/binary_size/libsupersize/testdata/Archive_OutputDirectory.golden
index c9d365f..604590f 100644
--- a/tools/binary_size/libsupersize/testdata/Archive_OutputDirectory.golden
+++ b/tools/binary_size/libsupersize/testdata/Archive_OutputDirectory.golden
@@ -1,43 +1,60 @@
-Section .text: has 100.0% of 35900712 bytes accounted for from 17 symbols. 0 bytes are unaccounted for.
-* 14 have source paths assigned (82.4%)
-* Padding accounts for 48 bytes (0.0%)
-* 5 placeholders (symbols that start with **) account for 35830760 bytes (99.8%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
-Section .rodata: has 100.0% of 5927652 bytes accounted for from 10 symbols. 0 bytes are unaccounted for.
-* 5 have source paths assigned (50.0%)
-* Padding accounts for 675996 bytes (11.4%)
-* 5 placeholders (symbols that start with **) account for 5251524 bytes (88.6%)
-* Contains 0 string literals. Total size=0, padding=0
-* Contains 0 aliases
-* 0 symbols have shared ownership
-Section .data.rel.ro: has 100.0% of 1065224 bytes accounted for from 4 symbols. 0 bytes are unaccounted for.
-* 3 have source paths assigned (75.0%)
+Section .text: has 0.2% of 83792 bytes accounted for from 16 symbols. 35816920 bytes are unaccounted for.
+* Padding accounts for 13808 bytes (16.5%)
+* 14 have source paths. Accounts for 74034 bytes (88.4%).
+* 4 placeholders exist (symbols that start with **). Accounts for 13840 bytes (16.5%).
+* 0 symbols have shared ownership.
+* 1 symbols are marked as "hot". Accounts for 12 bytes (0.0%).
+* 1 symbols are marked as "unlikely". Accounts for 69124 bytes (82.5%).
+* 4 symbols are marked as "startup". Accounts for 128 bytes (0.2%).
+* 2 symbols are clones. Accounts for 106 bytes (0.1%).
+* 3 symbols are from generated sources. Accounts for 69600 bytes (83.1%).
+Section .rodata: has 44.6% of 2641540 bytes accounted for from 9 symbols. 3286112 bytes are unaccounted for.
+* Padding accounts for 2637935 bytes (99.9%)
+* 5 have source paths. Accounts for 676128 bytes (25.6%).
+* 4 placeholders exist (symbols that start with **). Accounts for 1965412 bytes (74.4%).
+* 0 string literals exist. Accounts for 0 bytes (0.0%) padding is 0 bytes.
+* 0 symbols have shared ownership.
+Section .data.rel.ro: has 0.0% of 92 bytes accounted for from 3 symbols. 1065132 bytes are unaccounted for.
 * Padding accounts for 0 bytes (0.0%)
-* 1 placeholders (symbols that start with **) account for 1065132 bytes (100.0%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
-Section .data: has 100.0% of 101768 bytes accounted for from 6 symbols. 0 bytes are unaccounted for.
-* 5 have source paths assigned (83.3%)
+* 3 have source paths. Accounts for 92 bytes (100.0%).
+* 0 symbols have shared ownership.
+Section .data: has 0.2% of 168 bytes accounted for from 5 symbols. 101600 bytes are unaccounted for.
 * Padding accounts for 0 bytes (0.0%)
-* 1 placeholders (symbols that start with **) account for 101600 bytes (99.8%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
+* 5 have source paths. Accounts for 168 bytes (100.0%).
+* 0 symbols have shared ownership.
 Section .bss: has 40.3% of 524520 bytes accounted for from 6 symbols. 775936 bytes are unaccounted for.
-* 6 have source paths assigned (100.0%)
 * Padding accounts for 196 bytes (0.0%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
+* 6 have source paths. Accounts for 524520 bytes (100.0%).
+* 0 symbols have shared ownership.
+* 3 symbols are from generated sources. Accounts for 232 bytes (0.0%).
+Section .dex: 0 bytes from 0 symbols.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
+Section .dex.method: 0 bytes from 0 symbols.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
+Section .pak.translations: 0 bytes from 0 symbols.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
+Section .pak.nontranslated: 0 bytes from 0 symbols.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
+Section .other: 0 bytes from 0 symbols.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
 .data@2de7000(size_without_padding=4,padding=0,full_name=google::protobuf::internal::pLinuxKernelCmpxchg,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={},num_aliases=1,component=Blink>Internal)
 .data@2de7004(size_without_padding=4,padding=0,full_name=google::protobuf::internal::pLinuxKernelMemoryBarrier,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={},num_aliases=1,component=UI>Browser)
 .data@2de7008(size_without_padding=152,padding=0,full_name=base::android::kBaseRegisteredMethods,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={rel},num_aliases=1,component=UI>Browser)
 .data@2de70a0(size_without_padding=4,padding=0,full_name=base::android::g_renderer_histogram_code,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={anon},num_aliases=1,component=UI>Browser)
 .data@2de70a4(size_without_padding=4,padding=0,full_name=base::android::g_library_version_number,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={anon,rel.loc},num_aliases=1,component=UI>Browser)
-.data@2dffd88(size_without_padding=0,padding=101600,full_name=** symbol gap 0 (end of section),object_path=,source_path=,flags={},num_aliases=1,component=)
 .data.rel.ro@2cd8500(size_without_padding=56,padding=0,full_name=ChromeMainDelegateAndroid [vtable],object_path=third_party/sub/PaintChunker.o,source_path=third_party/paint.cc,flags={},num_aliases=1,component=Internal>Android)
 .data.rel.ro@2cd8538(size_without_padding=24,padding=0,full_name=mojo::MessageReceiver [vtable],object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={},num_aliases=1,component=Blink>Internal)
 .data.rel.ro@2cd8550(size_without_padding=12,padding=0,full_name=kMethodsAnimationFrameTimeHistogram,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={},num_aliases=1,component=Blink>Internal)
-.data.rel.ro@2ddc608(size_without_padding=0,padding=1065132,full_name=** symbol gap 0 (end of section),object_path=,source_path=,flags={},num_aliases=1,component=)
 .data.rel.ro.local@2c176f0(size_without_padding=56,padding=0,full_name=ChromeMainDelegate [vtable],object_path=third_party/icu/icuuc/ucnv_ext.o,source_path=third_party/icu/ucnv_ext.c,flags={gen},num_aliases=1,component=Internal>Android)
 .data.rel.ro.local@2c17728(size_without_padding=24,padding=0,full_name=chrome::mojom::FieldTrialRecorder [vtable],object_path=third_party/icu/icuuc/ucnv_ext.o,source_path=third_party/icu/ucnv_ext.c,flags={gen},num_aliases=1,component=Internal>Android)
 .data.rel.ro.local@2c17740(size_without_padding=789904,padding=0,full_name=chrome::mojom::FieldTrialRecorderProxy [vtable],object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={},num_aliases=1,component=UI>Browser)
@@ -52,7 +69,6 @@
 .rodata@284e398(size_without_padding=32,padding=0,full_name=chrome::mojom::FilePatcher::Name_,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={},num_aliases=1,component=UI>Browser)
 .rodata@28f3450(size_without_padding=48,padding=675992,full_name=kAnimationFrameTimeHistogramClassPath,object_path=third_party/sub/PaintChunker.o,source_path=third_party/paint.cc,flags={anon},num_aliases=1,component=Internal>Android)
 .rodata@28f3480(size_without_padding=4,padding=0,full_name=blink::CSSValueKeywordsHash::findValueImpl(char const*, unsigned int)::value_word_list,object_path=third_party/sub/PaintChunker.o,source_path=third_party/paint.cc,flags={anon},num_aliases=1,component=Internal>Android)
-.rodata@2c158e4(size_without_padding=0,padding=3286112,full_name=** symbol gap 1 (end of section),object_path=,source_path=,flags={},num_aliases=1,component=)
 .text@28d900(size_without_padding=16,padding=0,full_name=_GLOBAL__sub_I_page_allocator.cc,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={startup},num_aliases=1,component=Blink>Internal)
 .text@28d910(size_without_padding=56,padding=0,full_name=_GLOBAL__sub_I_bbr_sender.cc,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={startup},num_aliases=1,component=Blink>Internal)
 .text@28d948(size_without_padding=28,padding=0,full_name=_GLOBAL__sub_I_pacing_sender.cc,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={startup},num_aliases=1,component=Blink>Internal)
@@ -69,7 +85,6 @@
 .text@2a1000(size_without_padding=94,padding=0,full_name=blink::PaintChunker::releasePaintChunks(),object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={anon,clone},num_aliases=1,component=UI>Browser)
 .text@2a2000(size_without_padding=32,padding=4002,full_name=** outlined function,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={},num_aliases=1,component=UI>Browser)
 .text@2a2020(size_without_padding=48,padding=0,full_name=** outlined function,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={},num_aliases=1,component=UI>Browser)
-.text@24ca628(size_without_padding=0,padding=35816920,full_name=** symbol gap 2 (end of section),object_path=,source_path=,flags={},num_aliases=1,component=)
 .bss@0(size_without_padding=262144,padding=0,full_name=ff_cos_131072,object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_float.o,source_path=third_party/fft_float.cc,flags={},num_aliases=1,component=Internal>Android)
 .bss@0(size_without_padding=131072,padding=0,full_name=ff_cos_131072_fixed,object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_fixed.o,source_path=third_party/fft_fixed.cc,flags={},num_aliases=1,component=Internal>Android)
 .bss@0(size_without_padding=131072,padding=0,full_name=ff_cos_65536,object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_float.o,source_path=third_party/fft_float.cc,flags={},num_aliases=1,component=Internal>Android)
diff --git a/tools/binary_size/libsupersize/testdata/Archive_Pak_Files.golden b/tools/binary_size/libsupersize/testdata/Archive_Pak_Files.golden
index ded3734..02fe222d 100644
--- a/tools/binary_size/libsupersize/testdata/Archive_Pak_Files.golden
+++ b/tools/binary_size/libsupersize/testdata/Archive_Pak_Files.golden
@@ -7,61 +7,67 @@
 linker_name=gold
 map_file_name=../../../test.map
 tool_prefix=tools/binary_size/libsupersize/testdata/mock_toolchain/
-Section .text: has 100.0% of 35900712 bytes accounted for from 22 symbols. 0 bytes are unaccounted for.
-* 16 have source paths assigned (72.7%)
-* Padding accounts for 48 bytes (0.0%)
-* 5 placeholders (symbols that start with **) account for 35830760 bytes (99.8%)
-* Contains 8 aliases, mapped to 3 unique addresses (100 bytes saved)
-* 0 symbols have shared ownership
-Section .rodata: has 100.0% of 5927652 bytes accounted for from 12 symbols. 0 bytes are unaccounted for.
-* 8 have source paths assigned (66.7%)
-* Padding accounts for 675996 bytes (11.4%)
-* 4 placeholders (symbols that start with **) account for 5251503 bytes (88.6%)
-* Contains 3 string literals. Total size=21, padding=0
-* Contains 2 aliases, mapped to 1 unique addresses (5 bytes saved)
-* 0 symbols have shared ownership
-Section .data.rel.ro: has 100.0% of 1065224 bytes accounted for from 4 symbols. 0 bytes are unaccounted for.
-* 3 have source paths assigned (75.0%)
+Section .text: has 0.2% of 83792 bytes accounted for from 21 symbols. 35816920 bytes are unaccounted for.
+* Padding accounts for 13808 bytes (16.5%)
+* 16 have source paths. Accounts for 73986 bytes (88.3%).
+* 4 placeholders exist (symbols that start with **). Accounts for 13840 bytes (16.5%).
+* 8 aliases exist, mapped to 3 unique addresses (100 bytes saved)
+* 0 symbols have shared ownership.
+* 1 symbols are marked as "unlikely". Accounts for 69124 bytes (82.5%).
+* 4 symbols are marked as "startup". Accounts for 128 bytes (0.2%).
+* 3 symbols are clones. Accounts for 106 bytes (0.1%).
+* 5 symbols are from generated sources. Accounts for 69660 bytes (83.1%).
+Section .rodata: has 44.6% of 2641540 bytes accounted for from 11 symbols. 3286112 bytes are unaccounted for.
+* Padding accounts for 2637946 bytes (99.9%)
+* 8 have source paths. Accounts for 676149 bytes (25.6%).
+* 3 placeholders exist (symbols that start with **). Accounts for 1965391 bytes (74.4%).
+* 3 string literals exist. Accounts for 21 bytes (0.0%) padding is 0 bytes.
+* 2 aliases exist, mapped to 1 unique addresses (5 bytes saved)
+* 0 symbols have shared ownership.
+* 2 symbols are from generated sources. Accounts for 21 bytes (0.0%).
+Section .data.rel.ro: has 0.0% of 92 bytes accounted for from 3 symbols. 1065132 bytes are unaccounted for.
 * Padding accounts for 0 bytes (0.0%)
-* 1 placeholders (symbols that start with **) account for 1065132 bytes (100.0%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
-Section .data: has 100.0% of 101768 bytes accounted for from 6 symbols. 0 bytes are unaccounted for.
-* 5 have source paths assigned (83.3%)
+* 3 have source paths. Accounts for 92 bytes (100.0%).
+* 0 symbols have shared ownership.
+Section .data: has 0.2% of 168 bytes accounted for from 5 symbols. 101600 bytes are unaccounted for.
 * Padding accounts for 0 bytes (0.0%)
-* 1 placeholders (symbols that start with **) account for 101600 bytes (99.8%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
+* 5 have source paths. Accounts for 168 bytes (100.0%).
+* 0 symbols have shared ownership.
 Section .bss: has 40.3% of 524520 bytes accounted for from 6 symbols. 775936 bytes are unaccounted for.
-* 6 have source paths assigned (100.0%)
 * Padding accounts for 196 bytes (0.0%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
+* 6 have source paths. Accounts for 524520 bytes (100.0%).
+* 0 symbols have shared ownership.
+* 3 symbols are from generated sources. Accounts for 232 bytes (0.0%).
+Section .dex: 0 bytes from 0 symbols.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
+Section .dex.method: 0 bytes from 0 symbols.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
 Section .pak.translations: has 99.9% of 6821 bytes accounted for from 208 symbols. 9 bytes are unaccounted for.
-* 3 have source paths assigned (1.4%)
 * Padding accounts for 18 bytes (0.3%)
-* Contains 2 aliases, mapped to 1 unique addresses (9 bytes saved)
-* 0 symbols have shared ownership
+* 3 have source paths. Accounts for 23 bytes (0.3%).
+* 2 aliases exist, mapped to 1 unique addresses (9 bytes saved)
+* 0 symbols have shared ownership.
+* 2 symbols are from generated sources. Accounts for 23 bytes (0.3%).
 Section .pak.nontranslated: has 100.0% of 737 bytes accounted for from 3 symbols. 0 bytes are unaccounted for.
-* 0 have source paths assigned (0.0%)
 * Padding accounts for 18 bytes (2.4%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
 Section .other: has 100.0% of 33984171 bytes accounted for from 1 symbols. 0 bytes are unaccounted for.
-* 0 have source paths assigned (0.0%)
 * Padding accounts for 33984171 bytes (100.0%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
 .data@2de7000(size_without_padding=4,padding=0,full_name=google::protobuf::internal::pLinuxKernelCmpxchg,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={},num_aliases=1,component=Blink>Internal)
 .data@2de7004(size_without_padding=4,padding=0,full_name=google::protobuf::internal::pLinuxKernelMemoryBarrier,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={},num_aliases=1,component=UI>Browser)
 .data@2de7008(size_without_padding=152,padding=0,full_name=base::android::kBaseRegisteredMethods,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={rel},num_aliases=1,component=UI>Browser)
 .data@2de70a0(size_without_padding=4,padding=0,full_name=base::android::g_renderer_histogram_code,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={anon},num_aliases=1,component=UI>Browser)
 .data@2de70a4(size_without_padding=4,padding=0,full_name=base::android::g_library_version_number,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={anon,rel.loc},num_aliases=1,component=UI>Browser)
-.data@2dffd88(size_without_padding=0,padding=101600,full_name=** symbol gap 0 (end of section),object_path=,source_path=,flags={},num_aliases=1,component=)
 .data.rel.ro@2cd8500(size_without_padding=56,padding=0,full_name=ChromeMainDelegateAndroid [vtable],object_path=third_party/sub/PaintChunker.o,source_path=third_party/paint.cc,flags={},num_aliases=1,component=Internal>Android)
 .data.rel.ro@2cd8538(size_without_padding=24,padding=0,full_name=mojo::MessageReceiver [vtable],object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={},num_aliases=1,component=Blink>Internal)
 .data.rel.ro@2cd8550(size_without_padding=12,padding=0,full_name=kMethodsAnimationFrameTimeHistogram,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={},num_aliases=1,component=Blink>Internal)
-.data.rel.ro@2ddc608(size_without_padding=0,padding=1065132,full_name=** symbol gap 0 (end of section),object_path=,source_path=,flags={},num_aliases=1,component=)
 .data.rel.ro.local@2c176f0(size_without_padding=56,padding=0,full_name=ChromeMainDelegate [vtable],object_path=third_party/icu/icuuc/ucnv_ext.o,source_path=third_party/icu/ucnv_ext.c,flags={gen},num_aliases=1,component=Internal>Android)
 .data.rel.ro.local@2c17728(size_without_padding=24,padding=0,full_name=chrome::mojom::FieldTrialRecorder [vtable],object_path=third_party/icu/icuuc/ucnv_ext.o,source_path=third_party/icu/ucnv_ext.c,flags={gen},num_aliases=1,component=Internal>Android)
 .data.rel.ro.local@2c17740(size_without_padding=789904,padding=0,full_name=chrome::mojom::FieldTrialRecorderProxy [vtable],object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={},num_aliases=1,component=UI>Browser)
@@ -79,7 +85,6 @@
 .rodata@284e398(size_without_padding=32,padding=0,full_name=chrome::mojom::FilePatcher::Name_,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={},num_aliases=1,component=UI>Browser)
 .rodata@28f3450(size_without_padding=48,padding=675992,full_name=kAnimationFrameTimeHistogramClassPath,object_path=third_party/sub/PaintChunker.o,source_path=third_party/paint.cc,flags={anon},num_aliases=1,component=Internal>Android)
 .rodata@28f3480(size_without_padding=4,padding=0,full_name=blink::CSSValueKeywordsHash::findValueImpl(char const*, unsigned int)::value_word_list,object_path=third_party/sub/PaintChunker.o,source_path=third_party/paint.cc,flags={anon},num_aliases=1,component=Internal>Android)
-.rodata@2c158e4(size_without_padding=0,padding=3286112,full_name=** symbol gap 1 (end of section),object_path=,source_path=,flags={},num_aliases=1,component=)
 .text@28d900(size_without_padding=16,padding=0,full_name=_GLOBAL__sub_I_page_allocator.cc,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={startup},num_aliases=1,component=Blink>Internal)
 .text@28d910(size_without_padding=56,padding=0,full_name=_GLOBAL__sub_I_bbr_sender.cc,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={startup},num_aliases=1,component=Blink>Internal)
 .text@28d948(size_without_padding=28,padding=0,full_name=_GLOBAL__sub_I_pacing_sender.cc,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={startup},num_aliases=1,component=Blink>Internal)
@@ -101,7 +106,6 @@
 .text@2a2000(size_without_padding=32,padding=4002,full_name=** outlined function,object_path=third_party/sub/ContiguousContainer.o,source_path=third_party/container/container.c,flags={},num_aliases=1,component=UI>Browser)
 .text@2a2020(size_without_padding=48,padding=0,full_name=** outlined function * 2,object_path=,source_path=,flags={},num_aliases=2,component=)
 .text@2a2020(size_without_padding=48,padding=0,full_name=aliasedWithOutlinedFunction(),object_path=,source_path=,flags={},num_aliases=2,component=)
-.text@24ca628(size_without_padding=0,padding=35816920,full_name=** symbol gap 2 (end of section),object_path=,source_path=,flags={},num_aliases=1,component=)
 .bss@0(size_without_padding=262144,padding=0,full_name=ff_cos_131072,object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_float.o,source_path=third_party/fft_float.cc,flags={},num_aliases=1,component=Internal>Android)
 .bss@0(size_without_padding=131072,padding=0,full_name=ff_cos_131072_fixed,object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_fixed.o,source_path=third_party/fft_fixed.cc,flags={},num_aliases=1,component=Internal>Android)
 .bss@0(size_without_padding=131072,padding=0,full_name=ff_cos_65536,object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_float.o,source_path=third_party/fft_float.cc,flags={},num_aliases=1,component=Internal>Android)
diff --git a/tools/binary_size/libsupersize/testdata/Console.golden b/tools/binary_size/libsupersize/testdata/Console.golden
index 0c1f79a9..c30ae14 100644
--- a/tools/binary_size/libsupersize/testdata/Console.golden
+++ b/tools/binary_size/libsupersize/testdata/Console.golden
@@ -4,7 +4,7 @@
 SizeInfo: metadata, native_symbols, pak_symbols, raw_symbols, section_sizes, size_path, symbols
 Symbol: FlagsString, IsBss, IsDelta, IsDex, IsGeneratedByToolchain, IsGroup, IsNative, IsOther, IsOverhead, IsPak, IsStringLiteral, IterLeafSymbols, address, aliases, component, end_address, flags, full_name, generated_source, is_anonymous, name, num_aliases, object_path, padding, padding_pss, pss, pss_without_padding, section, section_name, size, size_without_padding, source_path, template_name
 
-SymbolGroup (extends Symbol): CountUniqueSymbols, Filter, GroupedBy, GroupedByAliases, GroupedByComponent, GroupedByFullName, GroupedByName, GroupedByPath, GroupedBySectionName, Inverted, IterUniqueSymbols, SetName, Sorted, SortedByAddress, SortedByCount, SortedByName, WhereAddressInRange, WhereComponentMatches, WhereFullNameMatches, WhereGeneratedByToolchain, WhereHasAnyAttribution, WhereHasComponent, WhereHasPath, WhereInSection, WhereIsDex, WhereIsGroup, WhereIsNative, WhereIsPak, WhereIsTemplate, WhereMatches, WhereNameMatches, WhereObjectPathMatches, WherePathMatches, WherePssBiggerThan, WhereSizeBiggerThan, WhereSourceIsGenerated, WhereSourcePathMatches, WhereTemplateNameMatches, index, is_default_sorted
+SymbolGroup (extends Symbol): CountUniqueSymbols, Filter, GroupedBy, GroupedByAliases, GroupedByComponent, GroupedByFullName, GroupedByName, GroupedByPath, GroupedBySectionName, Inverted, IterUniqueSymbols, SetName, Sorted, SortedByAddress, SortedByCount, SortedByName, WhereAddressInRange, WhereComponentMatches, WhereFullNameMatches, WhereGeneratedByToolchain, WhereHasAnyAttribution, WhereHasComponent, WhereHasFlag, WhereHasPath, WhereInSection, WhereIsDex, WhereIsGroup, WhereIsNative, WhereIsPak, WhereIsTemplate, WhereMatches, WhereNameMatches, WhereObjectPathMatches, WherePathMatches, WherePssBiggerThan, WhereSizeBiggerThan, WhereSourceIsGenerated, WhereSourcePathMatches, WhereTemplateNameMatches, index, is_default_sorted
 
 DeltaSizeInfo: after, before, native_symbols, pak_symbols, raw_symbols, section_sizes, symbols
 DeltaSymbol (extends Symbol): after_symbol, before_symbol, diff_status
@@ -12,7 +12,7 @@
 
 canned_queries: CategorizeByChromeComponent, CategorizeGenerated, LargeFiles, PakByPath, StaticInitializers, TemplatesByName
 
-Functions: Csv(), Diff(), Disassemble(), ExpandRegex(), Print(), ReadStringLiterals(), ShowExamples()
+Functions: Csv(), Diff(), Disassemble(), ExpandRegex(), Print(), ReadStringLiterals(), ShowExamples(), SizeStats()
 Variables:
   printed: List of objects passed to Print().
   size_info: Loaded from {redacted}
@@ -81,13 +81,13 @@
     .symtab: 16.4mb (17166112 bytes) (12.8%)
     .text: 34.2mb (35900712 bytes) (26.7%)
 
-Showing 53 symbols (47 unique) with total pss: 77769551 bytes
+Showing 51 symbols (45 unique) with total pss: 37499787 bytes
 Histogram of symbols based on PSS:
-     [2,4): 6    [16,32): 12     [128,256): 2    [65536,131072): 2    [524288,1048576): 2   [33554432,67108864): 2
-     [4,8): 6    [32,64): 9      [256,512): 1   [131072,262144): 2   [1048576,2097152): 2
-    [8,16): 3   [64,128): 1    [2048,4096): 1   [262144,524288): 1   [2097152,4194304): 1
-Sizes: .text=34.2mb     .rodata=5.65mb     .data.rel.ro=1.02mb     .data=99.4kb     .bss=512kb      .other=32.4mb     total=74.2mb
-Counts: .text=22 .rodata=12 .data.rel.ro=4 .data=6 .bss=6 .other=1
+     [2,4): 7    [16,32): 12     [128,256): 2      [8192,16384): 1     [262144,524288): 1   [33554432,67108864): 1
+     [4,8): 6    [32,64): 9      [256,512): 1    [65536,131072): 1    [524288,1048576): 2
+    [8,16): 3   [64,128): 1    [2048,4096): 1   [131072,262144): 2   [1048576,2097152): 1
+Sizes: .text=81.8kb     .rodata=2.52mb     .data.rel.ro=92 bytes   .data=168 bytes  .bss=512kb      .other=32.4mb     total=35.8mb
+Counts: .text=21 .rodata=11 .data.rel.ro=3 .data=5 .bss=6 .other=1
 Number of unique paths: 9
 
 Section Legend: t=.text, r=.rodata, R=.data.rel.ro, d=.data, b=.bss, o=.other
@@ -103,98 +103,94 @@
              base::android::g_renderer_histogram_code
 4)        168 (0.0%)  d@0x2de70a4  4              third_party/container/container.c
              base::android::g_library_version_number
-5)     101768 (0.1%)  d@0x2dffd88  101600         {no path}
-             ** symbol gap 0 (end of section)
-6)     101824 (0.1%)  R@0x2cd8500  56             third_party/paint.cc
+5)        224 (0.0%)  R@0x2cd8500  56             third_party/paint.cc
              ChromeMainDelegateAndroid [vtable]
-7)     101848 (0.1%)  R@0x2cd8538  24             base/page_allocator.cc
+6)        248 (0.0%)  R@0x2cd8538  24             base/page_allocator.cc
              mojo::MessageReceiver [vtable]
-8)     101860 (0.1%)  R@0x2cd8550  12             base/page_allocator.cc
+7)        260 (0.0%)  R@0x2cd8550  12             base/page_allocator.cc
              kMethodsAnimationFrameTimeHistogram
-9)    1166992 (1.5%)  R@0x2ddc608  1065132        {no path}
-             ** symbol gap 0 (end of section)
-10)   1167048 (1.5%)  R@0x2c176f0  56             $root_gen_dir/third_party/icu/ucnv_ext.c
+8)        316 (0.0%)  R@0x2c176f0  56             $root_gen_dir/third_party/icu/ucnv_ext.c
              ChromeMainDelegate [vtable]
-11)   1167072 (1.5%)  R@0x2c17728  24             $root_gen_dir/third_party/icu/ucnv_ext.c
+9)        340 (0.0%)  R@0x2c17728  24             $root_gen_dir/third_party/icu/ucnv_ext.c
              chrome::mojom::FieldTrialRecorder [vtable]
-12)   1956976 (2.5%)  R@0x2c17740  789904         third_party/container/container.c
+10)    790244 (2.1%)  R@0x2c17740  789904         third_party/container/container.c
              chrome::mojom::FieldTrialRecorderProxy [vtable]
-13)   1957008 (2.5%)  R@0x2cd84e0  32             third_party/gvr-android-sdk/libgvr_shim_static_arm.a/libcontroller_api_impl.a_controller_api_impl.o
+11)    790276 (2.1%)  R@0x2cd84e0  32             third_party/gvr-android-sdk/libgvr_shim_static_arm.a/libcontroller_api_impl.a_controller_api_impl.o
              .Lswitch.table.45
-14)   1957016 (2.5%)  R@0x2cd84f0  8              third_party/gvr-android-sdk/libgvr_shim_static_arm.a/libport_android_jni.a_jni_utils.o
+12)    790284 (2.1%)  R@0x2cd84f0  8              third_party/gvr-android-sdk/libgvr_shim_static_arm.a/libport_android_jni.a_jni_utils.o
              kSystemClassPrefixes
-15)  35941187 (46.2%) o@0x0        33984171       {no path}
+13)  34774455 (92.7%) o@0x0        33984171       {no path}
              Overhead: ELF file
-16)  35941189 (46.2%) r@0x266e600  2.5 (size=5)   base/page_allocator.cc
+14)  34774457 (92.7%) r@0x266e600  2.5 (size=5)   base/page_allocator.cc
              string literal (num_aliases=2)
-17)  35941192 (46.2%) r@0x266e600  2.5 (size=5)   $root_gen_dir/third_party/icu/ucnv_ext.c
+15)  34774460 (92.7%) r@0x266e600  2.5 (size=5)   $root_gen_dir/third_party/icu/ucnv_ext.c
              string literal (num_aliases=2)
-18)  35941208 (46.2%) r@0x266e605  16             $root_gen_dir/third_party/icu/ucnv_ext.c
+16)  34774476 (92.7%) r@0x266e605  16             $root_gen_dir/third_party/icu/ucnv_ext.c
              string literal
-19)  35941251 (46.2%) r@0x266e630  43             {no path}
+17)  34774519 (92.7%) r@0x266e630  43             {no path}
              ** merge strings
-20)  37906596 (48.7%) r@0x284d600  1965345        {no path}
+18)  36739864 (98.0%) r@0x284d600  1965345        {no path}
              ** merge constants
-21)  41192711 (53.0%) r@Group      3286115        {no path}
-             ** symbol gaps (count=2)
-22)  41192719 (53.0%) r@0x284e364  8              base/page_allocator.cc
-23)  41192763 (53.0%) r@0x284e370  44             base/page_allocator.cc
+19)  36739867 (98.0%) r@0x284e364  3              {no path}
+             ** symbol gap 0
+20)  36739875 (98.0%) r@0x284e364  8              base/page_allocator.cc
+21)  36739919 (98.0%) r@0x284e370  44             base/page_allocator.cc
              Name
-24)  41192795 (53.0%) r@0x284e398  32             third_party/container/container.c
+22)  36739951 (98.0%) r@0x284e398  32             third_party/container/container.c
              chrome::mojom::FilePatcher::Name_
-25)  41868835 (53.8%) r@0x28f3450  676040         third_party/paint.cc
+23)  37415991 (99.8%) r@0x28f3450  676040         third_party/paint.cc
              kAnimationFrameTimeHistogramClassPath
-26)  41868839 (53.8%) r@0x28f3480  4              third_party/paint.cc
+24)  37415995 (99.8%) r@0x28f3480  4              third_party/paint.cc
              blink::CSSValueKeywordsHash::findValueImpl::value_word_list
-27)  41868855 (53.8%) t@0x28d900   16             base/page_allocator.cc
+25)  37416011 (99.8%) t@0x28d900   16             base/page_allocator.cc
              _GLOBAL__sub_I_page_allocator.cc
-28)  41868911 (53.8%) t@0x28d910   56             base/page_allocator.cc
+26)  37416067 (99.8%) t@0x28d910   56             base/page_allocator.cc
              _GLOBAL__sub_I_bbr_sender.cc
-29)  41868939 (53.8%) t@0x28d948   28             base/page_allocator.cc
+27)  37416095 (99.8%) t@0x28d948   28             base/page_allocator.cc
              _GLOBAL__sub_I_pacing_sender.cc
-30)  41868977 (53.8%) t@0x28d964   38             base/page_allocator.cc
+28)  37416133 (99.8%) t@0x28d964   38             base/page_allocator.cc
              extFromUUseMapping
-31)  41869009 (53.8%) t@0x28d98a   32             base/page_allocator.cc
+29)  37416165 (99.8%) t@0x28d98a   32             base/page_allocator.cc
              extFromUUseMapping
-32)  77695687 (99.9%) t@Group      35826678       {no path}
-             ** symbol gaps (count=3)
-33)  77696135 (99.9%) t@0x28f000   448            $root_gen_dir/third_party/icu/ucnv_ext.c
+30)  37425923 (99.8%) t@Group      9758           {no path}
+             ** symbol gaps (count=2)
+31)  37426371 (99.8%) t@0x28f000   448            $root_gen_dir/third_party/icu/ucnv_ext.c
              ucnv_extMatchFromU
-34)  77696163 (99.9%) t@0x28f1c8   28             $root_gen_dir/third_party/icu/ucnv_ext.c
+32)  37426399 (99.8%) t@0x28f1c8   28             $root_gen_dir/third_party/icu/ucnv_ext.c
              _GLOBAL__sub_I_SkDeviceProfile.cpp
-35)  77765287 (100.0%) t@0x28f1e0   69124          $root_gen_dir/third_party/icu/ucnv_ext.c
+33)  37495523 (100.0%) t@0x28f1e0   69124          $root_gen_dir/third_party/icu/ucnv_ext.c
              foo_bar
-36)  77765311 (100.0%) t@0x2a0000   24 (size=48)   $root_gen_dir/third_party/icu/ucnv_ext.c
+34)  37495547 (100.0%) t@0x2a0000   24 (size=48)   $root_gen_dir/third_party/icu/ucnv_ext.c
              BazAlias (num_aliases=2)
-37)  77765335 (100.0%) t@0x2a0000   24 (size=48)   {no path}
+35)  37495571 (100.0%) t@0x2a0000   24 (size=48)   {no path}
              blink::ContiguousContainerBase::shrinkToFit (num_aliases=2)
-38)  77765338 (100.0%) t@0x2a0010   3 (size=12)    third_party/fft_float.cc
+36)  37495574 (100.0%) t@0x2a0010   3 (size=12)    third_party/fft_float.cc
              BarAlias (num_aliases=4)
-39)  77765341 (100.0%) t@0x2a0010   3 (size=12)    third_party/fft_float.cc
+37)  37495577 (100.0%) t@0x2a0010   3 (size=12)    third_party/fft_float.cc
              FooAlias (num_aliases=4)
-40)  77765344 (100.0%) t@0x2a0010   3 (size=12)    $root_gen_dir/third_party/icu/ucnv_ext.c
+38)  37495580 (100.0%) t@0x2a0010   3 (size=12)    $root_gen_dir/third_party/icu/ucnv_ext.c
              blink::ContiguousContainerBase::shrinkToFit (num_aliases=4)
-41)  77765347 (100.0%) t@0x2a0010   3 (size=12)    third_party/paint.cc
+39)  37495583 (100.0%) t@0x2a0010   3 (size=12)    third_party/paint.cc
              blink::ContiguousContainerBase::shrinkToFit (num_aliases=4)
-42)  77765375 (100.0%) t@0x2a0020   28             third_party/container/container.c
+40)  37495611 (100.0%) t@0x2a0020   28             third_party/container/container.c
              blink::ContiguousContainerBase::ContiguousContainerBase
-43)  77765469 (100.0%) t@0x2a1000   94             third_party/container/container.c
+41)  37495705 (100.0%) t@0x2a1000   94             third_party/container/container.c
              blink::PaintChunker::releasePaintChunks
-44)  77769503 (100.0%) t@0x2a2000   4034           third_party/container/container.c
+42)  37499739 (100.0%) t@0x2a2000   4034           third_party/container/container.c
              ** outlined function
-45)  77769527 (100.0%) t@0x2a2020   24 (size=48)   {no path}
+43)  37499763 (100.0%) t@0x2a2020   24 (size=48)   {no path}
              ** outlined function * 2 (num_aliases=2)
-46)  77769551 (100.0%) t@0x2a2020   24 (size=48)   {no path}
+44)  37499787 (100.0%) t@0x2a2020   24 (size=48)   {no path}
              aliasedWithOutlinedFunction (num_aliases=2)
-47)  77769551 (100.0%) b@0x0        262144         third_party/fft_float.cc
+45)  37499787 (100.0%) b@0x0        262144         third_party/fft_float.cc
              ff_cos_131072
-48)  77769551 (100.0%) b@0x0        131072         third_party/fft_fixed.cc
+46)  37499787 (100.0%) b@0x0        131072         third_party/fft_fixed.cc
              ff_cos_131072_fixed
-49)  77769551 (100.0%) b@0x0        131072         third_party/fft_float.cc
+47)  37499787 (100.0%) b@0x0        131072         third_party/fft_float.cc
              ff_cos_65536
-50)  77769551 (100.0%) b@0x2dffda0  28             $root_gen_dir/third_party/icu/ucnv_ext.c
+48)  37499787 (100.0%) b@0x2dffda0  28             $root_gen_dir/third_party/icu/ucnv_ext.c
              g_chrome_content_browser_client
-51)  77769551 (100.0%) b@0x2dffe80  200            $root_gen_dir/third_party/icu/ucnv_ext.c
+49)  37499787 (100.0%) b@0x2dffe80  200            $root_gen_dir/third_party/icu/ucnv_ext.c
              SaveHistogram::atomic_histogram_pointer
-52)  77769551 (100.0%) b@0x2dffe84  4              $root_gen_dir/third_party/icu/ucnv_ext.c
+50)  37499787 (100.0%) b@0x2dffe84  4              $root_gen_dir/third_party/icu/ucnv_ext.c
              g_AnimationFrameTimeHistogram_clazz
diff --git a/tools/binary_size/libsupersize/testdata/Csv.golden b/tools/binary_size/libsupersize/testdata/Csv.golden
index 74253bb..ecd143c 100644
--- a/tools/binary_size/libsupersize/testdata/Csv.golden
+++ b/tools/binary_size/libsupersize/testdata/Csv.golden
@@ -16,11 +16,9 @@
 ,0x2de7008,152,0,1,152.0,d,base::android::kBaseRegisteredMethods
 ,0x2de70a0,4,0,1,4.0,d,base::android::g_renderer_histogram_code
 ,0x2de70a4,4,0,1,4.0,d,base::android::g_library_version_number
-,0x2dffd88,0,101600,1,101600.0,d,** symbol gap 0 (end of section)
 ,0x2cd8500,56,0,1,56.0,R,ChromeMainDelegateAndroid [vtable]
 ,0x2cd8538,24,0,1,24.0,R,mojo::MessageReceiver [vtable]
 ,0x2cd8550,12,0,1,12.0,R,kMethodsAnimationFrameTimeHistogram
-,0x2ddc608,0,1065132,1,1065132.0,R,** symbol gap 0 (end of section)
 ,0x2c176f0,56,0,1,56.0,R,ChromeMainDelegate [vtable]
 ,0x2c17728,24,0,1,24.0,R,chrome::mojom::FieldTrialRecorder [vtable]
 ,0x2c17740,789904,0,1,789904.0,R,chrome::mojom::FieldTrialRecorderProxy [vtable]
@@ -32,7 +30,7 @@
 ,0x266e605,16,0,1,16.0,r,string literal
 ,0x266e630,16,27,1,43.0,r,** merge strings
 ,0x284d600,3425,1961920,1,1965345.0,r,** merge constants
-2,,0,3286115,1,3286115.0,r,** symbol gaps
+,0x284e364,0,3,1,3.0,r,** symbol gap 0
 ,0x284e364,8,0,1,8.0,r,
 ,0x284e370,40,4,1,44.0,r,Name
 ,0x284e398,32,0,1,32.0,r,chrome::mojom::FilePatcher::Name_
@@ -43,7 +41,7 @@
 ,0x28d948,28,0,1,28.0,t,_GLOBAL__sub_I_pacing_sender.cc
 ,0x28d964,38,0,1,38.0,t,extFromUUseMapping
 ,0x28d98a,32,0,1,32.0,t,extFromUUseMapping
-3,,0,35826678,1,35826678.0,t,** symbol gaps
+2,,0,9758,1,9758.0,t,** symbol gaps
 ,0x28f000,448,0,1,448.0,t,ucnv_extMatchFromU
 ,0x28f1c8,20,8,1,28.0,t,_GLOBAL__sub_I_SkDeviceProfile.cpp
 ,0x28f1e0,69120,4,1,69124.0,t,foo_bar
diff --git a/tools/binary_size/libsupersize/testdata/Diff_Basic.golden b/tools/binary_size/libsupersize/testdata/Diff_Basic.golden
index 0ed0012..2c61f37 100644
--- a/tools/binary_size/libsupersize/testdata/Diff_Basic.golden
+++ b/tools/binary_size/libsupersize/testdata/Diff_Basic.golden
@@ -40,10 +40,10 @@
     .strtab: 0 bytes (0 bytes)
     .symtab: 0 bytes (0 bytes)
 
-2 symbols added (+), 2 changed (~), 3 removed (-), 245 unchanged (not shown)
+2 symbols added (+), 2 changed (~), 3 removed (-), 243 unchanged (not shown)
 Added/Removed by section: .data: +2 .pak.translations: -3
 Of changed symbols, 3 grew, 4 shrank
-Number of unique symbols 256 -> 255 (-1)
+Number of unique symbols 252 -> 251 (-1)
 0 paths added, 0 removed, 2 changed
 Changed files:
   
diff --git a/tools/binary_size/libsupersize/testdata/Diff_NullDiff.golden b/tools/binary_size/libsupersize/testdata/Diff_NullDiff.golden
index f2f07c83..e3ba05c 100644
--- a/tools/binary_size/libsupersize/testdata/Diff_NullDiff.golden
+++ b/tools/binary_size/libsupersize/testdata/Diff_NullDiff.golden
@@ -20,10 +20,10 @@
     .rodata: 0 bytes (0 bytes) (0.0%)
     .text: 0 bytes (0 bytes) (0.0%)
 
-0 symbols added (+), 0 changed (~), 0 removed (-), 53 unchanged (not shown)
+0 symbols added (+), 0 changed (~), 0 removed (-), 51 unchanged (not shown)
 Added/Removed by section: 
 Of changed symbols, 0 grew, 0 shrank
-Number of unique symbols 50 -> 50 (+0)
+Number of unique symbols 46 -> 46 (+0)
 0 paths added, 0 removed, 0 changed
 
 Showing 0 symbols (0 -> 0 unique) with total pss: 0 bytes
diff --git a/tools/binary_size/libsupersize/testdata/FullDescription.golden b/tools/binary_size/libsupersize/testdata/FullDescription.golden
index 5ce4c80..9d9b5a9 100644
--- a/tools/binary_size/libsupersize/testdata/FullDescription.golden
+++ b/tools/binary_size/libsupersize/testdata/FullDescription.golden
@@ -42,49 +42,65 @@
     .rel.plt: 2.75kb (2816 bytes)
     .shstrtab: 436 bytes (436 bytes)
 
-Section .text: has 100.0% of 35900712 bytes accounted for from 22 symbols. 0 bytes are unaccounted for.
-* 16 have source paths assigned (72.7%)
-* Padding accounts for 48 bytes (0.0%)
-* 5 placeholders (symbols that start with **) account for 35830760 bytes (99.8%)
-* Contains 8 aliases, mapped to 3 unique addresses (100 bytes saved)
-* 0 symbols have shared ownership
-Section .rodata: has 100.0% of 5927652 bytes accounted for from 12 symbols. 0 bytes are unaccounted for.
-* 8 have source paths assigned (66.7%)
-* Padding accounts for 675996 bytes (11.4%)
-* 4 placeholders (symbols that start with **) account for 5251503 bytes (88.6%)
-* Contains 3 string literals. Total size=21, padding=0
-* Contains 2 aliases, mapped to 1 unique addresses (5 bytes saved)
-* 0 symbols have shared ownership
-Section .data.rel.ro: has 100.0% of 1065224 bytes accounted for from 4 symbols. 0 bytes are unaccounted for.
-* 3 have source paths assigned (75.0%)
+Section .text: has 0.2% of 83792 bytes accounted for from 21 symbols. 35816920 bytes are unaccounted for.
+* Padding accounts for 13808 bytes (16.5%)
+* 16 have source paths. Accounts for 73986 bytes (88.3%).
+* 4 placeholders exist (symbols that start with **). Accounts for 13840 bytes (16.5%).
+* 8 aliases exist, mapped to 3 unique addresses (100 bytes saved)
+* 0 symbols have shared ownership.
+* 1 symbols are marked as "unlikely". Accounts for 69124 bytes (82.5%).
+* 4 symbols are marked as "startup". Accounts for 128 bytes (0.2%).
+* 3 symbols are clones. Accounts for 106 bytes (0.1%).
+* 5 symbols are from generated sources. Accounts for 69660 bytes (83.1%).
+Section .rodata: has 44.6% of 2641540 bytes accounted for from 11 symbols. 3286112 bytes are unaccounted for.
+* Padding accounts for 2637946 bytes (99.9%)
+* 8 have source paths. Accounts for 676149 bytes (25.6%).
+* 3 placeholders exist (symbols that start with **). Accounts for 1965391 bytes (74.4%).
+* 3 string literals exist. Accounts for 21 bytes (0.0%) padding is 0 bytes.
+* 2 aliases exist, mapped to 1 unique addresses (5 bytes saved)
+* 0 symbols have shared ownership.
+* 2 symbols are from generated sources. Accounts for 21 bytes (0.0%).
+Section .data.rel.ro: has 0.0% of 92 bytes accounted for from 3 symbols. 1065132 bytes are unaccounted for.
 * Padding accounts for 0 bytes (0.0%)
-* 1 placeholders (symbols that start with **) account for 1065132 bytes (100.0%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
-Section .data: has 100.0% of 101768 bytes accounted for from 6 symbols. 0 bytes are unaccounted for.
-* 5 have source paths assigned (83.3%)
+* 3 have source paths. Accounts for 92 bytes (100.0%).
+* 0 symbols have shared ownership.
+Section .data: has 0.2% of 168 bytes accounted for from 5 symbols. 101600 bytes are unaccounted for.
 * Padding accounts for 0 bytes (0.0%)
-* 1 placeholders (symbols that start with **) account for 101600 bytes (99.8%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
+* 5 have source paths. Accounts for 168 bytes (100.0%).
+* 0 symbols have shared ownership.
 Section .bss: has 40.3% of 524520 bytes accounted for from 6 symbols. 775936 bytes are unaccounted for.
-* 6 have source paths assigned (100.0%)
 * Padding accounts for 196 bytes (0.0%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
+* 6 have source paths. Accounts for 524520 bytes (100.0%).
+* 0 symbols have shared ownership.
+* 3 symbols are from generated sources. Accounts for 232 bytes (0.0%).
+Section .dex: 0 bytes from 0 symbols.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
+Section .dex.method: 0 bytes from 0 symbols.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
+Section .pak.translations: 0 bytes from 0 symbols.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
+Section .pak.nontranslated: 0 bytes from 0 symbols.
+* Padding accounts for 0 bytes (0.0%)
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
 Section .other: has 100.0% of 33984171 bytes accounted for from 1 symbols. 0 bytes are unaccounted for.
-* 0 have source paths assigned (0.0%)
 * Padding accounts for 33984171 bytes (100.0%)
-* Contains 0 aliases
-* 0 symbols have shared ownership
+* 0 have source paths. Accounts for 0 bytes (0.0%).
+* 0 symbols have shared ownership.
 
-Showing 56 symbols (50 unique) with total pss: 77769551 bytes
+Showing 52 symbols (46 unique) with total pss: 37499787 bytes
 Histogram of symbols based on PSS:
-     [2,4): 7    [16,32): 12     [128,256): 2       [4096,8192): 1     [262144,524288): 1     [2097152,4194304): 1
-     [4,8): 6    [32,64): 9      [256,512): 1    [65536,131072): 2    [524288,1048576): 2   [33554432,67108864): 2
-    [8,16): 3   [64,128): 1    [2048,4096): 2   [131072,262144): 2   [1048576,2097152): 2
-Sizes: .text=34.2mb     .rodata=5.65mb     .data.rel.ro=1.02mb     .data=99.4kb     .bss=512kb      .other=32.4mb     total=74.2mb
-Counts: .text=22 .rodata=12 .data.rel.ro=4 .data=6 .bss=6 .other=1
+     [2,4): 7    [16,32): 12     [128,256): 2       [4096,8192): 1     [262144,524288): 1   [33554432,67108864): 1
+     [4,8): 6    [32,64): 9      [256,512): 1    [65536,131072): 1    [524288,1048576): 2
+    [8,16): 3   [64,128): 1    [2048,4096): 2   [131072,262144): 2   [1048576,2097152): 1
+Sizes: .text=81.8kb     .rodata=2.52mb     .data.rel.ro=92 bytes   .data=168 bytes  .bss=512kb      .other=32.4mb     total=35.8mb
+Counts: .text=21 .rodata=11 .data.rel.ro=3 .data=5 .bss=6 .other=1
 Number of unique paths: 9
 
 Section Legend: t=.text, r=.rodata, R=.data.rel.ro, d=.data, b=.bss, o=.other
@@ -105,179 +121,167 @@
 4)        168 (0.0%)  d@0x2de70a4  pss=4  padding=0  num_aliases=1
              source_path=third_party/container/container.c 	object_path=third_party/sub/ContiguousContainer.o
              flags={anon,rel.loc}  name=base::android::g_library_version_number
-5)     101768 (0.1%)  d@0x2dffd88  pss=101600  padding=101600  num_aliases=1
-             source_path= 	object_path=
-             flags={}  name=** symbol gap 0 (end of section)
-6)     101824 (0.1%)  R@0x2cd8500  pss=56  padding=0  num_aliases=1
+5)        224 (0.0%)  R@0x2cd8500  pss=56  padding=0  num_aliases=1
              source_path=third_party/paint.cc 	object_path=third_party/sub/PaintChunker.o
              flags={}  name=ChromeMainDelegateAndroid [vtable]
-7)     101848 (0.1%)  R@0x2cd8538  pss=24  padding=0  num_aliases=1
+6)        248 (0.0%)  R@0x2cd8538  pss=24  padding=0  num_aliases=1
              source_path=base/page_allocator.cc 	object_path=base/base/page_allocator.o
              flags={}  name=mojo::MessageReceiver [vtable]
-8)     101860 (0.1%)  R@0x2cd8550  pss=12  padding=0  num_aliases=1
+7)        260 (0.0%)  R@0x2cd8550  pss=12  padding=0  num_aliases=1
              source_path=base/page_allocator.cc 	object_path=base/base/page_allocator.o
              flags={}  name=kMethodsAnimationFrameTimeHistogram
-9)    1166992 (1.5%)  R@0x2ddc608  pss=1065132  padding=1065132  num_aliases=1
-             source_path= 	object_path=
-             flags={}  name=** symbol gap 0 (end of section)
-10)   1167048 (1.5%)  R@0x2c176f0  pss=56  padding=0  num_aliases=1
+8)        316 (0.0%)  R@0x2c176f0  pss=56  padding=0  num_aliases=1
              source_path=third_party/icu/ucnv_ext.c 	object_path=third_party/icu/icuuc/ucnv_ext.o
              flags={gen}  name=ChromeMainDelegate [vtable]
-11)   1167072 (1.5%)  R@0x2c17728  pss=24  padding=0  num_aliases=1
+9)        340 (0.0%)  R@0x2c17728  pss=24  padding=0  num_aliases=1
              source_path=third_party/icu/ucnv_ext.c 	object_path=third_party/icu/icuuc/ucnv_ext.o
              flags={gen}  name=chrome::mojom::FieldTrialRecorder [vtable]
-12)   1956976 (2.5%)  R@0x2c17740  pss=789904  padding=0  num_aliases=1
+10)    790244 (2.1%)  R@0x2c17740  pss=789904  padding=0  num_aliases=1
              source_path=third_party/container/container.c 	object_path=third_party/sub/ContiguousContainer.o
              flags={}  name=chrome::mojom::FieldTrialRecorderProxy [vtable]
-13)   1957008 (2.5%)  R@0x2cd84e0  pss=32  padding=16  num_aliases=1
+11)    790276 (2.1%)  R@0x2cd84e0  pss=32  padding=16  num_aliases=1
              source_path= 	object_path=third_party/gvr-android-sdk/libgvr_shim_static_arm.a/libcontroller_api_impl.a_controller_api_impl.o
              flags={}  name=.Lswitch.table.45
-14)   1957016 (2.5%)  R@0x2cd84f0  pss=8  padding=0  num_aliases=1
+12)    790284 (2.1%)  R@0x2cd84f0  pss=8  padding=0  num_aliases=1
              source_path= 	object_path=third_party/gvr-android-sdk/libgvr_shim_static_arm.a/libport_android_jni.a_jni_utils.o
              flags={anon}  name=kSystemClassPrefixes
-15)  35941187 (46.2%) o@0x0        pss=33984171  padding=33984171  num_aliases=1
+13)  34774455 (92.7%) o@0x0        pss=33984171  padding=33984171  num_aliases=1
              source_path= 	object_path=
              flags={}  name=Overhead: ELF file
-16)  35941189 (46.2%) r@0x266e600  pss=2.5 (size=5)  padding=0  num_aliases=2
+14)  34774457 (92.7%) r@0x266e600  pss=2.5 (size=5)  padding=0  num_aliases=2
              source_path=base/page_allocator.cc 	object_path=base/base/page_allocator.o
              flags={}  name=string literal
-17)  35941192 (46.2%) r@0x266e600  pss=2.5 (size=5)  padding=0  num_aliases=2
+15)  34774460 (92.7%) r@0x266e600  pss=2.5 (size=5)  padding=0  num_aliases=2
              source_path=third_party/icu/ucnv_ext.c 	object_path=third_party/icu/icuuc/ucnv_ext.o
              flags={gen}  name=string literal
-18)  35941208 (46.2%) r@0x266e605  pss=16  padding=0  num_aliases=1
+16)  34774476 (92.7%) r@0x266e605  pss=16  padding=0  num_aliases=1
              source_path=third_party/icu/ucnv_ext.c 	object_path=third_party/icu/icuuc/ucnv_ext.o
              flags={gen}  name=string literal
-19)  35941251 (46.2%) r@0x266e630  pss=43  padding=27  num_aliases=1
+17)  34774519 (92.7%) r@0x266e630  pss=43  padding=27  num_aliases=1
              source_path= 	object_path=
              flags={}  name=** merge strings
-20)  37906596 (48.7%) r@0x284d600  pss=1965345  padding=1961920  num_aliases=1
+18)  36739864 (98.0%) r@0x284d600  pss=1965345  padding=1961920  num_aliases=1
              source_path= 	object_path=
              flags={}  name=** merge constants
-21)  37906599 (48.7%) r@0x284e364  pss=3  padding=3  num_aliases=1
+19)  36739867 (98.0%) r@0x284e364  pss=3  padding=3  num_aliases=1
              source_path= 	object_path=
              flags={}  name=** symbol gap 0
-22)  37906607 (48.7%) r@0x284e364  pss=8  padding=0  num_aliases=1
+20)  36739875 (98.0%) r@0x284e364  pss=8  padding=0  num_aliases=1
              source_path=base/page_allocator.cc 	object_path=base/base/page_allocator.o
-23)  37906651 (48.7%) r@0x284e370  pss=44  padding=4  num_aliases=1
+21)  36739919 (98.0%) r@0x284e370  pss=44  padding=4  num_aliases=1
              source_path=base/page_allocator.cc 	object_path=base/base/page_allocator.o
              flags={}  name=Name
-24)  37906683 (48.7%) r@0x284e398  pss=32  padding=0  num_aliases=1
+22)  36739951 (98.0%) r@0x284e398  pss=32  padding=0  num_aliases=1
              source_path=third_party/container/container.c 	object_path=third_party/sub/ContiguousContainer.o
              flags={}  name=chrome::mojom::FilePatcher::Name_
-25)  38582723 (49.6%) r@0x28f3450  pss=676040  padding=675992  num_aliases=1
+23)  37415991 (99.8%) r@0x28f3450  pss=676040  padding=675992  num_aliases=1
              source_path=third_party/paint.cc 	object_path=third_party/sub/PaintChunker.o
              flags={anon}  name=kAnimationFrameTimeHistogramClassPath
-26)  38582727 (49.6%) r@0x28f3480  pss=4  padding=0  num_aliases=1
+24)  37415995 (99.8%) r@0x28f3480  pss=4  padding=0  num_aliases=1
              source_path=third_party/paint.cc 	object_path=third_party/sub/PaintChunker.o
              flags={anon}  name=blink::CSSValueKeywordsHash::findValueImpl::value_word_list
                   full_name=blink::CSSValueKeywordsHash::findValueImpl(char const*, unsigned int)::value_word_list
-27)  41868839 (53.8%) r@0x2c158e4  pss=3286112  padding=3286112  num_aliases=1
-             source_path= 	object_path=
-             flags={}  name=** symbol gap 1 (end of section)
-28)  41868855 (53.8%) t@0x28d900   pss=16  padding=0  num_aliases=1
+25)  37416011 (99.8%) t@0x28d900   pss=16  padding=0  num_aliases=1
              source_path=base/page_allocator.cc 	object_path=base/base/page_allocator.o
              flags={startup}  name=_GLOBAL__sub_I_page_allocator.cc
-29)  41868911 (53.8%) t@0x28d910   pss=56  padding=0  num_aliases=1
+26)  37416067 (99.8%) t@0x28d910   pss=56  padding=0  num_aliases=1
              source_path=base/page_allocator.cc 	object_path=base/base/page_allocator.o
              flags={startup}  name=_GLOBAL__sub_I_bbr_sender.cc
-30)  41868939 (53.8%) t@0x28d948   pss=28  padding=0  num_aliases=1
+27)  37416095 (99.8%) t@0x28d948   pss=28  padding=0  num_aliases=1
              source_path=base/page_allocator.cc 	object_path=base/base/page_allocator.o
              flags={startup}  name=_GLOBAL__sub_I_pacing_sender.cc
-31)  41868977 (53.8%) t@0x28d964   pss=38  padding=0  num_aliases=1
+28)  37416133 (99.8%) t@0x28d964   pss=38  padding=0  num_aliases=1
              source_path=base/page_allocator.cc 	object_path=base/base/page_allocator.o
              flags={}  name=extFromUUseMapping
                   full_name=extFromUUseMapping(signed char, unsigned int, int)
-32)  41869009 (53.8%) t@0x28d98a   pss=32  padding=0  num_aliases=1
+29)  37416165 (99.8%) t@0x28d98a   pss=32  padding=0  num_aliases=1
              source_path=base/page_allocator.cc 	object_path=base/base/page_allocator.o
              flags={}  name=extFromUUseMapping
                   full_name=extFromUUseMapping(aj, int)
-33)  41874727 (53.8%) t@0x28f000   pss=5718  padding=5718  num_aliases=1
+30)  37421883 (99.8%) t@0x28f000   pss=5718  padding=5718  num_aliases=1
              source_path= 	object_path=
              flags={}  name=** symbol gap 0
-34)  41875175 (53.8%) t@0x28f000   pss=448  padding=0  num_aliases=1
+31)  37422331 (99.8%) t@0x28f000   pss=448  padding=0  num_aliases=1
              source_path=third_party/icu/ucnv_ext.c 	object_path=third_party/icu/icuuc/ucnv_ext.o
              flags={gen}  name=ucnv_extMatchFromU
                   full_name=ucnv_extMatchFromU(int const*, int, unsigned short const*, int, unsigned short const*, int, unsigned int*, signed char, signed char)
-35)  41875203 (53.8%) t@0x28f1c8   pss=28  padding=8  num_aliases=1
+32)  37422359 (99.8%) t@0x28f1c8   pss=28  padding=8  num_aliases=1
              source_path=third_party/icu/ucnv_ext.c 	object_path=third_party/icu/icuuc/ucnv_ext.o
              flags={startup,gen}  name=_GLOBAL__sub_I_SkDeviceProfile.cpp
-36)  41944327 (53.9%) t@0x28f1e0   pss=69124  padding=4  num_aliases=1
+33)  37491483 (100.0%) t@0x28f1e0   pss=69124  padding=4  num_aliases=1
              source_path=third_party/icu/ucnv_ext.c 	object_path=third_party/icu/icuuc/ucnv_ext.o
              flags={unlikely,gen}  name=foo_bar
-37)  41944351 (53.9%) t@0x2a0000   pss=24 (size=48)  padding=32  num_aliases=2
+34)  37491507 (100.0%) t@0x2a0000   pss=24 (size=48)  padding=32  num_aliases=2
              source_path=third_party/icu/ucnv_ext.c 	object_path=third_party/icu/icuuc/ucnv_ext.o
              flags={gen}  name=BazAlias
                   full_name=BazAlias(bool)
-38)  41944375 (53.9%) t@0x2a0000   pss=24 (size=48)  padding=32  num_aliases=2
+35)  37491531 (100.0%) t@0x2a0000   pss=24 (size=48)  padding=32  num_aliases=2
              source_path= 	object_path=
              flags={}  name=blink::ContiguousContainerBase::shrinkToFit
                   full_name=blink::ContiguousContainerBase::shrinkToFit()
-39)  41944378 (53.9%) t@0x2a0010   pss=3 (size=12)  padding=0  num_aliases=4
+36)  37491534 (100.0%) t@0x2a0010   pss=3 (size=12)  padding=0  num_aliases=4
              source_path=third_party/fft_float.cc 	object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_float.o
              flags={}  name=BarAlias
                   full_name=BarAlias()
-40)  41944381 (53.9%) t@0x2a0010   pss=3 (size=12)  padding=0  num_aliases=4
+37)  37491537 (100.0%) t@0x2a0010   pss=3 (size=12)  padding=0  num_aliases=4
              source_path=third_party/fft_float.cc 	object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_float.o
              flags={}  name=FooAlias
                   full_name=FooAlias()
-41)  41944384 (53.9%) t@0x2a0010   pss=3 (size=12)  padding=0  num_aliases=4
+38)  37491540 (100.0%) t@0x2a0010   pss=3 (size=12)  padding=0  num_aliases=4
              source_path=third_party/icu/ucnv_ext.c 	object_path=third_party/icu/icuuc/ucnv_ext.o
              flags={gen,clone}  name=blink::ContiguousContainerBase::shrinkToFit
                   full_name=blink::ContiguousContainerBase::shrinkToFit()
-42)  41944387 (53.9%) t@0x2a0010   pss=3 (size=12)  padding=0  num_aliases=4
+39)  37491543 (100.0%) t@0x2a0010   pss=3 (size=12)  padding=0  num_aliases=4
              source_path=third_party/paint.cc 	object_path=third_party/sub/PaintChunker.o
              flags={clone}  name=blink::ContiguousContainerBase::shrinkToFit
                   full_name=blink::ContiguousContainerBase::shrinkToFit()
-43)  41944415 (53.9%) t@0x2a0020   pss=28  padding=4  num_aliases=1
+40)  37491571 (100.0%) t@0x2a0020   pss=28  padding=4  num_aliases=1
              source_path=third_party/container/container.c 	object_path=third_party/sub/ContiguousContainer.o
              flags={}  name=blink::ContiguousContainerBase::ContiguousContainerBase
                   full_name=blink::ContiguousContainerBase::ContiguousContainerBase(blink::ContiguousContainerBase&&)
-44)  41948455 (53.9%) t@0x2a1000   pss=4040  padding=4040  num_aliases=1
+41)  37495611 (100.0%) t@0x2a1000   pss=4040  padding=4040  num_aliases=1
              source_path= 	object_path=
              flags={}  name=** symbol gap 1
-45)  41948549 (53.9%) t@0x2a1000   pss=94  padding=0  num_aliases=1
+42)  37495705 (100.0%) t@0x2a1000   pss=94  padding=0  num_aliases=1
              source_path=third_party/container/container.c 	object_path=third_party/sub/ContiguousContainer.o
              flags={anon,clone}  name=blink::PaintChunker::releasePaintChunks
                   full_name=blink::PaintChunker::releasePaintChunks()
-46)  41952583 (53.9%) t@0x2a2000   pss=4034  padding=4002  num_aliases=1
+43)  37499739 (100.0%) t@0x2a2000   pss=4034  padding=4002  num_aliases=1
              source_path=third_party/container/container.c 	object_path=third_party/sub/ContiguousContainer.o
              flags={}  name=** outlined function
-47)  41952607 (53.9%) t@0x2a2020   pss=24 (size=48)  padding=0  num_aliases=2
+44)  37499763 (100.0%) t@0x2a2020   pss=24 (size=48)  padding=0  num_aliases=2
              source_path= 	object_path=
              flags={}  name=** outlined function * 2
-48)  41952631 (53.9%) t@0x2a2020   pss=24 (size=48)  padding=0  num_aliases=2
+45)  37499787 (100.0%) t@0x2a2020   pss=24 (size=48)  padding=0  num_aliases=2
              source_path= 	object_path=
              flags={}  name=aliasedWithOutlinedFunction
                   full_name=aliasedWithOutlinedFunction()
-49)  77769551 (100.0%) t@0x24ca628  pss=35816920  padding=35816920  num_aliases=1
-             source_path= 	object_path=
-             flags={}  name=** symbol gap 2 (end of section)
-50)  77769551 (100.0%) b@0x0        pss=262144  padding=0  num_aliases=1
+46)  37499787 (100.0%) b@0x0        pss=262144  padding=0  num_aliases=1
              source_path=third_party/fft_float.cc 	object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_float.o
              flags={}  name=ff_cos_131072
-51)  77769551 (100.0%) b@0x0        pss=131072  padding=0  num_aliases=1
+47)  37499787 (100.0%) b@0x0        pss=131072  padding=0  num_aliases=1
              source_path=third_party/fft_fixed.cc 	object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_fixed.o
              flags={}  name=ff_cos_131072_fixed
-52)  77769551 (100.0%) b@0x0        pss=131072  padding=0  num_aliases=1
+48)  37499787 (100.0%) b@0x0        pss=131072  padding=0  num_aliases=1
              source_path=third_party/fft_float.cc 	object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_float.o
              flags={}  name=ff_cos_65536
-53)  77769551 (100.0%) b@0x2dffda0  pss=28  padding=0  num_aliases=1
+49)  37499787 (100.0%) b@0x2dffda0  pss=28  padding=0  num_aliases=1
              source_path=third_party/icu/ucnv_ext.c 	object_path=third_party/icu/icuuc/ucnv_ext.o
              flags={gen}  name=g_chrome_content_browser_client
-54)  77769551 (100.0%) b@0x2dffe80  pss=200  padding=196  num_aliases=1
+50)  37499787 (100.0%) b@0x2dffe80  pss=200  padding=196  num_aliases=1
              source_path=third_party/icu/ucnv_ext.c 	object_path=third_party/icu/icuuc/ucnv_ext.o
              flags={gen}  name=SaveHistogram::atomic_histogram_pointer
                   full_name=SaveHistogram(_JNIEnv*, base::android::JavaParamRef<_jobject*> const&, base::android::JavaParamRef<_jstring*> const&, base::android::JavaParamRef<_jlongArray*> const&, int)::atomic_histogram_pointer
-55)  77769551 (100.0%) b@0x2dffe84  pss=4  padding=0  num_aliases=1
+51)  37499787 (100.0%) b@0x2dffe84  pss=4  padding=0  num_aliases=1
              source_path=third_party/icu/ucnv_ext.c 	object_path=third_party/icu/icuuc/ucnv_ext.o
              flags={anon,gen}  name=g_AnimationFrameTimeHistogram_clazz
-Showing 53 symbols (47 unique) with total pss: 77769551 bytes
+Showing 51 symbols (45 unique) with total pss: 37499787 bytes
 Histogram of symbols based on PSS:
-     [2,4): 6    [16,32): 12     [128,256): 2    [65536,131072): 2    [524288,1048576): 2   [33554432,67108864): 2
-     [4,8): 6    [32,64): 9      [256,512): 1   [131072,262144): 2   [1048576,2097152): 2
-    [8,16): 3   [64,128): 1    [2048,4096): 1   [262144,524288): 1   [2097152,4194304): 1
-Sizes: .text=34.2mb     .rodata=5.65mb     .data.rel.ro=1.02mb     .data=99.4kb     .bss=512kb      .other=32.4mb     total=74.2mb
-Counts: .text=22 .rodata=12 .data.rel.ro=4 .data=6 .bss=6 .other=1
+     [2,4): 7    [16,32): 12     [128,256): 2      [8192,16384): 1     [262144,524288): 1   [33554432,67108864): 1
+     [4,8): 6    [32,64): 9      [256,512): 1    [65536,131072): 1    [524288,1048576): 2
+    [8,16): 3   [64,128): 1    [2048,4096): 1   [131072,262144): 2   [1048576,2097152): 1
+Sizes: .text=81.8kb     .rodata=2.52mb     .data.rel.ro=92 bytes   .data=168 bytes  .bss=512kb      .other=32.4mb     total=35.8mb
+Counts: .text=21 .rodata=11 .data.rel.ro=3 .data=5 .bss=6 .other=1
 Number of unique paths: 9
 
 Section Legend: t=.text, r=.rodata, R=.data.rel.ro, d=.data, b=.bss, o=.other
@@ -298,175 +302,160 @@
 4)        168 (0.0%)  d@0x2de70a4  pss=4  padding=0  num_aliases=1
              source_path=third_party/container/container.c 	object_path=third_party/sub/ContiguousContainer.o
              flags={anon,rel.loc}  name=base::android::g_library_version_number
-5)     101768 (0.1%)  d@0x2dffd88  pss=101600  padding=101600  num_aliases=1
-             source_path= 	object_path=
-             flags={}  name=** symbol gap 0 (end of section)
-6)     101824 (0.1%)  R@0x2cd8500  pss=56  padding=0  num_aliases=1
+5)        224 (0.0%)  R@0x2cd8500  pss=56  padding=0  num_aliases=1
              source_path=third_party/paint.cc 	object_path=third_party/sub/PaintChunker.o
              flags={}  name=ChromeMainDelegateAndroid [vtable]
-7)     101848 (0.1%)  R@0x2cd8538  pss=24  padding=0  num_aliases=1
+6)        248 (0.0%)  R@0x2cd8538  pss=24  padding=0  num_aliases=1
              source_path=base/page_allocator.cc 	object_path=base/base/page_allocator.o
              flags={}  name=mojo::MessageReceiver [vtable]
-8)     101860 (0.1%)  R@0x2cd8550  pss=12  padding=0  num_aliases=1
+7)        260 (0.0%)  R@0x2cd8550  pss=12  padding=0  num_aliases=1
              source_path=base/page_allocator.cc 	object_path=base/base/page_allocator.o
              flags={}  name=kMethodsAnimationFrameTimeHistogram
-9)    1166992 (1.5%)  R@0x2ddc608  pss=1065132  padding=1065132  num_aliases=1
-             source_path= 	object_path=
-             flags={}  name=** symbol gap 0 (end of section)
-10)   1167048 (1.5%)  R@0x2c176f0  pss=56  padding=0  num_aliases=1
+8)        316 (0.0%)  R@0x2c176f0  pss=56  padding=0  num_aliases=1
              source_path=third_party/icu/ucnv_ext.c 	object_path=third_party/icu/icuuc/ucnv_ext.o
              flags={gen}  name=ChromeMainDelegate [vtable]
-11)   1167072 (1.5%)  R@0x2c17728  pss=24  padding=0  num_aliases=1
+9)        340 (0.0%)  R@0x2c17728  pss=24  padding=0  num_aliases=1
              source_path=third_party/icu/ucnv_ext.c 	object_path=third_party/icu/icuuc/ucnv_ext.o
              flags={gen}  name=chrome::mojom::FieldTrialRecorder [vtable]
-12)   1956976 (2.5%)  R@0x2c17740  pss=789904  padding=0  num_aliases=1
+10)    790244 (2.1%)  R@0x2c17740  pss=789904  padding=0  num_aliases=1
              source_path=third_party/container/container.c 	object_path=third_party/sub/ContiguousContainer.o
              flags={}  name=chrome::mojom::FieldTrialRecorderProxy [vtable]
-13)   1957008 (2.5%)  R@0x2cd84e0  pss=32  padding=16  num_aliases=1
+11)    790276 (2.1%)  R@0x2cd84e0  pss=32  padding=16  num_aliases=1
              source_path= 	object_path=third_party/gvr-android-sdk/libgvr_shim_static_arm.a/libcontroller_api_impl.a_controller_api_impl.o
              flags={}  name=.Lswitch.table.45
-14)   1957016 (2.5%)  R@0x2cd84f0  pss=8  padding=0  num_aliases=1
+12)    790284 (2.1%)  R@0x2cd84f0  pss=8  padding=0  num_aliases=1
              source_path= 	object_path=third_party/gvr-android-sdk/libgvr_shim_static_arm.a/libport_android_jni.a_jni_utils.o
              flags={anon}  name=kSystemClassPrefixes
-15)  35941187 (46.2%) o@0x0        pss=33984171  padding=33984171  num_aliases=1
+13)  34774455 (92.7%) o@0x0        pss=33984171  padding=33984171  num_aliases=1
              source_path= 	object_path=
              flags={}  name=Overhead: ELF file
-16)  35941189 (46.2%) r@0x266e600  pss=2.5 (size=5)  padding=0  num_aliases=2
+14)  34774457 (92.7%) r@0x266e600  pss=2.5 (size=5)  padding=0  num_aliases=2
              source_path=base/page_allocator.cc 	object_path=base/base/page_allocator.o
              flags={}  name=string literal
-17)  35941192 (46.2%) r@0x266e600  pss=2.5 (size=5)  padding=0  num_aliases=2
+15)  34774460 (92.7%) r@0x266e600  pss=2.5 (size=5)  padding=0  num_aliases=2
              source_path=third_party/icu/ucnv_ext.c 	object_path=third_party/icu/icuuc/ucnv_ext.o
              flags={gen}  name=string literal
-18)  35941208 (46.2%) r@0x266e605  pss=16  padding=0  num_aliases=1
+16)  34774476 (92.7%) r@0x266e605  pss=16  padding=0  num_aliases=1
              source_path=third_party/icu/ucnv_ext.c 	object_path=third_party/icu/icuuc/ucnv_ext.o
              flags={gen}  name=string literal
-19)  35941251 (46.2%) r@0x266e630  pss=43  padding=27  num_aliases=1
+17)  34774519 (92.7%) r@0x266e630  pss=43  padding=27  num_aliases=1
              source_path= 	object_path=
              flags={}  name=** merge strings
-20)  37906596 (48.7%) r@0x284d600  pss=1965345  padding=1961920  num_aliases=1
+18)  36739864 (98.0%) r@0x284d600  pss=1965345  padding=1961920  num_aliases=1
              source_path= 	object_path=
              flags={}  name=** merge constants
-21)  41192711 (53.0%) r@Group      pss=3286115  padding=3286115  count=2
+19)  36739867 (98.0%) r@0x284e364  pss=3  padding=3  num_aliases=1
              source_path= 	object_path=
-             flags={}  name=** symbol gaps
-> 0)          3 (0.0%)  r@0x284e364  pss=3  padding=3  num_aliases=1
-               source_path= 	object_path=
-               flags={}  name=** symbol gap 0
-> 1)    3286115 (100.0%) r@0x2c158e4  pss=3286112  padding=3286112  num_aliases=1
-               source_path= 	object_path=
-               flags={}  name=** symbol gap 1 (end of section)
-22)  41192719 (53.0%) r@0x284e364  pss=8  padding=0  num_aliases=1
+             flags={}  name=** symbol gap 0
+20)  36739875 (98.0%) r@0x284e364  pss=8  padding=0  num_aliases=1
              source_path=base/page_allocator.cc 	object_path=base/base/page_allocator.o
-23)  41192763 (53.0%) r@0x284e370  pss=44  padding=4  num_aliases=1
+21)  36739919 (98.0%) r@0x284e370  pss=44  padding=4  num_aliases=1
              source_path=base/page_allocator.cc 	object_path=base/base/page_allocator.o
              flags={}  name=Name
-24)  41192795 (53.0%) r@0x284e398  pss=32  padding=0  num_aliases=1
+22)  36739951 (98.0%) r@0x284e398  pss=32  padding=0  num_aliases=1
              source_path=third_party/container/container.c 	object_path=third_party/sub/ContiguousContainer.o
              flags={}  name=chrome::mojom::FilePatcher::Name_
-25)  41868835 (53.8%) r@0x28f3450  pss=676040  padding=675992  num_aliases=1
+23)  37415991 (99.8%) r@0x28f3450  pss=676040  padding=675992  num_aliases=1
              source_path=third_party/paint.cc 	object_path=third_party/sub/PaintChunker.o
              flags={anon}  name=kAnimationFrameTimeHistogramClassPath
-26)  41868839 (53.8%) r@0x28f3480  pss=4  padding=0  num_aliases=1
+24)  37415995 (99.8%) r@0x28f3480  pss=4  padding=0  num_aliases=1
              source_path=third_party/paint.cc 	object_path=third_party/sub/PaintChunker.o
              flags={anon}  name=blink::CSSValueKeywordsHash::findValueImpl::value_word_list
                   full_name=blink::CSSValueKeywordsHash::findValueImpl(char const*, unsigned int)::value_word_list
-27)  41868855 (53.8%) t@0x28d900   pss=16  padding=0  num_aliases=1
+25)  37416011 (99.8%) t@0x28d900   pss=16  padding=0  num_aliases=1
              source_path=base/page_allocator.cc 	object_path=base/base/page_allocator.o
              flags={startup}  name=_GLOBAL__sub_I_page_allocator.cc
-28)  41868911 (53.8%) t@0x28d910   pss=56  padding=0  num_aliases=1
+26)  37416067 (99.8%) t@0x28d910   pss=56  padding=0  num_aliases=1
              source_path=base/page_allocator.cc 	object_path=base/base/page_allocator.o
              flags={startup}  name=_GLOBAL__sub_I_bbr_sender.cc
-29)  41868939 (53.8%) t@0x28d948   pss=28  padding=0  num_aliases=1
+27)  37416095 (99.8%) t@0x28d948   pss=28  padding=0  num_aliases=1
              source_path=base/page_allocator.cc 	object_path=base/base/page_allocator.o
              flags={startup}  name=_GLOBAL__sub_I_pacing_sender.cc
-30)  41868977 (53.8%) t@0x28d964   pss=38  padding=0  num_aliases=1
+28)  37416133 (99.8%) t@0x28d964   pss=38  padding=0  num_aliases=1
              source_path=base/page_allocator.cc 	object_path=base/base/page_allocator.o
              flags={}  name=extFromUUseMapping
                   full_name=extFromUUseMapping(signed char, unsigned int, int)
-31)  41869009 (53.8%) t@0x28d98a   pss=32  padding=0  num_aliases=1
+29)  37416165 (99.8%) t@0x28d98a   pss=32  padding=0  num_aliases=1
              source_path=base/page_allocator.cc 	object_path=base/base/page_allocator.o
              flags={}  name=extFromUUseMapping
                   full_name=extFromUUseMapping(aj, int)
-32)  77695687 (99.9%) t@Group      pss=35826678  padding=35826678  count=3
+30)  37425923 (99.8%) t@Group      pss=9758  padding=9758  count=2
              source_path= 	object_path=
              flags={}  name=** symbol gaps
-> 0)       5718 (0.0%)  t@0x28f000   pss=5718  padding=5718  num_aliases=1
+> 0)       5718 (58.6%) t@0x28f000   pss=5718  padding=5718  num_aliases=1
                source_path= 	object_path=
                flags={}  name=** symbol gap 0
-> 1)       9758 (0.0%)  t@0x2a1000   pss=4040  padding=4040  num_aliases=1
+> 1)       9758 (100.0%) t@0x2a1000   pss=4040  padding=4040  num_aliases=1
                source_path= 	object_path=
                flags={}  name=** symbol gap 1
-> 2)   35826678 (100.0%) t@0x24ca628  pss=35816920  padding=35816920  num_aliases=1
-               source_path= 	object_path=
-               flags={}  name=** symbol gap 2 (end of section)
-33)  77696135 (99.9%) t@0x28f000   pss=448  padding=0  num_aliases=1
+31)  37426371 (99.8%) t@0x28f000   pss=448  padding=0  num_aliases=1
              source_path=third_party/icu/ucnv_ext.c 	object_path=third_party/icu/icuuc/ucnv_ext.o
              flags={gen}  name=ucnv_extMatchFromU
                   full_name=ucnv_extMatchFromU(int const*, int, unsigned short const*, int, unsigned short const*, int, unsigned int*, signed char, signed char)
-34)  77696163 (99.9%) t@0x28f1c8   pss=28  padding=8  num_aliases=1
+32)  37426399 (99.8%) t@0x28f1c8   pss=28  padding=8  num_aliases=1
              source_path=third_party/icu/ucnv_ext.c 	object_path=third_party/icu/icuuc/ucnv_ext.o
              flags={startup,gen}  name=_GLOBAL__sub_I_SkDeviceProfile.cpp
-35)  77765287 (100.0%) t@0x28f1e0   pss=69124  padding=4  num_aliases=1
+33)  37495523 (100.0%) t@0x28f1e0   pss=69124  padding=4  num_aliases=1
              source_path=third_party/icu/ucnv_ext.c 	object_path=third_party/icu/icuuc/ucnv_ext.o
              flags={unlikely,gen}  name=foo_bar
-36)  77765311 (100.0%) t@0x2a0000   pss=24 (size=48)  padding=32  num_aliases=2
+34)  37495547 (100.0%) t@0x2a0000   pss=24 (size=48)  padding=32  num_aliases=2
              source_path=third_party/icu/ucnv_ext.c 	object_path=third_party/icu/icuuc/ucnv_ext.o
              flags={gen}  name=BazAlias
                   full_name=BazAlias(bool)
-37)  77765335 (100.0%) t@0x2a0000   pss=24 (size=48)  padding=32  num_aliases=2
+35)  37495571 (100.0%) t@0x2a0000   pss=24 (size=48)  padding=32  num_aliases=2
              source_path= 	object_path=
              flags={}  name=blink::ContiguousContainerBase::shrinkToFit
                   full_name=blink::ContiguousContainerBase::shrinkToFit()
-38)  77765338 (100.0%) t@0x2a0010   pss=3 (size=12)  padding=0  num_aliases=4
+36)  37495574 (100.0%) t@0x2a0010   pss=3 (size=12)  padding=0  num_aliases=4
              source_path=third_party/fft_float.cc 	object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_float.o
              flags={}  name=BarAlias
                   full_name=BarAlias()
-39)  77765341 (100.0%) t@0x2a0010   pss=3 (size=12)  padding=0  num_aliases=4
+37)  37495577 (100.0%) t@0x2a0010   pss=3 (size=12)  padding=0  num_aliases=4
              source_path=third_party/fft_float.cc 	object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_float.o
              flags={}  name=FooAlias
                   full_name=FooAlias()
-40)  77765344 (100.0%) t@0x2a0010   pss=3 (size=12)  padding=0  num_aliases=4
+38)  37495580 (100.0%) t@0x2a0010   pss=3 (size=12)  padding=0  num_aliases=4
              source_path=third_party/icu/ucnv_ext.c 	object_path=third_party/icu/icuuc/ucnv_ext.o
              flags={gen,clone}  name=blink::ContiguousContainerBase::shrinkToFit
                   full_name=blink::ContiguousContainerBase::shrinkToFit()
-41)  77765347 (100.0%) t@0x2a0010   pss=3 (size=12)  padding=0  num_aliases=4
+39)  37495583 (100.0%) t@0x2a0010   pss=3 (size=12)  padding=0  num_aliases=4
              source_path=third_party/paint.cc 	object_path=third_party/sub/PaintChunker.o
              flags={clone}  name=blink::ContiguousContainerBase::shrinkToFit
                   full_name=blink::ContiguousContainerBase::shrinkToFit()
-42)  77765375 (100.0%) t@0x2a0020   pss=28  padding=4  num_aliases=1
+40)  37495611 (100.0%) t@0x2a0020   pss=28  padding=4  num_aliases=1
              source_path=third_party/container/container.c 	object_path=third_party/sub/ContiguousContainer.o
              flags={}  name=blink::ContiguousContainerBase::ContiguousContainerBase
                   full_name=blink::ContiguousContainerBase::ContiguousContainerBase(blink::ContiguousContainerBase&&)
-43)  77765469 (100.0%) t@0x2a1000   pss=94  padding=0  num_aliases=1
+41)  37495705 (100.0%) t@0x2a1000   pss=94  padding=0  num_aliases=1
              source_path=third_party/container/container.c 	object_path=third_party/sub/ContiguousContainer.o
              flags={anon,clone}  name=blink::PaintChunker::releasePaintChunks
                   full_name=blink::PaintChunker::releasePaintChunks()
-44)  77769503 (100.0%) t@0x2a2000   pss=4034  padding=4002  num_aliases=1
+42)  37499739 (100.0%) t@0x2a2000   pss=4034  padding=4002  num_aliases=1
              source_path=third_party/container/container.c 	object_path=third_party/sub/ContiguousContainer.o
              flags={}  name=** outlined function
-45)  77769527 (100.0%) t@0x2a2020   pss=24 (size=48)  padding=0  num_aliases=2
+43)  37499763 (100.0%) t@0x2a2020   pss=24 (size=48)  padding=0  num_aliases=2
              source_path= 	object_path=
              flags={}  name=** outlined function * 2
-46)  77769551 (100.0%) t@0x2a2020   pss=24 (size=48)  padding=0  num_aliases=2
+44)  37499787 (100.0%) t@0x2a2020   pss=24 (size=48)  padding=0  num_aliases=2
              source_path= 	object_path=
              flags={}  name=aliasedWithOutlinedFunction
                   full_name=aliasedWithOutlinedFunction()
-47)  77769551 (100.0%) b@0x0        pss=262144  padding=0  num_aliases=1
+45)  37499787 (100.0%) b@0x0        pss=262144  padding=0  num_aliases=1
              source_path=third_party/fft_float.cc 	object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_float.o
              flags={}  name=ff_cos_131072
-48)  77769551 (100.0%) b@0x0        pss=131072  padding=0  num_aliases=1
+46)  37499787 (100.0%) b@0x0        pss=131072  padding=0  num_aliases=1
              source_path=third_party/fft_fixed.cc 	object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_fixed.o
              flags={}  name=ff_cos_131072_fixed
-49)  77769551 (100.0%) b@0x0        pss=131072  padding=0  num_aliases=1
+47)  37499787 (100.0%) b@0x0        pss=131072  padding=0  num_aliases=1
              source_path=third_party/fft_float.cc 	object_path=third_party/ffmpeg/libffmpeg_internal.a/fft_float.o
              flags={}  name=ff_cos_65536
-50)  77769551 (100.0%) b@0x2dffda0  pss=28  padding=0  num_aliases=1
+48)  37499787 (100.0%) b@0x2dffda0  pss=28  padding=0  num_aliases=1
              source_path=third_party/icu/ucnv_ext.c 	object_path=third_party/icu/icuuc/ucnv_ext.o
              flags={gen}  name=g_chrome_content_browser_client
-51)  77769551 (100.0%) b@0x2dffe80  pss=200  padding=196  num_aliases=1
+49)  37499787 (100.0%) b@0x2dffe80  pss=200  padding=196  num_aliases=1
              source_path=third_party/icu/ucnv_ext.c 	object_path=third_party/icu/icuuc/ucnv_ext.o
              flags={gen}  name=SaveHistogram::atomic_histogram_pointer
                   full_name=SaveHistogram(_JNIEnv*, base::android::JavaParamRef<_jobject*> const&, base::android::JavaParamRef<_jstring*> const&, base::android::JavaParamRef<_jlongArray*> const&, int)::atomic_histogram_pointer
-52)  77769551 (100.0%) b@0x2dffe84  pss=4  padding=0  num_aliases=1
+50)  37499787 (100.0%) b@0x2dffe84  pss=4  padding=0  num_aliases=1
              source_path=third_party/icu/ucnv_ext.c 	object_path=third_party/icu/icuuc/ucnv_ext.o
              flags={anon,gen}  name=g_AnimationFrameTimeHistogram_clazz
diff --git a/tools/binary_size/libsupersize/testdata/SymbolGroupMethods.golden b/tools/binary_size/libsupersize/testdata/SymbolGroupMethods.golden
index 0753836..d3042b2 100644
--- a/tools/binary_size/libsupersize/testdata/SymbolGroupMethods.golden
+++ b/tools/binary_size/libsupersize/testdata/SymbolGroupMethods.golden
@@ -1,11 +1,11 @@
 GroupedByName()
-Showing 46 symbols (46 unique) with total pss: 77769551 bytes
+Showing 46 symbols (46 unique) with total pss: 37499787 bytes
 Histogram of symbols based on PSS:
-      {0}: 6    [8,16): 3     [64,128): 2        [2048,4096): 1     [1048576,2097152): 2
-    [2,4): 2   [16,32): 11   [128,256): 1     [65536,131072): 1   [33554432,67108864): 2
-    [4,8): 5   [32,64): 7    [256,512): 1   [524288,1048576): 2
-Sizes: .text=34.2mb     .rodata=5.65mb     .data.rel.ro=1.02mb     .data=99.4kb     .bss=512kb      .other=32.4mb     total=74.2mb
-Counts: .text=22 .rodata=12 .data.rel.ro=4 .data=6 .bss=6 .other=1
+      {0}: 6    [8,16): 3     [64,128): 2      [2048,4096): 1      [524288,1048576): 2
+    [2,4): 3   [16,32): 11   [128,256): 1     [8192,16384): 1     [1048576,2097152): 1
+    [4,8): 5   [32,64): 7    [256,512): 1   [65536,131072): 1   [33554432,67108864): 1
+Sizes: .text=81.8kb     .rodata=2.52mb     .data.rel.ro=92 bytes   .data=168 bytes  .bss=512kb      .other=32.4mb     total=35.8mb
+Counts: .text=21 .rodata=11 .data.rel.ro=3 .data=5 .bss=6 .other=1
 Number of unique paths: 9
 
 Section Legend: t=.text, r=.rodata, R=.data.rel.ro, d=.data, b=.bss, o=.other
@@ -16,55 +16,55 @@
 2)        160 (0.0%)  *@Group      152             base::android::kBaseRegisteredMethods (count=1)
 3)        164 (0.0%)  *@Group      4               base::android::g_renderer_histogram_code (count=1)
 4)        168 (0.0%)  *@Group      4               base::android::g_library_version_number (count=1)
-5)    1166900 (1.5%)  *@Group      1166732         ** symbol gap 0 (end of section) (count=2)
-6)    1166956 (1.5%)  *@Group      56              ChromeMainDelegateAndroid [vtable] (count=1)
-7)    1166980 (1.5%)  *@Group      24              mojo::MessageReceiver [vtable] (count=1)
-8)    1166992 (1.5%)  *@Group      12              kMethodsAnimationFrameTimeHistogram (count=1)
-9)    1167048 (1.5%)  *@Group      56              ChromeMainDelegate [vtable] (count=1)
-10)   1167072 (1.5%)  *@Group      24              chrome::mojom::FieldTrialRecorder [vtable] (count=1)
-11)   1956976 (2.5%)  *@Group      789904          chrome::mojom::FieldTrialRecorderProxy [vtable] (count=1)
-12)   1957008 (2.5%)  *@Group      32              .Lswitch.table.45 (count=1)
-13)   1957016 (2.5%)  *@Group      8               kSystemClassPrefixes (count=1)
-14)  35941187 (46.2%) *@Group      33984171        Overhead: ELF file (count=1)
-15)  35941208 (46.2%) *@Group      21              string literal (count=3)
-16)  35941251 (46.2%) *@Group      43              ** merge strings (count=1)
-17)  37906596 (48.7%) *@Group      1965345         ** merge constants (count=1)
-18)  77019389 (99.0%) *@Group      39112793        ** symbol gaps (count=2)
-19)  77019397 (99.0%) *@Group      8                (count=1)
-20)  77019441 (99.0%) *@Group      44              Name (count=1)
-21)  77019473 (99.0%) *@Group      32              chrome::mojom::FilePatcher::Name_ (count=1)
-22)  77695513 (99.9%) *@Group      676040          kAnimationFrameTimeHistogramClassPath (count=1)
-23)  77695517 (99.9%) *@Group      4               blink::CSSValueKeywordsHash::findValueImpl::value_word_list (count=1)
-24)  77695533 (99.9%) *@Group      16              _GLOBAL__sub_I_page_allocator.cc (count=1)
-25)  77695589 (99.9%) *@Group      56              _GLOBAL__sub_I_bbr_sender.cc (count=1)
-26)  77695617 (99.9%) *@Group      28              _GLOBAL__sub_I_pacing_sender.cc (count=1)
-27)  77695687 (99.9%) *@Group      70              extFromUUseMapping (count=2)
-28)  77696135 (99.9%) *@Group      448             ucnv_extMatchFromU (count=1)
-29)  77696163 (99.9%) *@Group      28              _GLOBAL__sub_I_SkDeviceProfile.cpp (count=1)
-30)  77765287 (100.0%) *@Group      69124           foo_bar (count=1)
-31)  77765311 (100.0%) *@Group      24              BazAlias (count=1)
-32)  77765341 (100.0%) *@Group      30              blink::ContiguousContainerBase::shrinkToFit (count=3)
-33)  77765344 (100.0%) *@Group      3               BarAlias (count=1)
-34)  77765347 (100.0%) *@Group      3               FooAlias (count=1)
-35)  77765375 (100.0%) *@Group      28              blink::ContiguousContainerBase::ContiguousContainerBase (count=1)
-36)  77765469 (100.0%) *@Group      94              blink::PaintChunker::releasePaintChunks (count=1)
-37)  77769503 (100.0%) *@Group      4034            ** outlined function (count=1)
-38)  77769527 (100.0%) *@Group      24              ** outlined function * 2 (count=1)
-39)  77769551 (100.0%) *@Group      24              aliasedWithOutlinedFunction (count=1)
-40)  77769551 (100.0%) *@Group      0               ff_cos_131072 (count=1)
-41)  77769551 (100.0%) *@Group      0               ff_cos_131072_fixed (count=1)
-42)  77769551 (100.0%) *@Group      0               ff_cos_65536 (count=1)
-43)  77769551 (100.0%) *@Group      0               g_chrome_content_browser_client (count=1)
-44)  77769551 (100.0%) *@Group      0               SaveHistogram::atomic_histogram_pointer (count=1)
-45)  77769551 (100.0%) *@Group      0               g_AnimationFrameTimeHistogram_clazz (count=1)
+5)        224 (0.0%)  *@Group      56              ChromeMainDelegateAndroid [vtable] (count=1)
+6)        248 (0.0%)  *@Group      24              mojo::MessageReceiver [vtable] (count=1)
+7)        260 (0.0%)  *@Group      12              kMethodsAnimationFrameTimeHistogram (count=1)
+8)        316 (0.0%)  *@Group      56              ChromeMainDelegate [vtable] (count=1)
+9)        340 (0.0%)  *@Group      24              chrome::mojom::FieldTrialRecorder [vtable] (count=1)
+10)    790244 (2.1%)  *@Group      789904          chrome::mojom::FieldTrialRecorderProxy [vtable] (count=1)
+11)    790276 (2.1%)  *@Group      32              .Lswitch.table.45 (count=1)
+12)    790284 (2.1%)  *@Group      8               kSystemClassPrefixes (count=1)
+13)  34774455 (92.7%) *@Group      33984171        Overhead: ELF file (count=1)
+14)  34774476 (92.7%) *@Group      21              string literal (count=3)
+15)  34774519 (92.7%) *@Group      43              ** merge strings (count=1)
+16)  36739864 (98.0%) *@Group      1965345         ** merge constants (count=1)
+17)  36739867 (98.0%) *@Group      3               ** symbol gap 0 (count=1)
+18)  36739875 (98.0%) *@Group      8                (count=1)
+19)  36739919 (98.0%) *@Group      44              Name (count=1)
+20)  36739951 (98.0%) *@Group      32              chrome::mojom::FilePatcher::Name_ (count=1)
+21)  37415991 (99.8%) *@Group      676040          kAnimationFrameTimeHistogramClassPath (count=1)
+22)  37415995 (99.8%) *@Group      4               blink::CSSValueKeywordsHash::findValueImpl::value_word_list (count=1)
+23)  37416011 (99.8%) *@Group      16              _GLOBAL__sub_I_page_allocator.cc (count=1)
+24)  37416067 (99.8%) *@Group      56              _GLOBAL__sub_I_bbr_sender.cc (count=1)
+25)  37416095 (99.8%) *@Group      28              _GLOBAL__sub_I_pacing_sender.cc (count=1)
+26)  37416165 (99.8%) *@Group      70              extFromUUseMapping (count=2)
+27)  37425923 (99.8%) *@Group      9758            ** symbol gaps (count=1)
+28)  37426371 (99.8%) *@Group      448             ucnv_extMatchFromU (count=1)
+29)  37426399 (99.8%) *@Group      28              _GLOBAL__sub_I_SkDeviceProfile.cpp (count=1)
+30)  37495523 (100.0%) *@Group      69124           foo_bar (count=1)
+31)  37495547 (100.0%) *@Group      24              BazAlias (count=1)
+32)  37495577 (100.0%) *@Group      30              blink::ContiguousContainerBase::shrinkToFit (count=3)
+33)  37495580 (100.0%) *@Group      3               BarAlias (count=1)
+34)  37495583 (100.0%) *@Group      3               FooAlias (count=1)
+35)  37495611 (100.0%) *@Group      28              blink::ContiguousContainerBase::ContiguousContainerBase (count=1)
+36)  37495705 (100.0%) *@Group      94              blink::PaintChunker::releasePaintChunks (count=1)
+37)  37499739 (100.0%) *@Group      4034            ** outlined function (count=1)
+38)  37499763 (100.0%) *@Group      24              ** outlined function * 2 (count=1)
+39)  37499787 (100.0%) *@Group      24              aliasedWithOutlinedFunction (count=1)
+40)  37499787 (100.0%) *@Group      0               ff_cos_131072 (count=1)
+41)  37499787 (100.0%) *@Group      0               ff_cos_131072_fixed (count=1)
+42)  37499787 (100.0%) *@Group      0               ff_cos_65536 (count=1)
+43)  37499787 (100.0%) *@Group      0               g_chrome_content_browser_client (count=1)
+44)  37499787 (100.0%) *@Group      0               SaveHistogram::atomic_histogram_pointer (count=1)
+45)  37499787 (100.0%) *@Group      0               g_AnimationFrameTimeHistogram_clazz (count=1)
 GroupedByName(depth=1)
-Showing 38 symbols (38 unique) with total pss: 77769551 bytes
+Showing 38 symbols (38 unique) with total pss: 37499787 bytes
 Histogram of symbols based on PSS:
-       {0}: 6    [16,32): 8     [128,256): 2      [65536,131072): 1   [33554432,67108864): 2
-     [2,4): 2    [32,64): 6     [256,512): 1    [524288,1048576): 2
-    [8,16): 4   [64,128): 1   [2048,4096): 1   [1048576,2097152): 2
-Sizes: .text=34.2mb     .rodata=5.65mb     .data.rel.ro=1.02mb     .data=99.4kb     .bss=512kb      .other=32.4mb     total=74.2mb
-Counts: .text=22 .rodata=12 .data.rel.ro=4 .data=6 .bss=6 .other=1
+       {0}: 6    [16,32): 8     [128,256): 2       [8192,16384): 1     [1048576,2097152): 1
+     [2,4): 3    [32,64): 6     [256,512): 1     [65536,131072): 1   [33554432,67108864): 1
+    [8,16): 4   [64,128): 1   [2048,4096): 1   [524288,1048576): 2
+Sizes: .text=81.8kb     .rodata=2.52mb     .data.rel.ro=92 bytes   .data=168 bytes  .bss=512kb      .other=32.4mb     total=35.8mb
+Counts: .text=21 .rodata=11 .data.rel.ro=3 .data=5 .bss=6 .other=1
 Number of unique paths: 9
 
 Section Legend: t=.text, r=.rodata, R=.data.rel.ro, d=.data, b=.bss, o=.other
@@ -72,50 +72,50 @@
 ------------------------------------------------------------
 0)          8 (0.0%)  *@Group      8               google (count=2)
 1)        168 (0.0%)  *@Group      160             base (count=3)
-2)    1166900 (1.5%)  *@Group      1166732         ** symbol gap 0 (end of section) (count=2)
-3)    1166956 (1.5%)  *@Group      56              ChromeMainDelegateAndroid [vtable] (count=1)
-4)    1166980 (1.5%)  *@Group      24              mojo (count=1)
-5)    1166992 (1.5%)  *@Group      12              kMethodsAnimationFrameTimeHistogram (count=1)
-6)    1167048 (1.5%)  *@Group      56              ChromeMainDelegate [vtable] (count=1)
-7)    1957008 (2.5%)  *@Group      789960          chrome (count=3)
-8)    1957040 (2.5%)  *@Group      32              .Lswitch.table.45 (count=1)
-9)    1957048 (2.5%)  *@Group      8               kSystemClassPrefixes (count=1)
-10)  35941219 (46.2%) *@Group      33984171        Overhead: ELF file (count=1)
-11)  35941240 (46.2%) *@Group      21              string literal (count=3)
-12)  35941283 (46.2%) *@Group      43              ** merge strings (count=1)
-13)  37906628 (48.7%) *@Group      1965345         ** merge constants (count=1)
-14)  77019421 (99.0%) *@Group      39112793        ** symbol gaps (count=2)
-15)  77019429 (99.0%) *@Group      8                (count=1)
-16)  77019473 (99.0%) *@Group      44              Name (count=1)
-17)  77695513 (99.9%) *@Group      676040          kAnimationFrameTimeHistogramClassPath (count=1)
-18)  77695669 (99.9%) *@Group      156             blink (count=6)
-19)  77695685 (99.9%) *@Group      16              _GLOBAL__sub_I_page_allocator.cc (count=1)
-20)  77695741 (99.9%) *@Group      56              _GLOBAL__sub_I_bbr_sender.cc (count=1)
-21)  77695769 (99.9%) *@Group      28              _GLOBAL__sub_I_pacing_sender.cc (count=1)
-22)  77695839 (99.9%) *@Group      70              extFromUUseMapping (count=2)
-23)  77696287 (99.9%) *@Group      448             ucnv_extMatchFromU (count=1)
-24)  77696315 (99.9%) *@Group      28              _GLOBAL__sub_I_SkDeviceProfile.cpp (count=1)
-25)  77765439 (100.0%) *@Group      69124           foo_bar (count=1)
-26)  77765463 (100.0%) *@Group      24              BazAlias (count=1)
-27)  77765466 (100.0%) *@Group      3               BarAlias (count=1)
-28)  77765469 (100.0%) *@Group      3               FooAlias (count=1)
-29)  77769503 (100.0%) *@Group      4034            ** outlined function (count=1)
-30)  77769527 (100.0%) *@Group      24              ** outlined function * 2 (count=1)
-31)  77769551 (100.0%) *@Group      24              aliasedWithOutlinedFunction (count=1)
-32)  77769551 (100.0%) *@Group      0               ff_cos_131072 (count=1)
-33)  77769551 (100.0%) *@Group      0               ff_cos_131072_fixed (count=1)
-34)  77769551 (100.0%) *@Group      0               ff_cos_65536 (count=1)
-35)  77769551 (100.0%) *@Group      0               g_chrome_content_browser_client (count=1)
-36)  77769551 (100.0%) *@Group      0               SaveHistogram (count=1)
-37)  77769551 (100.0%) *@Group      0               g_AnimationFrameTimeHistogram_clazz (count=1)
+2)        224 (0.0%)  *@Group      56              ChromeMainDelegateAndroid [vtable] (count=1)
+3)        248 (0.0%)  *@Group      24              mojo (count=1)
+4)        260 (0.0%)  *@Group      12              kMethodsAnimationFrameTimeHistogram (count=1)
+5)        316 (0.0%)  *@Group      56              ChromeMainDelegate [vtable] (count=1)
+6)     790276 (2.1%)  *@Group      789960          chrome (count=3)
+7)     790308 (2.1%)  *@Group      32              .Lswitch.table.45 (count=1)
+8)     790316 (2.1%)  *@Group      8               kSystemClassPrefixes (count=1)
+9)   34774487 (92.7%) *@Group      33984171        Overhead: ELF file (count=1)
+10)  34774508 (92.7%) *@Group      21              string literal (count=3)
+11)  34774551 (92.7%) *@Group      43              ** merge strings (count=1)
+12)  36739896 (98.0%) *@Group      1965345         ** merge constants (count=1)
+13)  36739899 (98.0%) *@Group      3               ** symbol gap 0 (count=1)
+14)  36739907 (98.0%) *@Group      8                (count=1)
+15)  36739951 (98.0%) *@Group      44              Name (count=1)
+16)  37415991 (99.8%) *@Group      676040          kAnimationFrameTimeHistogramClassPath (count=1)
+17)  37416147 (99.8%) *@Group      156             blink (count=6)
+18)  37416163 (99.8%) *@Group      16              _GLOBAL__sub_I_page_allocator.cc (count=1)
+19)  37416219 (99.8%) *@Group      56              _GLOBAL__sub_I_bbr_sender.cc (count=1)
+20)  37416247 (99.8%) *@Group      28              _GLOBAL__sub_I_pacing_sender.cc (count=1)
+21)  37416317 (99.8%) *@Group      70              extFromUUseMapping (count=2)
+22)  37426075 (99.8%) *@Group      9758            ** symbol gaps (count=1)
+23)  37426523 (99.8%) *@Group      448             ucnv_extMatchFromU (count=1)
+24)  37426551 (99.8%) *@Group      28              _GLOBAL__sub_I_SkDeviceProfile.cpp (count=1)
+25)  37495675 (100.0%) *@Group      69124           foo_bar (count=1)
+26)  37495699 (100.0%) *@Group      24              BazAlias (count=1)
+27)  37495702 (100.0%) *@Group      3               BarAlias (count=1)
+28)  37495705 (100.0%) *@Group      3               FooAlias (count=1)
+29)  37499739 (100.0%) *@Group      4034            ** outlined function (count=1)
+30)  37499763 (100.0%) *@Group      24              ** outlined function * 2 (count=1)
+31)  37499787 (100.0%) *@Group      24              aliasedWithOutlinedFunction (count=1)
+32)  37499787 (100.0%) *@Group      0               ff_cos_131072 (count=1)
+33)  37499787 (100.0%) *@Group      0               ff_cos_131072_fixed (count=1)
+34)  37499787 (100.0%) *@Group      0               ff_cos_65536 (count=1)
+35)  37499787 (100.0%) *@Group      0               g_chrome_content_browser_client (count=1)
+36)  37499787 (100.0%) *@Group      0               SaveHistogram (count=1)
+37)  37499787 (100.0%) *@Group      0               g_AnimationFrameTimeHistogram_clazz (count=1)
 GroupedByName(depth=-1)
-Showing 41 symbols (41 unique) with total pss: 77769551 bytes
+Showing 41 symbols (41 unique) with total pss: 37499787 bytes
 Histogram of symbols based on PSS:
-      {0}: 6    [8,16): 4    [64,128): 2        [2048,4096): 1     [1048576,2097152): 2
-    [2,4): 2   [16,32): 8   [128,256): 1     [65536,131072): 1   [33554432,67108864): 2
-    [4,8): 1   [32,64): 8   [256,512): 1   [524288,1048576): 2
-Sizes: .text=34.2mb     .rodata=5.65mb     .data.rel.ro=1.02mb     .data=99.4kb     .bss=512kb      .other=32.4mb     total=74.2mb
-Counts: .text=22 .rodata=12 .data.rel.ro=4 .data=6 .bss=6 .other=1
+      {0}: 6    [8,16): 4    [64,128): 2      [2048,4096): 1      [524288,1048576): 2
+    [2,4): 3   [16,32): 8   [128,256): 1     [8192,16384): 1     [1048576,2097152): 1
+    [4,8): 1   [32,64): 8   [256,512): 1   [65536,131072): 1   [33554432,67108864): 1
+Sizes: .text=81.8kb     .rodata=2.52mb     .data.rel.ro=92 bytes   .data=168 bytes  .bss=512kb      .other=32.4mb     total=35.8mb
+Counts: .text=21 .rodata=11 .data.rel.ro=3 .data=5 .bss=6 .other=1
 Number of unique paths: 9
 
 Section Legend: t=.text, r=.rodata, R=.data.rel.ro, d=.data, b=.bss, o=.other
@@ -123,53 +123,53 @@
 ------------------------------------------------------------
 0)          8 (0.0%)  *@Group      8               google::protobuf::internal (count=2)
 1)        168 (0.0%)  *@Group      160             base::android (count=3)
-2)    1166900 (1.5%)  *@Group      1166732         ** symbol gap 0 (end of section) (count=2)
-3)    1166956 (1.5%)  *@Group      56              ChromeMainDelegateAndroid [vtable] (count=1)
-4)    1166980 (1.5%)  *@Group      24              mojo (count=1)
-5)    1166992 (1.5%)  *@Group      12              kMethodsAnimationFrameTimeHistogram (count=1)
-6)    1167048 (1.5%)  *@Group      56              ChromeMainDelegate [vtable] (count=1)
-7)    1956976 (2.5%)  *@Group      789928          chrome::mojom (count=2)
-8)    1957008 (2.5%)  *@Group      32              .Lswitch.table.45 (count=1)
-9)    1957016 (2.5%)  *@Group      8               kSystemClassPrefixes (count=1)
-10)  35941187 (46.2%) *@Group      33984171        Overhead: ELF file (count=1)
-11)  35941208 (46.2%) *@Group      21              string literal (count=3)
-12)  35941251 (46.2%) *@Group      43              ** merge strings (count=1)
-13)  37906596 (48.7%) *@Group      1965345         ** merge constants (count=1)
-14)  77019389 (99.0%) *@Group      39112793        ** symbol gaps (count=2)
-15)  77019397 (99.0%) *@Group      8                (count=1)
-16)  77019441 (99.0%) *@Group      44              Name (count=1)
-17)  77019473 (99.0%) *@Group      32              chrome::mojom::FilePatcher (count=1)
-18)  77695513 (99.9%) *@Group      676040          kAnimationFrameTimeHistogramClassPath (count=1)
-19)  77695517 (99.9%) *@Group      4               blink::CSSValueKeywordsHash::findValueImpl (count=1)
-20)  77695533 (99.9%) *@Group      16              _GLOBAL__sub_I_page_allocator.cc (count=1)
-21)  77695589 (99.9%) *@Group      56              _GLOBAL__sub_I_bbr_sender.cc (count=1)
-22)  77695617 (99.9%) *@Group      28              _GLOBAL__sub_I_pacing_sender.cc (count=1)
-23)  77695687 (99.9%) *@Group      70              extFromUUseMapping (count=2)
-24)  77696135 (99.9%) *@Group      448             ucnv_extMatchFromU (count=1)
-25)  77696163 (99.9%) *@Group      28              _GLOBAL__sub_I_SkDeviceProfile.cpp (count=1)
-26)  77765287 (100.0%) *@Group      69124           foo_bar (count=1)
-27)  77765311 (100.0%) *@Group      24              BazAlias (count=1)
-28)  77765369 (100.0%) *@Group      58              blink::ContiguousContainerBase (count=4)
-29)  77765372 (100.0%) *@Group      3               BarAlias (count=1)
-30)  77765375 (100.0%) *@Group      3               FooAlias (count=1)
-31)  77765469 (100.0%) *@Group      94              blink::PaintChunker (count=1)
-32)  77769503 (100.0%) *@Group      4034            ** outlined function (count=1)
-33)  77769527 (100.0%) *@Group      24              ** outlined function * 2 (count=1)
-34)  77769551 (100.0%) *@Group      24              aliasedWithOutlinedFunction (count=1)
-35)  77769551 (100.0%) *@Group      0               ff_cos_131072 (count=1)
-36)  77769551 (100.0%) *@Group      0               ff_cos_131072_fixed (count=1)
-37)  77769551 (100.0%) *@Group      0               ff_cos_65536 (count=1)
-38)  77769551 (100.0%) *@Group      0               g_chrome_content_browser_client (count=1)
-39)  77769551 (100.0%) *@Group      0               SaveHistogram (count=1)
-40)  77769551 (100.0%) *@Group      0               g_AnimationFrameTimeHistogram_clazz (count=1)
+2)        224 (0.0%)  *@Group      56              ChromeMainDelegateAndroid [vtable] (count=1)
+3)        248 (0.0%)  *@Group      24              mojo (count=1)
+4)        260 (0.0%)  *@Group      12              kMethodsAnimationFrameTimeHistogram (count=1)
+5)        316 (0.0%)  *@Group      56              ChromeMainDelegate [vtable] (count=1)
+6)     790244 (2.1%)  *@Group      789928          chrome::mojom (count=2)
+7)     790276 (2.1%)  *@Group      32              .Lswitch.table.45 (count=1)
+8)     790284 (2.1%)  *@Group      8               kSystemClassPrefixes (count=1)
+9)   34774455 (92.7%) *@Group      33984171        Overhead: ELF file (count=1)
+10)  34774476 (92.7%) *@Group      21              string literal (count=3)
+11)  34774519 (92.7%) *@Group      43              ** merge strings (count=1)
+12)  36739864 (98.0%) *@Group      1965345         ** merge constants (count=1)
+13)  36739867 (98.0%) *@Group      3               ** symbol gap 0 (count=1)
+14)  36739875 (98.0%) *@Group      8                (count=1)
+15)  36739919 (98.0%) *@Group      44              Name (count=1)
+16)  36739951 (98.0%) *@Group      32              chrome::mojom::FilePatcher (count=1)
+17)  37415991 (99.8%) *@Group      676040          kAnimationFrameTimeHistogramClassPath (count=1)
+18)  37415995 (99.8%) *@Group      4               blink::CSSValueKeywordsHash::findValueImpl (count=1)
+19)  37416011 (99.8%) *@Group      16              _GLOBAL__sub_I_page_allocator.cc (count=1)
+20)  37416067 (99.8%) *@Group      56              _GLOBAL__sub_I_bbr_sender.cc (count=1)
+21)  37416095 (99.8%) *@Group      28              _GLOBAL__sub_I_pacing_sender.cc (count=1)
+22)  37416165 (99.8%) *@Group      70              extFromUUseMapping (count=2)
+23)  37425923 (99.8%) *@Group      9758            ** symbol gaps (count=1)
+24)  37426371 (99.8%) *@Group      448             ucnv_extMatchFromU (count=1)
+25)  37426399 (99.8%) *@Group      28              _GLOBAL__sub_I_SkDeviceProfile.cpp (count=1)
+26)  37495523 (100.0%) *@Group      69124           foo_bar (count=1)
+27)  37495547 (100.0%) *@Group      24              BazAlias (count=1)
+28)  37495605 (100.0%) *@Group      58              blink::ContiguousContainerBase (count=4)
+29)  37495608 (100.0%) *@Group      3               BarAlias (count=1)
+30)  37495611 (100.0%) *@Group      3               FooAlias (count=1)
+31)  37495705 (100.0%) *@Group      94              blink::PaintChunker (count=1)
+32)  37499739 (100.0%) *@Group      4034            ** outlined function (count=1)
+33)  37499763 (100.0%) *@Group      24              ** outlined function * 2 (count=1)
+34)  37499787 (100.0%) *@Group      24              aliasedWithOutlinedFunction (count=1)
+35)  37499787 (100.0%) *@Group      0               ff_cos_131072 (count=1)
+36)  37499787 (100.0%) *@Group      0               ff_cos_131072_fixed (count=1)
+37)  37499787 (100.0%) *@Group      0               ff_cos_65536 (count=1)
+38)  37499787 (100.0%) *@Group      0               g_chrome_content_browser_client (count=1)
+39)  37499787 (100.0%) *@Group      0               SaveHistogram (count=1)
+40)  37499787 (100.0%) *@Group      0               g_AnimationFrameTimeHistogram_clazz (count=1)
 GroupedByName(depth=1, min_count=2)
-Showing 38 symbols (36 unique) with total pss: 77769551 bytes
+Showing 38 symbols (36 unique) with total pss: 37499787 bytes
 Histogram of symbols based on PSS:
-     [2,4): 2    [16,32): 9     [128,256): 3    [65536,131072): 1      [524288,1048576): 2
-     [4,8): 1    [32,64): 6     [256,512): 1   [131072,262144): 2     [1048576,2097152): 2
-    [8,16): 4   [64,128): 1   [2048,4096): 1   [262144,524288): 1   [33554432,67108864): 2
-Sizes: .text=34.2mb     .rodata=5.65mb     .data.rel.ro=1.02mb     .data=99.4kb     .bss=512kb      .other=32.4mb     total=74.2mb
-Counts: .text=22 .rodata=12 .data.rel.ro=4 .data=6 .bss=6 .other=1
+     [2,4): 3    [16,32): 9     [128,256): 3      [8192,16384): 1     [262144,524288): 1   [33554432,67108864): 1
+     [4,8): 1    [32,64): 6     [256,512): 1    [65536,131072): 1    [524288,1048576): 2
+    [8,16): 4   [64,128): 1   [2048,4096): 1   [131072,262144): 2   [1048576,2097152): 1
+Sizes: .text=81.8kb     .rodata=2.52mb     .data.rel.ro=92 bytes   .data=168 bytes  .bss=512kb      .other=32.4mb     total=35.8mb
+Counts: .text=21 .rodata=11 .data.rel.ro=3 .data=5 .bss=6 .other=1
 Number of unique paths: 9
 
 Section Legend: t=.text, r=.rodata, R=.data.rel.ro, d=.data, b=.bss, o=.other
@@ -179,74 +179,74 @@
              google (count=2)
 1)        168 (0.0%)  *@Group      160            third_party/container/container.c
              base (count=3)
-2)    1166900 (1.5%)  *@Group      1166732        {no path}
-             ** symbol gap 0 (end of section) (count=2)
-3)    1166956 (1.5%)  R@0x2cd8500  56             third_party/paint.cc
+2)        224 (0.0%)  R@0x2cd8500  56             third_party/paint.cc
              ChromeMainDelegateAndroid [vtable]
-4)    1166980 (1.5%)  R@0x2cd8538  24             base/page_allocator.cc
+3)        248 (0.0%)  R@0x2cd8538  24             base/page_allocator.cc
              mojo::MessageReceiver [vtable]
-5)    1166992 (1.5%)  R@0x2cd8550  12             base/page_allocator.cc
+4)        260 (0.0%)  R@0x2cd8550  12             base/page_allocator.cc
              kMethodsAnimationFrameTimeHistogram
-6)    1167048 (1.5%)  R@0x2c176f0  56             $root_gen_dir/third_party/icu/ucnv_ext.c
+5)        316 (0.0%)  R@0x2c176f0  56             $root_gen_dir/third_party/icu/ucnv_ext.c
              ChromeMainDelegate [vtable]
-7)    1957008 (2.5%)  *@Group      789960         {no path}
+6)     790276 (2.1%)  *@Group      789960         {no path}
              chrome (count=3)
-8)    1957040 (2.5%)  R@0x2cd84e0  32             third_party/gvr-android-sdk/libgvr_shim_static_arm.a/libcontroller_api_impl.a_controller_api_impl.o
+7)     790308 (2.1%)  R@0x2cd84e0  32             third_party/gvr-android-sdk/libgvr_shim_static_arm.a/libcontroller_api_impl.a_controller_api_impl.o
              .Lswitch.table.45
-9)    1957048 (2.5%)  R@0x2cd84f0  8              third_party/gvr-android-sdk/libgvr_shim_static_arm.a/libport_android_jni.a_jni_utils.o
+8)     790316 (2.1%)  R@0x2cd84f0  8              third_party/gvr-android-sdk/libgvr_shim_static_arm.a/libport_android_jni.a_jni_utils.o
              kSystemClassPrefixes
-10)  35941219 (46.2%) o@0x0        33984171       {no path}
+9)   34774487 (92.7%) o@0x0        33984171       {no path}
              Overhead: ELF file
-11)  35941240 (46.2%) *@Group      21             {no path}
+10)  34774508 (92.7%) *@Group      21             {no path}
              string literal (count=3)
-12)  35941283 (46.2%) r@0x266e630  43             {no path}
+11)  34774551 (92.7%) r@0x266e630  43             {no path}
              ** merge strings
-13)  37906628 (48.7%) r@0x284d600  1965345        {no path}
+12)  36739896 (98.0%) r@0x284d600  1965345        {no path}
              ** merge constants
-14)  77019421 (99.0%) *@Group      39112793       {no path}
-             ** symbol gaps (count=2)
-15)  77019429 (99.0%) r@0x284e364  8              base/page_allocator.cc
-16)  77019473 (99.0%) r@0x284e370  44             base/page_allocator.cc
+13)  36739899 (98.0%) r@0x284e364  3              {no path}
+             ** symbol gap 0
+14)  36739907 (98.0%) r@0x284e364  8              base/page_allocator.cc
+15)  36739951 (98.0%) r@0x284e370  44             base/page_allocator.cc
              Name
-17)  77695513 (99.9%) r@0x28f3450  676040         third_party/paint.cc
+16)  37415991 (99.8%) r@0x28f3450  676040         third_party/paint.cc
              kAnimationFrameTimeHistogramClassPath
-18)  77695669 (99.9%) *@Group      156            {no path}
+17)  37416147 (99.8%) *@Group      156            {no path}
              blink (count=6)
-19)  77695685 (99.9%) t@0x28d900   16             base/page_allocator.cc
+18)  37416163 (99.8%) t@0x28d900   16             base/page_allocator.cc
              _GLOBAL__sub_I_page_allocator.cc
-20)  77695741 (99.9%) t@0x28d910   56             base/page_allocator.cc
+19)  37416219 (99.8%) t@0x28d910   56             base/page_allocator.cc
              _GLOBAL__sub_I_bbr_sender.cc
-21)  77695769 (99.9%) t@0x28d948   28             base/page_allocator.cc
+20)  37416247 (99.8%) t@0x28d948   28             base/page_allocator.cc
              _GLOBAL__sub_I_pacing_sender.cc
-22)  77695839 (99.9%) *@Group      70             base/page_allocator.cc
+21)  37416317 (99.8%) *@Group      70             base/page_allocator.cc
              extFromUUseMapping (count=2)
-23)  77696287 (99.9%) t@0x28f000   448            $root_gen_dir/third_party/icu/ucnv_ext.c
+22)  37426075 (99.8%) t@Group      9758           {no path}
+             ** symbol gaps (count=2)
+23)  37426523 (99.8%) t@0x28f000   448            $root_gen_dir/third_party/icu/ucnv_ext.c
              ucnv_extMatchFromU
-24)  77696315 (99.9%) t@0x28f1c8   28             $root_gen_dir/third_party/icu/ucnv_ext.c
+24)  37426551 (99.8%) t@0x28f1c8   28             $root_gen_dir/third_party/icu/ucnv_ext.c
              _GLOBAL__sub_I_SkDeviceProfile.cpp
-25)  77765439 (100.0%) t@0x28f1e0   69124          $root_gen_dir/third_party/icu/ucnv_ext.c
+25)  37495675 (100.0%) t@0x28f1e0   69124          $root_gen_dir/third_party/icu/ucnv_ext.c
              foo_bar
-26)  77765463 (100.0%) t@0x2a0000   24 (size=48)   $root_gen_dir/third_party/icu/ucnv_ext.c
+26)  37495699 (100.0%) t@0x2a0000   24 (size=48)   $root_gen_dir/third_party/icu/ucnv_ext.c
              BazAlias (num_aliases=2)
-27)  77765466 (100.0%) t@0x2a0010   3 (size=12)    third_party/fft_float.cc
+27)  37495702 (100.0%) t@0x2a0010   3 (size=12)    third_party/fft_float.cc
              BarAlias (num_aliases=4)
-28)  77765469 (100.0%) t@0x2a0010   3 (size=12)    third_party/fft_float.cc
+28)  37495705 (100.0%) t@0x2a0010   3 (size=12)    third_party/fft_float.cc
              FooAlias (num_aliases=4)
-29)  77769503 (100.0%) t@0x2a2000   4034           third_party/container/container.c
+29)  37499739 (100.0%) t@0x2a2000   4034           third_party/container/container.c
              ** outlined function
-30)  77769527 (100.0%) t@0x2a2020   24 (size=48)   {no path}
+30)  37499763 (100.0%) t@0x2a2020   24 (size=48)   {no path}
              ** outlined function * 2 (num_aliases=2)
-31)  77769551 (100.0%) t@0x2a2020   24 (size=48)   {no path}
+31)  37499787 (100.0%) t@0x2a2020   24 (size=48)   {no path}
              aliasedWithOutlinedFunction (num_aliases=2)
-32)  77769551 (100.0%) b@0x0        262144         third_party/fft_float.cc
+32)  37499787 (100.0%) b@0x0        262144         third_party/fft_float.cc
              ff_cos_131072
-33)  77769551 (100.0%) b@0x0        131072         third_party/fft_fixed.cc
+33)  37499787 (100.0%) b@0x0        131072         third_party/fft_fixed.cc
              ff_cos_131072_fixed
-34)  77769551 (100.0%) b@0x0        131072         third_party/fft_float.cc
+34)  37499787 (100.0%) b@0x0        131072         third_party/fft_float.cc
              ff_cos_65536
-35)  77769551 (100.0%) b@0x2dffda0  28             $root_gen_dir/third_party/icu/ucnv_ext.c
+35)  37499787 (100.0%) b@0x2dffda0  28             $root_gen_dir/third_party/icu/ucnv_ext.c
              g_chrome_content_browser_client
-36)  77769551 (100.0%) b@0x2dffe80  200            $root_gen_dir/third_party/icu/ucnv_ext.c
+36)  37499787 (100.0%) b@0x2dffe80  200            $root_gen_dir/third_party/icu/ucnv_ext.c
              SaveHistogram::atomic_histogram_pointer
-37)  77769551 (100.0%) b@0x2dffe84  4              $root_gen_dir/third_party/icu/ucnv_ext.c
+37)  37499787 (100.0%) b@0x2dffe84  4              $root_gen_dir/third_party/icu/ucnv_ext.c
              g_AnimationFrameTimeHistogram_clazz
diff --git a/tools/binary_size/libsupersize/testdata/linker_map_parser/Parser.golden b/tools/binary_size/libsupersize/testdata/linker_map_parser/Parser.golden
index e92aad3..0b95b3c 100644
--- a/tools/binary_size/libsupersize/testdata/linker_map_parser/Parser.golden
+++ b/tools/binary_size/libsupersize/testdata/linker_map_parser/Parser.golden
@@ -66,7 +66,7 @@
 .rodata@213420(size_without_padding=29,padding=0,full_name=typeinfo name for std::__ndk1::ios_base::failure,object_path=../../third_party/android_ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_static.a(ios.o),source_path=,flags={},num_aliases=1,component=)
 .rodata@213440(size_without_padding=21,padding=0,full_name=typeinfo name for std::__ndk1::ios_base,object_path=../../third_party/android_ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_static.a(ios.o),source_path=,flags={},num_aliases=1,component=)
 .rodata@213460(size_without_padding=33,padding=0,full_name=typeinfo name for std::__ndk1::__iostream_category,object_path=../../third_party/android_ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_static.a(ios.o),source_path=,flags={},num_aliases=1,component=)
-.rodata@213490(size_without_padding=45,padding=0,full_name=,object_path=../../third_party/android_ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_static.a(ios.o),source_path=,flags={},num_aliases=1,component=)
+.rodata@213490(size_without_padding=45,padding=0,full_name=_ZTSNSt6__ndk19basic_iosIcNS_11char_traitsIcEEEE,object_path=../../third_party/android_ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_static.a(ios.o),source_path=,flags={},num_aliases=1,component=)
 .rodata@21368b(size_without_padding=2897806,padding=0,full_name=** lld merge strings,object_path=,source_path=,flags={},num_aliases=1,component=)
 .rodata@4d6e20(size_without_padding=27,padding=0,full_name=typeinfo name for std::__ndk1::__stdinbuf<wchar_t>,object_path=../../third_party/android_ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_static.a(iostream.o),source_path=,flags={},num_aliases=1,component=)
 .rodata@4d7920(size_without_padding=9836,padding=0,full_name=** lld merge strings,object_path=,source_path=,flags={},num_aliases=1,component=)
@@ -104,6 +104,8 @@
 .text@97c834(size_without_padding=1244,padding=0,full_name=vpx_convolve8_avg_horiz_filter_type1_neon,object_path=obj/third_party/libvpx/libvpx_assembly_arm.a(libvpx_assembly_arm/vpx_convolve8_avg_horiz_filter_type1_neon.asm.o),source_path=,flags={},num_aliases=1,component=)
 .text@99cad8(size_without_padding=252,padding=0,full_name=sinh,object_path=../../third_party/android_ndk/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libandroid_support.a(e_sinh.o),source_path=,flags={},num_aliases=1,component=)
 .text@1401788(size_without_padding=164,padding=0,full_name=$_21::operator()(FamilyData*, char const*, char const**) const,object_path=,source_path=,flags={},num_aliases=1,component=)
+.text@1401820(size_without_padding=16,padding=0,full_name=UnlikelyFunc,object_path=,source_path=,flags={unlikely},num_aliases=1,component=)
+.text@1401850(size_without_padding=16,padding=0,full_name=StartUpFunc,object_path=,source_path=,flags={startup},num_aliases=1,component=)
 .data@2d4c000(size_without_padding=4,padding=0,full_name=v8_Default_embedded_blob_,object_path=obj/v8/v8_external_snapshot/embedded.o,source_path=,flags={},num_aliases=1,component=)
 .data@2d4c004(size_without_padding=4,padding=0,full_name=__dso_handle,object_path=../../third_party/android_ndk/platforms/android-16/arch-arm/usr/lib/crtbegin_so.o,source_path=,flags={},num_aliases=1,component=)
 .data.rel.ro@2d69000(size_without_padding=60,padding=0,full_name=fft_tab_vfp,object_path=obj/third_party/ffmpeg/libffmpeg_internal.a(ffmpeg_internal/fft_vfp.o),source_path=,flags={},num_aliases=1,component=)
diff --git a/tools/binary_size/libsupersize/testdata/linker_map_parser/Tokenize.golden b/tools/binary_size/libsupersize/testdata/linker_map_parser/Tokenize.golden
index 68545513..e9e5225 100644
--- a/tools/binary_size/libsupersize/testdata/linker_map_parser/Tokenize.golden
+++ b/tools/binary_size/libsupersize/testdata/linker_map_parser/Tokenize.golden
@@ -156,6 +156,11 @@
   99CAD8       FC (3)       FC sinh
  1401788       A4 (2) -------- thinlto-cache/Thin-826b9f.tmp.o:(.text._ZNK4$_21clEP10FamilyDataPKcPS3_)
  1401788       A4 (3)       A4 $_21::operator()(FamilyData*, char const*, char const**) const
+ 1401820       10 (2) -------- thinlto-cache/Thin-826b9f.tmp.o:(.text.unlikely.UnlikelyFunc)
+ 1401820       10 (3)       10 UnlikelyFunc
+ 1401830       10 (3)        0 UnlikelyFunc2
+ 1401850       10 (2) -------- thinlto-cache/Thin-826b9f.tmp.o:(.text.startup)
+ 1401850       10 (3)       10 StartUpFunc
  2D4A7F0     17D0 (1) -------- .plt
  2D4A7F0     17D0 (2) -------- <internal>:(.plt)
  2D4C000    1CFC8 (1) -------- .data
diff --git a/tools/binary_size/libsupersize/testdata/linker_map_parser/test_lld-lto_v1.map b/tools/binary_size/libsupersize/testdata/linker_map_parser/test_lld-lto_v1.map
index cb22f61b..b7f1b937 100644
--- a/tools/binary_size/libsupersize/testdata/linker_map_parser/test_lld-lto_v1.map
+++ b/tools/binary_size/libsupersize/testdata/linker_map_parser/test_lld-lto_v1.map
@@ -254,6 +254,19 @@
  1401789  1401789       a4     1                 $_21::operator()(FamilyData*, char const*, char const**) const
  1401818  1401818        0     1                 $d.79
 
+# Sections prefixed with ".unlikely" or ".hot"
+ 1401820  1401820       10     4         thinlto-cache/Thin-826b9f.tmp.o:(.text.unlikely.UnlikelyFunc)
+ 1401820  1401820        0     1                 $t.78
+ 1401821  1401821       10     1                 UnlikelyFunc
+ 1401831  1401831       10     1                 UnlikelyFunc2
+ 1401841  1401841        0     1                 $d.79
+
+# Sections prefixed with ".startup"
+ 1401850  1401850       10     4         thinlto-cache/Thin-826b9f.tmp.o:(.text.startup)
+ 1401850  1401850        0     1                 $t.78
+ 1401851  1401851       10     1                 StartUpFunc
+ 1401861  1401861        0     1                 $d.79
+
 # Size-only sections.
  2d4a7f0  2d4a7f0     17d0    16 .plt
  2d4a7f0  2d4a7f0     17d0    16         <internal>:(.plt)
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 7bac342..866f1024 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -22186,6 +22186,7 @@
   <int value="2828" label="FlexboxWithOverflowFlexItemIntrinsicSize"/>
   <int value="2829" label="CSSSelectorHostContextInSnapshotProfile"/>
   <int value="2830" label="CSSSelectorHostContextInLiveProfile"/>
+  <int value="2831" label="ImportMap"/>
 </enum>
 
 <enum name="FeaturePolicyFeature">
@@ -32910,6 +32911,7 @@
   <int value="348115702" label="new-password-form-parsing-for-saving:enabled"/>
   <int value="348854923" label="v8-cache-strategies-for-cache-storage"/>
   <int value="350399958" label="ModuleScriptsImportMetaUrl:disabled"/>
+  <int value="350616049" label="IntentPicker:disabled"/>
   <int value="351005753" label="enable-experimental-accessibility-autoclick"/>
   <int value="352191859" label="disabled-new-style-notification"/>
   <int value="352937987" label="OverflowIconsForMediaControls:disabled"/>
@@ -33958,6 +33960,7 @@
   <int value="2039276757" label="EnableOverviewRoundedCorners:enabled"/>
   <int value="2040316611" label="IPH_ReopenTab:enabled"/>
   <int value="2043321329" label="OfflinePagesPrefetchingUI:disabled"/>
+  <int value="2047981703" label="IntentPicker:enabled"/>
   <int value="2056572020" label="EnableUsernameCorrection:disabled"/>
   <int value="2058148069" label="UseMessagesStagingUrl:enabled"/>
   <int value="2058283872" label="CCTModuleCache:disabled"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 248a32e1..1c9ea4c0 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -53251,55 +53251,145 @@
 
 <histogram
     name="Memory.Experimental.OomIntervention.ReducedBlinkUsageAfter10secs"
-    units="MB">
+    units="MB" expires_after="2019-5-31">
+  <obsolete>
+    Replaced by ReducedBlinkUsageAfter10secs2 in 03/2019.
+  </obsolete>
   <owner>yuzus@chromium.org</owner>
   <summary>
-    Reduced amount of blink usage after 10 seconds of intervention.
+    Reduced amount of blink usage after 10 seconds of intervention. This reports
+    negative numbers when reduced.
+  </summary>
+</histogram>
+
+<histogram
+    name="Memory.Experimental.OomIntervention.ReducedBlinkUsageAfter10secs2"
+    units="MB" expires_after="2019-7-31">
+  <owner>yuzus@chromium.org</owner>
+  <owner>keishi@chromium.org</owner>
+  <summary>
+    Reduced amount of blink usage after 10 seconds of intervention. This reports
+    positive numbers when reduced.
   </summary>
 </histogram>
 
 <histogram
     name="Memory.Experimental.OomIntervention.ReducedBlinkUsageAfter20secs"
-    units="MB">
+    units="MB" expires_after="2019-5-31">
+  <obsolete>
+    Replaced by ReducedBlinkUsageAfter20secs2 in 03/2019.
+  </obsolete>
   <owner>yuzus@chromium.org</owner>
   <summary>
-    Reduced amount of blink usage after 20 seconds of intervention.
+    Reduced amount of blink usage after 20 seconds of intervention. This reports
+    negative numbers when reduced.
+  </summary>
+</histogram>
+
+<histogram
+    name="Memory.Experimental.OomIntervention.ReducedBlinkUsageAfter20secs2"
+    units="MB" expires_after="2019-7-31">
+  <owner>yuzus@chromium.org</owner>
+  <owner>keishi@chromium.org</owner>
+  <summary>
+    Reduced amount of blink usage after 20 seconds of intervention. This reports
+    positive numbers when reduced.
   </summary>
 </histogram>
 
 <histogram
     name="Memory.Experimental.OomIntervention.ReducedBlinkUsageAfter30secs"
-    units="MB">
+    units="MB" expires_after="2019-5-31">
+  <obsolete>
+    Replaced by ReducedBlinkUsageAfter30secs2 in 03/2019.
+  </obsolete>
   <owner>yuzus@chromium.org</owner>
   <summary>
-    Reduced amount of blink usage after 30 seconds of intervention.
+    Reduced amount of blink usage after 30 seconds of intervention. This reports
+    negative numbers when reduced.
+  </summary>
+</histogram>
+
+<histogram
+    name="Memory.Experimental.OomIntervention.ReducedBlinkUsageAfter30secs2"
+    units="MB" expires_after="2019-7-31">
+  <owner>yuzus@chromium.org</owner>
+  <owner>keishi@chromium.org</owner>
+  <summary>
+    Reduced amount of blink usage after 30 seconds of intervention. This reports
+    positive numbers when reduced.
   </summary>
 </histogram>
 
 <histogram
     name="Memory.Experimental.OomIntervention.ReducedRendererPMFAfter10secs"
-    units="MB">
+    units="MB" expires_after="2019-5-31">
+  <obsolete>
+    Replaced by ReducedRendererPMFAfter10secs2 in 03/2019.
+  </obsolete>
   <owner>yuzus@chromium.org</owner>
   <summary>
-    Reduced amount of renderer pmf after 10 seconds of intervention.
+    Reduced amount of renderer pmf after 10 seconds of intervention. This
+    reports negative numbers when reduced.
+  </summary>
+</histogram>
+
+<histogram
+    name="Memory.Experimental.OomIntervention.ReducedRendererPMFAfter10secs2"
+    units="MB" expires_after="2019-7-31">
+  <owner>yuzus@chromium.org</owner>
+  <owner>keishi@chromium.org</owner>
+  <summary>
+    Reduced amount of renderer pmf after 10 seconds of intervention. This
+    reports positive numbers when reduced.
   </summary>
 </histogram>
 
 <histogram
     name="Memory.Experimental.OomIntervention.ReducedRendererPMFAfter20secs"
-    units="MB">
+    units="MB" expires_after="2019-5-31">
+  <obsolete>
+    Replaced by ReducedRendererPMFAfter20secs2 in 03/2019.
+  </obsolete>
   <owner>yuzus@chromium.org</owner>
   <summary>
-    Reduced amount of renderer pmf after 20 seconds of intervention.
+    Reduced amount of renderer pmf after 20 seconds of intervention. This
+    reports negative numbers when reduced.
+  </summary>
+</histogram>
+
+<histogram
+    name="Memory.Experimental.OomIntervention.ReducedRendererPMFAfter20secs2"
+    units="MB" expires_after="2019-7-31">
+  <owner>yuzus@chromium.org</owner>
+  <owner>keishi@chromium.org</owner>
+  <summary>
+    Reduced amount of renderer pmf after 20 seconds of intervention. This
+    reports positive numbers when reduced.
   </summary>
 </histogram>
 
 <histogram
     name="Memory.Experimental.OomIntervention.ReducedRendererPMFAfter30secs"
-    units="MB">
+    units="MB" expires_after="2019-5-31">
+  <obsolete>
+    Replaced by ReducedRendererPMFAfter30secs2 in 03/2019.
+  </obsolete>
   <owner>yuzus@chromium.org</owner>
   <summary>
-    Reduced amount of renderer pmf after 30 seconds of intervention.
+    Reduced amount of renderer pmf after 30 seconds of intervention. This
+    reports negative numbers when reduced.
+  </summary>
+</histogram>
+
+<histogram
+    name="Memory.Experimental.OomIntervention.ReducedRendererPMFAfter30secs2"
+    units="MB" expires_after="2019-7-31">
+  <owner>yuzus@chromium.org</owner>
+  <owner>keishi@chromium.org</owner>
+  <summary>
+    Reduced amount of renderer pmf after 30 seconds of intervention. This
+    reports positive numbers when reduced.
   </summary>
 </histogram>
 
@@ -59328,6 +59418,25 @@
   </summary>
 </histogram>
 
+<histogram name="Net.Certificate.ClientCertDialogCount.Android" units="dialogs"
+    expires_after="2020-03-14">
+  <owner>dmcardle@chromium.org</owner>
+  <owner>davidben@chromium.org</owner>
+  <summary>
+    As of 03/2019, abusive sites can create a nuisance for Android users by
+    repeatedly displaying client certificate request dialogs. This histogram
+    records how many client certificate request dialogs were displayed to the
+    user. At first, we would like to get a handle on the number of request
+    dialogs displayed by sites in the wild. Once we have sufficient data, we
+    will impose some limits to prevent abuse without breaking legitimate sites.
+
+    This metric is emitted whenever a new main frame navigation commits and
+    whenever a WebContents is destroyed.
+
+    https://crbug.com/817208
+  </summary>
+</histogram>
+
 <histogram name="Net.Certificate.IgnoreCertificateErrorsSPKIListPresent"
     enum="BooleanPresent">
   <owner>martinkr@google.com</owner>
@@ -78938,6 +79047,30 @@
 </histogram>
 
 <histogram
+    name="PageLoad.Clients.AMP.Experimental.LayoutStability.JankScore.Subframe"
+    units="scorex10" expires_after="2019-09-10">
+  <owner>bmcquade@chromium.org</owner>
+  <owner>skobes@chromium.org</owner>
+  <summary>
+    Measures the amount of layout jank (bit.ly/lsm-explainer) that has occurred
+    during the session, in the AMP subframe. Recorded for same-document
+    navigations.
+  </summary>
+</histogram>
+
+<histogram
+    name="PageLoad.Clients.AMP.Experimental.LayoutStability.JankScore.Subframe.FullNavigation"
+    units="scorex10" expires_after="2019-09-10">
+  <owner>bmcquade@chromium.org</owner>
+  <owner>skobes@chromium.org</owner>
+  <summary>
+    Measures the amount of layout jank (bit.ly/lsm-explainer) that has occurred
+    during the session, in the AMP subframe. Recorded for non-same-document
+    navigations.
+  </summary>
+</histogram>
+
+<histogram
     name="PageLoad.Clients.AMP.Experimental.PageTiming.InputToNavigation.Subframe"
     units="ms">
   <owner>bmcquade@chromium.org</owner>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml
index e4af7791..89d4f0f 100644
--- a/tools/metrics/ukm/ukm.xml
+++ b/tools/metrics/ukm/ukm.xml
@@ -144,6 +144,12 @@
       https://goo.gl/tr1oTZ for a detailed explanation. In milliseconds.
     </summary>
   </metric>
+  <metric name="SubFrame.LayoutStability.JankScore">
+    <summary>
+      Measures the amount of layout jank (bit.ly/lsm-explainer) that has
+      occurred during the session, in the AMP subframe.
+    </summary>
+  </metric>
   <metric name="SubFrame.MainFrameToSubFrameNavigationDelta">
     <summary>
       Measures the time in milliseconds from the navigation in the main frame to
diff --git a/tools/traffic_annotation/scripts/update_annotations_sheet.py b/tools/traffic_annotation/scripts/update_annotations_sheet.py
index 07787dc..9fdb104d 100755
--- a/tools/traffic_annotation/scripts/update_annotations_sheet.py
+++ b/tools/traffic_annotation/scripts/update_annotations_sheet.py
@@ -233,7 +233,8 @@
         print("Added: %s" %id)
 
     empty_row = [''] * len(file_contents[0])
-    row = 0
+    # Skip first row (it's the header row).
+    row = 1
     while row < len(sheet_contents):
       row_id = sheet_contents[row][0]
       # If a row is removed, remove it from previous sheet.
diff --git a/ui/accessibility/ax_enum_util.cc b/ui/accessibility/ax_enum_util.cc
index fd28627..c72588d 100644
--- a/ui/accessibility/ax_enum_util.cc
+++ b/ui/accessibility/ax_enum_util.cc
@@ -30,6 +30,8 @@
       return "documentSelectionChanged";
     case ax::mojom::Event::kDocumentTitleChanged:
       return "documentTitleChanged";
+    case ax::mojom::Event::kEndOfTest:
+      return "endOfTest";
     case ax::mojom::Event::kExpandedChanged:
       return "expandedChanged";
     case ax::mojom::Event::kFocus:
@@ -148,6 +150,8 @@
     return ax::mojom::Event::kDocumentSelectionChanged;
   if (0 == strcmp(event, "documentTitleChanged"))
     return ax::mojom::Event::kDocumentTitleChanged;
+  if (0 == strcmp(event, "endOfTest"))
+    return ax::mojom::Event::kEndOfTest;
   if (0 == strcmp(event, "expandedChanged"))
     return ax::mojom::Event::kExpandedChanged;
   if (0 == strcmp(event, "focus"))
@@ -1101,6 +1105,8 @@
       return "getTextLocation";
     case ax::mojom::Action::kAnnotatePageImages:
       return "annotatePageImages";
+    case ax::mojom::Action::kSignalEndOfTest:
+      return "signalEndOfTest";
   }
 
   return "";
@@ -1163,6 +1169,8 @@
     return ax::mojom::Action::kSetValue;
   if (0 == strcmp(action, "showContextMenu"))
     return ax::mojom::Action::kShowContextMenu;
+  if (0 == strcmp(action, "signalEndOfTest"))
+    return ax::mojom::Action::kSignalEndOfTest;
   return ax::mojom::Action::kNone;
 }
 
diff --git a/ui/accessibility/ax_enums.mojom b/ui/accessibility/ax_enums.mojom
index 9ca117e6..1de320b 100644
--- a/ui/accessibility/ax_enums.mojom
+++ b/ui/accessibility/ax_enums.mojom
@@ -37,6 +37,7 @@
   kClicked,
   kDocumentSelectionChanged,
   kDocumentTitleChanged,
+  kEndOfTest,                 // Sentinel value indicating the end of a test
   kExpandedChanged,           // Web
   kFocus,
   kFocusContext,              // Contextual focus event that must delay the next focus event
@@ -398,6 +399,9 @@
    // reset the selection, if applicable.
   kSetValue,
   kShowContextMenu,
+
+   // Send an event signaling the end of a test.
+  kSignalEndOfTest,
 };
 
 enum ActionFlags {
diff --git a/ui/accessibility/ax_event_generator.cc b/ui/accessibility/ax_event_generator.cc
index 371919a..f438f880 100644
--- a/ui/accessibility/ax_event_generator.cc
+++ b/ui/accessibility/ax_event_generator.cc
@@ -361,7 +361,7 @@
     if ((change.type == NODE_CREATED || change.type == SUBTREE_CREATED)) {
       if (change.node->data().HasStringAttribute(
               ax::mojom::StringAttribute::kLiveStatus)) {
-        if (change.node->data().role == ax::mojom::Role::kAlert)
+        if (ui::IsAlert(change.node->data().role))
           AddEvent(change.node, Event::ALERT);
         else if (change.node->data().GetStringAttribute(
                      ax::mojom::StringAttribute::kLiveStatus) != "off")
diff --git a/ui/accessibility/ax_node_data.cc b/ui/accessibility/ax_node_data.cc
index cdb2f5f..d490ddb 100644
--- a/ui/accessibility/ax_node_data.cc
+++ b/ui/accessibility/ax_node_data.cc
@@ -651,6 +651,7 @@
     case ax::mojom::Action::kScrollRight:
     case ax::mojom::Action::kGetTextLocation:
     case ax::mojom::Action::kAnnotatePageImages:
+    case ax::mojom::Action::kSignalEndOfTest:
       break;
   }
 
diff --git a/ui/accessibility/ax_role_properties.cc b/ui/accessibility/ax_role_properties.cc
index bc3f219a..c033708 100644
--- a/ui/accessibility/ax_role_properties.cc
+++ b/ui/accessibility/ax_role_properties.cc
@@ -18,6 +18,16 @@
 
 }  // namespace
 
+bool IsAlert(const ax::mojom::Role role) {
+  switch (role) {
+    case ax::mojom::Role::kAlert:
+    case ax::mojom::Role::kAlertDialog:
+      return true;
+    default:
+      return false;
+  }
+}
+
 bool IsClickable(const ax::mojom::Role role) {
   switch (role) {
     case ax::mojom::Role::kButton:
diff --git a/ui/accessibility/ax_role_properties.h b/ui/accessibility/ax_role_properties.h
index 4c0e660e7..f1c22728 100644
--- a/ui/accessibility/ax_role_properties.h
+++ b/ui/accessibility/ax_role_properties.h
@@ -15,6 +15,9 @@
 //
 // Please keep these functions in alphabetic order.
 
+// Checks if the given role is an alert or alert-dialog type.
+AX_EXPORT bool IsAlert(const ax::mojom::Role role);
+
 // Checks if the given role should belong to a control that can respond to
 // clicks.
 AX_EXPORT bool IsClickable(const ax::mojom::Role role);
diff --git a/ui/file_manager/file_manager/foreground/js/BUILD.gn b/ui/file_manager/file_manager/foreground/js/BUILD.gn
index cabae49..4209133 100644
--- a/ui/file_manager/file_manager/foreground/js/BUILD.gn
+++ b/ui/file_manager/file_manager/foreground/js/BUILD.gn
@@ -442,7 +442,6 @@
     ":file_manager_commands",
     "../elements:files_toggle_ripple",
     "ui:gear_menu",
-    "//ui/webui/resources/js/cr/ui:context_menu_button",
   ]
 }
 
@@ -679,7 +678,6 @@
   deps = [
     ":file_list_model",
     "../elements:files_toggle_ripple",
-    "//ui/webui/resources/js/cr/ui:context_menu_button",
   ]
 }
 
diff --git a/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn b/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn
index e9b135b7..91a98b4 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn
+++ b/ui/file_manager/file_manager/foreground/js/ui/BUILD.gn
@@ -147,7 +147,6 @@
     "../../../common/js:util",
     "../metadata:metadata_model",
     "//ui/file_manager/base/js:volume_manager_types",
-    "//ui/webui/resources/js/cr/ui:context_menu_button",
     "//ui/webui/resources/js/cr/ui:context_menu_handler",
     "//ui/webui/resources/js/cr/ui:menu",
     "//ui/webui/resources/js/cr/ui:tree",
@@ -254,7 +253,6 @@
     "//ui/file_manager/file_manager/foreground/js:launch_param",
     "//ui/file_manager/file_manager/foreground/js:providers_model",
     "//ui/webui/resources/js:util",
-    "//ui/webui/resources/js/cr/ui:context_menu_button",
     "//ui/webui/resources/js/cr/ui:dialogs",
     "//ui/webui/resources/js/cr/ui:menu",
   ]
@@ -301,13 +299,13 @@
 
 js_unittest("file_table_list_unittest") {
   deps = [
-    ":file_table_list",
     ":file_table",
+    ":file_table_list",
     "../../../common/js:util",
     "//ui/file_manager/base/js:test_error_reporting",
-    "//ui/webui/resources/js:webui_resource_test",
     "//ui/file_manager/file_manager/background/js:mock_volume_manager",
     "//ui/file_manager/file_manager/foreground/js/metadata:mock_metadata",
+    "//ui/webui/resources/js:webui_resource_test",
   ]
 }
 
@@ -473,10 +471,10 @@
     ":actions_submenu_unittest",
     ":directory_tree_unittest",
     ":file_list_selection_model_unittest",
+    ":file_table_list_unittest",
     ":file_table_unittest",
     ":file_tap_handler_unittest",
     ":list_container_unittest",
-    ":file_table_list_unittest",
     ":multi_menu_unittest",
   ]
 }
diff --git a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js
index 90577c4a..0476b01 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js
@@ -727,7 +727,7 @@
       item.setAttribute('drive-label', location.volumeInfo.driveLabel);
     }
   } else {
-    const rootType = location.rootType || null;
+    const rootType = location && location.rootType ? location.rootType : null;
     const iconOverride = FileType.getIconOverrides(dirEntry, rootType);
     // Add Downloads icon as volume so current test code passes with
     // MyFilesVolume flag enabled and disabled.
diff --git a/ui/file_manager/file_manager/main.html b/ui/file_manager/file_manager/main.html
index 0d80b7d..db662e1 100644
--- a/ui/file_manager/file_manager/main.html
+++ b/ui/file_manager/file_manager/main.html
@@ -509,7 +509,7 @@
                 </div>
                 <div class="detail-table" id="detail-table" tabindex="1" autofocus>
                 </div>
-                <grid class="thumbnail-grid" tabindex="2"></grid>
+                <grid class="thumbnail-grid" tabindex="2" hidden></grid>
                 <paper-progress class="loading-indicator" indeterminate hidden></paper-progress>
                 <div class="drive-welcome page"></div>
               </div>
diff --git a/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js b/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js
index 17e480c..ca4336d 100644
--- a/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js
+++ b/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js
@@ -5,6 +5,9 @@
 'use strict';
 (() => {
 
+// Filter used to wait for tree item to have fully loaded its children.
+const hasChildren = ' > .tree-row[has-children=true]';
+
 /**
  * Sets up for directory tree context menu test. In addition to normal setup, we
  * add destination directory.
@@ -649,14 +652,25 @@
 };
 
 /**
- * Tests context menu for Crostini real root.
- * TODO(lucmult): Check menus for a crostini folder.
+ * Tests context menu for Crostini real root and a folder inside it.
  */
 testcase.dirContextMenuCrostini = async () => {
   const linuxMenus = [
     ['#new-folder', true],
   ];
+  const folderMenus = [
+    ['#cut', true],
+    ['#copy', true],
+    ['#paste-into-folder', false],
+    ['#rename', true],
+    ['#delete', true],
+    ['#new-folder', true],
+  ];
   const linuxQuery = '#directory-tree [entry-label="Linux files"]';
+  const folderQuery = linuxQuery + ' [entry-label="photos"]';
+
+  // Add a crostini folder.
+  await addEntries(['crostini'], [ENTRIES.photos]);
 
   // Open Files app on local Downloads.
   const appId = await setupAndWaitUntilReady(
@@ -678,18 +692,37 @@
 
   // Check the context menu for Linux files.
   await checkContextMenu(appId, linuxQuery, linuxMenus, false /* rootMenu */);
+
+  // Expand Crostini to display its folders, it dismisses the context menu.
+  await expandTreeItem(appId, linuxQuery);
+
+  // Check the context menu for a folder in Linux files.
+  await checkContextMenu(appId, folderQuery, folderMenus, false /* rootMenu */);
 };
 
 /**
- * Tests context menu for ARC++/Play files root.
- * TODO(lucmult): Check menus for a Play folder.
+ * Tests context menu for ARC++/Play files root and a folder inside it.
  */
 testcase.dirContextMenuPlayFiles = async () => {
   const playFilesMenus = [
     ['#share-with-linux', true],
     ['#new-folder', false],
   ];
+  const folderMenus = [
+    ['#cut', true],
+    ['#copy', true],
+    ['#paste-into-folder', false],
+    ['#share-with-linux', true],
+    ['#rename', false],
+    ['#delete', true],
+    ['#new-folder', true],
+  ];
+
   const playFilesQuery = '#directory-tree [entry-label="Play files"]';
+  const folderQuery = playFilesQuery + ' [entry-label="Documents"]';
+
+  // Add an Android folder.
+  await addEntries(['android_files'], [ENTRIES.directoryDocuments]);
 
   // Open Files app on local Downloads.
   const appId = await setupAndWaitUntilReady(
@@ -698,11 +731,16 @@
   // Check the context menu for Play files.
   await checkContextMenu(
       appId, playFilesQuery, playFilesMenus, false /* rootMenu */);
+
+  // Expand Play files to display its folders, it dismisses the context menu.
+  await expandTreeItem(appId, playFilesQuery);
+
+  // Check the context menu for a folder in Play files.
+  await checkContextMenu(appId, folderQuery, folderMenus, false /* rootMenu */);
 };
 
 /**
  * Tests context menu for USB root (single and multiple partitions).
- * TODO(lucmult): Check menus for a USB folder.
  */
 testcase.dirContextMenuUsbs = async () => {
   const singleUsbMenus = [
@@ -721,10 +759,21 @@
     ['#rename', false],
     ['#new-folder', true],
   ];
+  const folderMenus = [
+    ['#cut', true],
+    ['#copy', true],
+    ['#paste-into-folder', false],
+    ['#share-with-linux', true],
+    ['#rename', true],
+    ['#delete', true],
+    ['#new-folder', true],
+  ];
 
   const singleUsbQuery = '#directory-tree [entry-label="fake-usb"]';
   const partitionsRootQuery = '#directory-tree [entry-label="Drive Label"]';
   const partition1Query = '#directory-tree [entry-label="partition-1"]';
+  const singleUsbFolderQuery = singleUsbQuery + ' [entry-label="A"]';
+  const partition1FolderQuery = partition1Query + ' [entry-label="Folder"]';
 
   // Mount removable volumes.
   await sendTestMessage({name: 'mountUsbWithPartitions'});
@@ -745,17 +794,36 @@
   // Check the context menu for multiple partitions USB (actual partition).
   await checkContextMenu(
       appId, partition1Query, partition1Menus, false /* rootMenu */);
+
+  // Check the context menu for a folder inside a singlue USB partition.
+  await expandTreeItem(appId, singleUsbQuery);
+  await checkContextMenu(
+      appId, singleUsbFolderQuery, folderMenus, false /* rootMenu */);
+
+  // Check the context menu for a folder inside a partition1.
+  await expandTreeItem(appId, partition1Query);
+  await checkContextMenu(
+      appId, partition1FolderQuery, folderMenus, false /* rootMenu */);
+
 };
 
 /**
- * Tests context menu for FSP root.
- * TODO(lucmult): Check menus for a FSP.
+ * Tests context menu for FSP root and a folder inside it.
  */
 testcase.dirContextMenuFsp = async () => {
   const fspMenus = [
     ['#unmount', true],
   ];
+  const folderMenus = [
+    ['#cut', false],
+    ['#copy', true],
+    ['#paste-into-folder', false],
+    ['#rename', false],
+    ['#delete', false],
+    ['#new-folder', false],
+  ];
   const fspQuery = '#directory-tree [entry-label="Test (1)"]';
+  const folderQuery = fspQuery + ' [entry-label="folder"]';
 
   // Install a FSP.
   const manifest = 'manifest_source_file.json';
@@ -766,7 +834,49 @@
       await setupAndWaitUntilReady(RootPath.DOWNLOADS, [ENTRIES.beautiful], []);
 
   // Check the context menu for FSP.
+  await remoteCall.waitForElement(appId, fspQuery + hasChildren);
   await checkContextMenu(appId, fspQuery, fspMenus, true /* rootMenu */);
+
+  // Check the context menu for a folder inside a FSP.
+  await expandTreeItem(appId, fspQuery);
+  await checkContextMenu(appId, folderQuery, folderMenus, false /* rootMenu */);
+};
+
+/**
+ * Tests context menu for DocumentsProvider root and a folder inside it.
+ */
+testcase.dirContextMenuDocumentsProvider = async () => {
+  const folderMenus = [
+    ['#cut', false],
+    ['#copy', true],
+    ['#paste-into-folder', false],
+    ['#rename', false],
+    ['#delete', false],
+    ['#new-folder', false],
+  ];
+  const documentsProviderQuery =
+      '#directory-tree [entry-label="DocumentsProvider"]';
+  const folderQuery = documentsProviderQuery + ' [entry-label="photos"]';
+
+  // Add a DocumentsProvider folder.
+  await addEntries(['documents_provider'], [ENTRIES.photos]);
+
+  // Open Files app on local Downloads.
+  const appId =
+      await setupAndWaitUntilReady(RootPath.DOWNLOADS, [ENTRIES.beautiful], []);
+
+  // Wait for DocumentsProvider to appear.
+  await remoteCall.waitForElement(appId, documentsProviderQuery + hasChildren);
+
+  // Check that both menus are still hidden, because DocumentsProvider root
+  // doesn't show any context menu.
+  await remoteCall.waitForElement(appId, '#roots-context-menu[hidden]');
+  await remoteCall.waitForElement(
+      appId, '#directory-tree-context-menu[hidden]');
+
+  // Check the context menu for a folder inside a DocumentsProvider.
+  await expandTreeItem(appId, documentsProviderQuery);
+  await checkContextMenu(appId, folderQuery, folderMenus, false /* rootMenu */);
 };
 
 })();
diff --git a/ui/file_manager/integration_tests/file_manager/file_display.js b/ui/file_manager/integration_tests/file_manager/file_display.js
index ab7728c..7371e56 100644
--- a/ui/file_manager/integration_tests/file_manager/file_display.js
+++ b/ui/file_manager/integration_tests/file_manager/file_display.js
@@ -649,7 +649,10 @@
   if (removableDirectory === 'partition-1' ||
       removableDirectory === 'partition-2') {
     const partitionQuery = `#file-list [file-name="${removableDirectory}"]`;
-    const partitionFiles = [ENTRIES.hello.getExpectedRow()];
+    const partitionFiles = [
+      ENTRIES.hello.getExpectedRow(),
+      ['Folder', '--', 'Folder', Date()],
+    ];
     await remoteCall.callRemoteTestUtil(
         'fakeMouseDoubleClick', appId, [partitionQuery]);
     await remoteCall.waitUntilCurrentDirectoryIsChanged(
diff --git a/ui/file_manager/integration_tests/file_manager/quick_view.js b/ui/file_manager/integration_tests/file_manager/quick_view.js
index 20a9251..a179ab7 100644
--- a/ui/file_manager/integration_tests/file_manager/quick_view.js
+++ b/ui/file_manager/integration_tests/file_manager/quick_view.js
@@ -195,7 +195,10 @@
       'fakeMouseClick failed');
 
   // Check: the 'hello.txt' file should appear in the file list.
-  const files = [ENTRIES.hello.getExpectedRow()];
+  const files = [
+    ENTRIES.hello.getExpectedRow(),
+    ['Folder', '--', 'Folder', Date()],
+  ];
   await remoteCall.waitForFiles(appId, files, {ignoreLastModifiedTime: true});
 
   // Open the file in Quick View.
diff --git a/ui/file_manager/integration_tests/testing_provider/background.js b/ui/file_manager/integration_tests/testing_provider/background.js
index 8033db2..15bc66a 100644
--- a/ui/file_manager/integration_tests/testing_provider/background.js
+++ b/ui/file_manager/integration_tests/testing_provider/background.js
@@ -26,10 +26,22 @@
       });
     });
 
-chrome.fileSystemProvider.onReadDirectoryRequested.addListener(
-    function(options, onSuccess, onError) {
-      onSuccess([], false /* hasMore */);
-    });
+chrome.fileSystemProvider.onReadDirectoryRequested.addListener(function(
+    options, onSuccess, onError) {
+  // For anything other than root, return no entries.
+  if (options.directoryPath !== '/') {
+    onSuccess([], false /* hasMore */);
+    return;
+  }
+  // For root we return 1 folder entry.
+  const entries = [
+    {
+      isDirectory: true,
+      name: 'folder',
+    },
+  ];
+  onSuccess(entries, false /* hasMore */);
+});
 
 chrome.fileSystemProvider.onMountRequested.addListener(mountFileSystem);
 
diff --git a/ui/webui/resources/cr_elements/search_highlight_style_css.html b/ui/webui/resources/cr_elements/search_highlight_style_css.html
index bebb5ec..fd83632f 100644
--- a/ui/webui/resources/cr_elements/search_highlight_style_css.html
+++ b/ui/webui/resources/cr_elements/search_highlight_style_css.html
@@ -6,8 +6,7 @@
   <template>
     <style>
       .search-bubble {
-        /* RGB value matches var(--paper-yellow-500). */
-        --search-bubble-color: rgba(255, 235, 59, 0.9);
+        --search-bubble-color: var(--paper-yellow-500);
         position: absolute;
         z-index: 1;
       }
@@ -16,6 +15,7 @@
         align-items: center;
         background-color: var(--search-bubble-color);
         border-radius: 2px;
+        color: var(--google-grey-900);
         max-width: 100px;
         min-width: 64px;
         padding: 4px 10px;
diff --git a/ui/webui/resources/html/cr/ui/context_menu_button.html b/ui/webui/resources/html/cr/ui/context_menu_button.html
deleted file mode 100644
index da2eec4..0000000
--- a/ui/webui/resources/html/cr/ui/context_menu_button.html
+++ /dev/null
@@ -1 +0,0 @@
-<script src="../../../js/cr/ui/context_menu_button.js"></script>
diff --git a/ui/webui/resources/js/cr/ui/BUILD.gn b/ui/webui/resources/js/cr/ui/BUILD.gn
index 8e3229d1..6d250c7a 100644
--- a/ui/webui/resources/js/cr/ui/BUILD.gn
+++ b/ui/webui/resources/js/cr/ui/BUILD.gn
@@ -16,7 +16,6 @@
     ":array_data_model",
     ":autocomplete_list",
     ":command",
-    ":context_menu_button",
     ":context_menu_handler",
     ":dialogs",
     ":drag_wrapper",
@@ -77,12 +76,6 @@
   ]
 }
 
-js_library("context_menu_button") {
-  deps = [
-    ":menu_button",
-  ]
-}
-
 js_library("context_menu_handler") {
   deps = [
     ":menu",
diff --git a/ui/webui/resources/js/cr/ui/context_menu_button.js b/ui/webui/resources/js/cr/ui/context_menu_button.js
deleted file mode 100644
index 1c1bd273..0000000
--- a/ui/webui/resources/js/cr/ui/context_menu_button.js
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview This implements a special button that is useful for showing a
- * context menu.
- */
-
-cr.define('cr.ui', function() {
-  /** @const */ const MenuButton = cr.ui.MenuButton;
-
-  /**
-   * Helper function for ContextMenuButton to find the first ancestor of the
-   * button that has a context menu.
-   * @param {!cr.ui.MenuButton} button The button to start the search from.
-   * @return {HTMLElement} The found element or null if not found.
-   */
-  function getContextMenuTarget(button) {
-    let el = button;
-    do {
-      el = el.parentNode;
-    } while (el && !('contextMenu' in el));
-    return el ? assertInstanceof(el, HTMLElement) : null;
-  }
-
-  /**
-   * Creates a new menu button which is used to show the context menu for an
-   * ancestor that has a {@code contextMenu} property.
-   * @param {Object=} opt_propertyBag Optional properties.
-   * @constructor
-   * @extends {cr.ui.MenuButton}
-   */
-  const ContextMenuButton = cr.ui.define('button');
-
-  ContextMenuButton.prototype = {
-    __proto__: MenuButton.prototype,
-
-    /**
-     * Override to return the contextMenu for the ancestor.
-     * @override
-     * @type {cr.ui.Menu}
-     */
-    get menu() {
-      const target = getContextMenuTarget(this);
-      return target && target.contextMenu;
-    },
-
-    /** @override */
-    decorate: function() {
-      this.tabIndex = -1;
-      this.addEventListener('mouseup', this);
-      MenuButton.prototype.decorate.call(this);
-    },
-
-    /** @override */
-    handleEvent: function(e) {
-      switch (e.type) {
-        case 'mousedown':
-          // Menu buttons prevent focus changes.
-          const target = getContextMenuTarget(this);
-          if (target) {
-            target.focus();
-          }
-          break;
-        case 'mouseup':
-          // Stop mouseup to prevent selection changes.
-          e.stopPropagation();
-          break;
-      }
-      MenuButton.prototype.handleEvent.call(this, e);
-    },
-
-    /**
-     * Override MenuButton showMenu to allow the mousedown to be fully handled
-     * before the menu is shown. This is important in case the mousedown
-     * triggers command changes.
-     * @param {boolean} shouldSetFocus Whether the menu should be focused after
-     *     the menu is shown.
-     * @param {{x: number, y: number}=} opt_mousePos The position of the mouse
-     *     when shown (in screen coordinates).
-     * @override
-     */
-    showMenu: function(shouldSetFocus, opt_mousePos) {
-      const self = this;
-      window.setTimeout(function() {
-        MenuButton.prototype.showMenu.call(self, shouldSetFocus, opt_mousePos);
-      }, 0);
-    }
-  };
-
-  // Export
-  return {ContextMenuButton: ContextMenuButton};
-});
diff --git a/ui/webui/resources/js/search_highlight_utils.js b/ui/webui/resources/js/search_highlight_utils.js
index 5477b91a..fdaa237 100644
--- a/ui/webui/resources/js/search_highlight_utils.js
+++ b/ui/webui/resources/js/search_highlight_utils.js
@@ -21,7 +21,7 @@
    * @param {!Array<!Node>} wrappers
    */
   function removeHighlights(wrappers) {
-    for (let wrapper of wrappers) {
+    for (const wrapper of wrappers) {
       // If wrapper is already removed, do nothing.
       if (!wrapper.parentElement) {
         continue;
@@ -79,7 +79,8 @@
       } else {
         const hitSpan = document.createElement('span');
         hitSpan.classList.add(HIT_CSS_CLASS);
-        hitSpan.style.backgroundColor = '#ffeb3b';  // --var(--paper-yellow-500)
+        hitSpan.style.backgroundColor = '#ffeb3b';  // var(--paper-yellow-500)
+        hitSpan.style.color = '#202124';            // var(--google-grey-900)
         hitSpan.textContent = tokens[i];
         wrapper.appendChild(hitSpan);
       }
diff --git a/ui/webui/resources/webui_resources.grd b/ui/webui/resources/webui_resources.grd
index 0e8190ee..354fc9d 100644
--- a/ui/webui/resources/webui_resources.grd
+++ b/ui/webui/resources/webui_resources.grd
@@ -292,9 +292,6 @@
       <structure name="IDR_WEBUI_HTML_CR_UI_COMMAND"
                  file="html/cr/ui/command.html" type="chrome_html"
                  compress="gzip" />
-      <structure name="IDR_WEBUI_HTML_CR_UI_CONTEXT_MENU_BUTTON"
-                 file="html/cr/ui/context_menu_button.html"
-                 type="chrome_html" compress="gzip" />
       <structure name="IDR_WEBUI_HTML_CR_UI_CONTEXT_MENU_HANDLER"
                  file="html/cr/ui/context_menu_handler.html"
                  type="chrome_html" compress="gzip" />
@@ -406,9 +403,6 @@
       <structure name="IDR_WEBUI_JS_CR_UI_COMMAND"
                  file="js/cr/ui/command.js" type="chrome_html"
                  compress="gzip" />
-      <structure name="IDR_WEBUI_JS_CR_UI_CONTEXT_MENU_BUTTON"
-                 file="js/cr/ui/context_menu_button.js"
-                 type="chrome_html" compress="gzip" />
       <structure name="IDR_WEBUI_JS_CR_UI_CONTEXT_MENU_HANDLER"
                  file="js/cr/ui/context_menu_handler.js"
                  type="chrome_html" compress="gzip" />