diff --git a/DEPS b/DEPS
index 61bbc2fb..07d89511 100644
--- a/DEPS
+++ b/DEPS
@@ -38,6 +38,7 @@
   'checkout_android',
   'checkout_android_prebuilts_build_tools',
   'checkout_android_native_support',
+  'checkout_fuchsia_for_arm64_host',
   'checkout_google_benchmark',
   'checkout_ios_webkit',
   'checkout_nacl',
@@ -199,11 +200,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '34ddcb84f3c277bdbed6e01f29d84cf2dd27719c',
+  'skia_revision': 'a0f5452c6e2373678f2caac934bd311dacff0836',
   # 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': 'ba4c87c9e0ec74e0333ec2d53daa5b97b16a1ab3',
+  'v8_revision': '28cb2dd6633ecb818598c6babfb5f82fcfe7843c',
   # 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.
@@ -211,11 +212,11 @@
   # 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': '4c9f892f0d42c41e1cf5cef7a593ecf694dc9cb4',
+  'angle_revision': 'a2ef814426ee780c50e89f40c22daca0486ca9dd',
   # 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': 'fa0140b92951ac126d75793f5b51564433e7d3f7',
+  'swiftshader_revision': '52c1a859d9ebd3adb49e70d1c7a5ac287388445e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
@@ -262,7 +263,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': 'fb3d4294864abacff588cd22db67be508e4ebb76',
+  'catapult_revision': 'b7c1c3f1140ba42e6367f25c6f3950678be55c56',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -270,7 +271,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling devtools-frontend
   # and whatever else without interference from each other.
-  'devtools_frontend_revision': '61aa96cc7a59f696c977ae1ddc4e01acc5e17f55',
+  'devtools_frontend_revision': '9a5e8ce8b8733d889ef5a8c6b4483492b804e915',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libprotobuf-mutator
   # and whatever else without interference from each other.
@@ -361,7 +362,7 @@
   'ukey2_revision': '0275885d8e6038c39b8a8ca55e75d1d4d1727f47',
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'tint_revision': '5afb002aa4237c133ed192f3f12bc9af4d0af9a5',
+  'tint_revision': 'ff267ca60e144afa928d4a2c204e0045e3f5f7d5',
 
   # TODO(crbug.com/941824): The values below need to be kept in sync
   # between //DEPS and //buildtools/DEPS, so if you're updating one,
@@ -925,7 +926,7 @@
   },
 
   'src/third_party/ffmpeg':
-    Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + 'e61dd757a8c09139c03ffa2ef285d5678909370a',
+    Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '6d9096c9e3f7f5d4e6528104ed77987ec9327315',
 
   'src/third_party/flac':
     Var('chromium_git') + '/chromium/deps/flac.git' + '@' + 'af862024c8c8fa0ae07ced05e89013d881b00596',
@@ -1244,7 +1245,7 @@
     Var('chromium_git') + '/openscreen' + '@' + 'a3f46f23c52688cc3c0de927b7fb8a86ff9e8dff',
 
   'src/third_party/openxr/src': {
-    'url': Var('chromium_git') + '/external/github.com/KhronosGroup/OpenXR-SDK' + '@' + 'e3a4e41d61544d8e2eba73f00da99b6818ec472b',
+    'url': Var('chromium_git') + '/external/github.com/KhronosGroup/OpenXR-SDK' + '@' + '9e97b73e7dd2bfc07745489d728f6a36665c648f',
     'condition': 'checkout_openxr',
   },
 
@@ -1258,7 +1259,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '0581509dc2dd4d6d38b34e05059becddcfc693ef',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '7411aeba4d3b11872828b8b15ac9bfddd63f4e6c',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1336,7 +1337,7 @@
       'packages': [
           {
               'package': 'fuchsia/third_party/aemu/linux-amd64',
-              'version': 'fXB8-psP9LjGgvBfws13Jq6cj76raUn9-okihlMjbYAC'
+              'version': 'ZGsmd0k3ijPxG9j-pwQg-yGF3zXYYOUD1L40GuIoAjEC'
           },
       ],
       'condition': 'host_os == "linux" and checkout_fuchsia',
@@ -1562,7 +1563,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@08cdb1c17f2e7ed0646fad3759f6907d35b9dedb',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@df97f4c2861e3577c51ad1531aba6cb5e10e969e',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn
index d98859b..0357f58 100644
--- a/android_webview/BUILD.gn
+++ b/android_webview/BUILD.gn
@@ -934,6 +934,7 @@
   ]
   deps = [
     "//mojo/public/js:bindings_lite",
+    "//mojo/public/js:bindings_module",
     "//mojo/public/mojom/base:base_js",
   ]
 }
diff --git a/android_webview/browser/tracing/aw_tracing_delegate.cc b/android_webview/browser/tracing/aw_tracing_delegate.cc
index 041b491..652c4960 100644
--- a/android_webview/browser/tracing/aw_tracing_delegate.cc
+++ b/android_webview/browser/tracing/aw_tracing_delegate.cc
@@ -23,6 +23,22 @@
   return NULL;
 }
 
+bool AwTracingDelegate::IsAllowedToBeginBackgroundScenario(
+    const content::BackgroundTracingConfig& config,
+    bool requires_anonymized_data) {
+  // Background tracing is allowed in general and can be restricted when
+  // configuring BackgroundTracingManager.
+  return true;
+}
+
+bool AwTracingDelegate::IsAllowedToEndBackgroundScenario(
+    const content::BackgroundTracingConfig& config,
+    bool requires_anonymized_data) {
+  // Background tracing is allowed in general and can be restricted when
+  // configuring BackgroundTracingManager.
+  return true;
+}
+
 std::unique_ptr<base::DictionaryValue>
 AwTracingDelegate::GenerateMetadataDict() {
   auto metadata_dict = std::make_unique<base::DictionaryValue>();
diff --git a/android_webview/browser/tracing/aw_tracing_delegate.h b/android_webview/browser/tracing/aw_tracing_delegate.h
index 27eb2d8..74d118b 100644
--- a/android_webview/browser/tracing/aw_tracing_delegate.h
+++ b/android_webview/browser/tracing/aw_tracing_delegate.h
@@ -23,6 +23,12 @@
   // content::TracingDelegate implementation:
   std::unique_ptr<content::TraceUploader> GetTraceUploader(
       scoped_refptr<network::SharedURLLoaderFactory> factory) override;
+  bool IsAllowedToBeginBackgroundScenario(
+      const content::BackgroundTracingConfig& config,
+      bool requires_anonymized_data) override;
+  bool IsAllowedToEndBackgroundScenario(
+      const content::BackgroundTracingConfig& config,
+      bool requires_anonymized_data) override;
   std::unique_ptr<base::DictionaryValue> GenerateMetadataDict() override;
 };
 
diff --git a/ash/ambient/backdrop/ambient_backend_controller_impl.cc b/ash/ambient/backdrop/ambient_backend_controller_impl.cc
index 2f6a9f8..e7adf7b 100644
--- a/ash/ambient/backdrop/ambient_backend_controller_impl.cc
+++ b/ash/ambient/backdrop/ambient_backend_controller_impl.cc
@@ -90,37 +90,19 @@
   return resource_request;
 }
 
-std::string BuildCuratedTopicDetails(
-    const backdrop::ScreenUpdate::Topic& topic) {
-  if (topic.has_metadata_line_1() && topic.has_metadata_line_2()) {
-    // Uses a space as the separator between.
-    return topic.metadata_line_1() + " " + topic.metadata_line_2();
-  } else if (topic.has_metadata_line_1()) {
-    return topic.metadata_line_1();
-  } else if (topic.has_metadata_line_2()) {
-    return topic.metadata_line_2();
-  } else {
-    return std::string();
-  }
-}
+std::string BuildBackdropTopicDetails(
+    const backdrop::ScreenUpdate::Topic& backdrop_topic) {
+  std::string result;
+  if (backdrop_topic.has_metadata_line_1())
+    result += backdrop_topic.metadata_line_1();
 
-std::string BuildPersonalTopicDetails(
-    const backdrop::ScreenUpdate::Topic& topic) {
-  // |metadata_line_1| contains the album name.
-  return topic.has_metadata_line_1() ? topic.metadata_line_1() : std::string();
-}
-
-void BuildBackdropTopicDetails(
-    const backdrop::ScreenUpdate::Topic& backdrop_topic,
-    AmbientModeTopic& ambient_topic) {
-  switch (backdrop_topic.topic_type()) {
-    case backdrop::TopicSource::PERSONAL_PHOTO:
-      ambient_topic.details = BuildPersonalTopicDetails(backdrop_topic);
-      break;
-    default:
-      ambient_topic.details = BuildCuratedTopicDetails(backdrop_topic);
-      break;
+  if (backdrop_topic.has_metadata_line_2()) {
+    if (!result.empty())
+      result += " ";
+    result += backdrop_topic.metadata_line_2();
   }
+  // Do not include metadata_line_3.
+  return result;
 }
 
 AmbientModeTopicType ToAmbientModeTopicType(
@@ -240,8 +222,7 @@
               backdrop_topic.related_topic().url();
         }
       }
-
-      BuildBackdropTopicDetails(backdrop_topic, ambient_topic);
+      ambient_topic.details = BuildBackdropTopicDetails(backdrop_topic);
       screen_update.next_topics.emplace_back(ambient_topic);
     }
   }
diff --git a/ash/app_list/app_list_color_provider_impl.cc b/ash/app_list/app_list_color_provider_impl.cc
index 260936b..4a4d3ad4 100644
--- a/ash/app_list/app_list_color_provider_impl.cc
+++ b/ash/app_list/app_list_color_provider_impl.cc
@@ -52,7 +52,7 @@
 SkColor AppListColorProviderImpl::GetSearchBoxPlaceholderTextColor() const {
   return DeprecatedGetContentLayerColor(
       AshColorProvider::ContentLayerType::kTextColorSecondary,
-      /*default_color*/ gfx::kGoogleGrey200);
+      /*default_color*/ SkColorSetARGB(0xDE, 0x00, 0x00, 0x00));
 }
 
 SkColor AppListColorProviderImpl::GetSearchBoxTextColor(
@@ -82,7 +82,7 @@
 SkColor AppListColorProviderImpl::GetAppListItemTextColor() const {
   return DeprecatedGetContentLayerColor(
       AshColorProvider::ContentLayerType::kTextColorPrimary,
-      /*default_color*/ SK_ColorBLACK);
+      /*default_color*/ SK_ColorWHITE);
 }
 
 SkColor AppListColorProviderImpl::GetPageSwitcherButtonColor(
diff --git a/ash/app_list/views/app_list_item_view.cc b/ash/app_list/views/app_list_item_view.cc
index 27f53fd..c1f4cc51 100644
--- a/ash/app_list/views/app_list_item_view.cc
+++ b/ash/app_list/views/app_list_item_view.cc
@@ -334,7 +334,9 @@
   title->SetFontList(GetAppListConfig().app_title_font());
   title->SetHorizontalAlignment(gfx::ALIGN_CENTER);
   title->SetEnabledColor(
-      AppListColorProvider::Get()->GetAppListItemTextColor());
+      apps_grid_view_->is_in_folder()
+          ? SK_ColorBLACK
+          : AppListColorProvider::Get()->GetAppListItemTextColor());
 
   if (!is_in_folder) {
     gfx::ShadowValues title_shadow = gfx::ShadowValues(
diff --git a/ash/app_list/views/app_list_page.cc b/ash/app_list/views/app_list_page.cc
index 13227f6e..137efde 100644
--- a/ash/app_list/views/app_list_page.cc
+++ b/ash/app_list/views/app_list_page.cc
@@ -41,10 +41,6 @@
       GetPageBoundsForState(state, contents_bounds, search_box_bounds));
 }
 
-views::View* AppListPage::GetSelectedView() const {
-  return nullptr;
-}
-
 views::View* AppListPage::GetFirstFocusableView() {
   return nullptr;
 }
diff --git a/ash/app_list/views/app_list_page.h b/ash/app_list/views/app_list_page.h
index bd25217..45730e4 100644
--- a/ash/app_list/views/app_list_page.h
+++ b/ash/app_list/views/app_list_page.h
@@ -101,9 +101,6 @@
     contents_view_ = contents_view;
   }
 
-  // Returns selected view in this page.
-  virtual views::View* GetSelectedView() const;
-
   // Returns the first focusable view in this page.
   virtual views::View* GetFirstFocusableView();
 
diff --git a/ash/app_list/views/contents_view.cc b/ash/app_list/views/contents_view.cc
index 8c1415c..f130144 100644
--- a/ash/app_list/views/contents_view.cc
+++ b/ash/app_list/views/contents_view.cc
@@ -661,10 +661,6 @@
   UpdateSearchBoxAnimation(progress, current_state, target_state);
 }
 
-views::View* ContentsView::GetSelectedView() const {
-  return app_list_pages_[GetActivePageIndex()]->GetSelectedView();
-}
-
 void ContentsView::UpdateYPositionAndOpacity() {
   const int current_page = pagination_model_.has_transition()
                                ? pagination_model_.transition().target_page
diff --git a/ash/app_list/views/contents_view.h b/ash/app_list/views/contents_view.h
index 2434dbd..5b950041 100644
--- a/ash/app_list/views/contents_view.h
+++ b/ash/app_list/views/contents_view.h
@@ -194,9 +194,6 @@
   void TransitionStarted() override;
   void TransitionChanged() override;
 
-  // Returns selected view in active page.
-  views::View* GetSelectedView() const;
-
   // Updates y position and opacity of the items in this view during dragging.
   void UpdateYPositionAndOpacity();
 
diff --git a/ash/app_list/views/folder_header_view.cc b/ash/app_list/views/folder_header_view.cc
index 0205817..9c33007 100644
--- a/ash/app_list/views/folder_header_view.cc
+++ b/ash/app_list/views/folder_header_view.cc
@@ -42,6 +42,8 @@
         ui::ResourceBundle::GetSharedInstance().GetFontListWithDelta(2));
     set_placeholder_text_color(
         AppListColorProvider::Get()->GetFolderHintTextColor());
+    SetTextColor(AppListColorProvider::Get()->GetFolderTitleTextColor(
+        gfx::kGoogleGrey700));
     SetEventTargeter(std::make_unique<views::ViewTargeter>(this));
   }
 
diff --git a/ash/app_list/views/search_box_view.cc b/ash/app_list/views/search_box_view.cc
index cb3044a..dafc50e8 100644
--- a/ash/app_list/views/search_box_view.cc
+++ b/ash/app_list/views/search_box_view.cc
@@ -134,12 +134,6 @@
       true, false /*triggered_by_contents_change*/);
 }
 
-views::View* SearchBoxView::GetSelectedViewInContentsView() {
-  if (!contents_view_)
-    return nullptr;
-  return contents_view_->GetSelectedView();
-}
-
 void SearchBoxView::HandleSearchBoxEvent(ui::LocatedEvent* located_event) {
   if (located_event->type() == ui::ET_MOUSEWHEEL) {
     if (!app_list_view_->HandleScroll(
diff --git a/ash/app_list/views/search_box_view.h b/ash/app_list/views/search_box_view.h
index fac061c..7d9e76d 100644
--- a/ash/app_list/views/search_box_view.h
+++ b/ash/app_list/views/search_box_view.h
@@ -50,7 +50,6 @@
 
   // Overridden from SearchBoxViewBase:
   void ClearSearch() override;
-  views::View* GetSelectedViewInContentsView() override;
   void HandleSearchBoxEvent(ui::LocatedEvent* located_event) override;
   void ModelChanged() override;
   void UpdateKeyboardVisibility() override;
diff --git a/ash/clipboard/clipboard_history_resource_manager.cc b/ash/clipboard/clipboard_history_resource_manager.cc
index cce8dfa..a909336 100644
--- a/ash/clipboard/clipboard_history_resource_manager.cc
+++ b/ash/clipboard/clipboard_history_resource_manager.cc
@@ -267,8 +267,10 @@
 void ClipboardHistoryResourceManager::OnClipboardHistoryItemRemoved(
     const ClipboardHistoryItem& item) {
   // For items that will not be represented by their rendered HTML, do nothing.
-  if (!item.data().bitmap().isNull() || item.data().markup_data().empty())
+  if (ClipboardHistoryUtil::CalculateMainFormat(item.data()) !=
+      ui::ClipboardInternalFormat::kHtml) {
     return;
+  }
 
   // We should have an image model in the cache.
   auto cached_image_model = base::ConstCastIterator(
diff --git a/ash/clipboard/clipboard_nudge.cc b/ash/clipboard/clipboard_nudge.cc
index 41c23eb..6a5aab1 100644
--- a/ash/clipboard/clipboard_nudge.cc
+++ b/ash/clipboard/clipboard_nudge.cc
@@ -8,11 +8,14 @@
 #include "ash/public/cpp/shelf_config.h"
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/resources/vector_icons/vector_icons.h"
+#include "ash/root_window_controller.h"
+#include "ash/shelf/hotseat_widget.h"
 #include "ash/shell.h"
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/style/ash_color_provider.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/chromeos/events/keyboard_layout_util.h"
+#include "ui/compositor/scoped_layer_animation_settings.h"
 #include "ui/gfx/color_palette.h"
 #include "ui/gfx/paint_vector_icon.h"
 #include "ui/views/border.h"
@@ -49,6 +52,9 @@
 // The padding which separates the nudge's border with its inner contents.
 constexpr int kNudgePadding = 16;
 
+constexpr base::TimeDelta kNudgeBoundsAnimationTime =
+    base::TimeDelta::FromMilliseconds(250);
+
 bool IsAssistantAvailable() {
   AssistantStateBase* state = AssistantState::Get();
   return state->allowed_state() ==
@@ -143,7 +149,11 @@
   views::ImageView* clipboard_icon_ = nullptr;
 };
 
-ClipboardNudge::ClipboardNudge() : widget_(std::make_unique<views::Widget>()) {
+ClipboardNudge::ClipboardNudge()
+    : widget_(std::make_unique<views::Widget>()),
+      root_window_(Shell::GetRootWindowForNewWindows()) {
+  shelf_observer_.Add(RootWindowController::ForWindow(root_window_)->shelf());
+
   views::Widget::InitParams params(
       views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
   params.z_order = ui::ZOrderLevel::kFloatingWindow;
@@ -151,8 +161,8 @@
   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
   params.name = "ClipboardContextualNudge";
   params.layer_type = ui::LAYER_NOT_DRAWN;
-  params.parent = Shell::GetPrimaryRootWindow()->GetChildById(
-      kShellWindowId_OverlayContainer);
+  params.parent =
+      root_window_->GetChildById(kShellWindowId_SettingBubbleContainer);
   widget_->Init(std::move(params));
 
   nudge_view_ =
@@ -163,14 +173,18 @@
 
 ClipboardNudge::~ClipboardNudge() = default;
 
+void ClipboardNudge::OnHotseatStateChanged(HotseatState old_state,
+                                           HotseatState new_state) {
+  CalculateAndSetWidgetBounds();
+}
+
 void ClipboardNudge::Close() {
   widget_->CloseWithReason(views::Widget::ClosedReason::kUnspecified);
 }
 
 void ClipboardNudge::CalculateAndSetWidgetBounds() {
-  aura::Window* root_window = Shell::GetRootWindowForNewWindows();
-  gfx::Rect display_bounds = root_window->bounds();
-  ::wm::ConvertRectToScreen(root_window, &display_bounds);
+  gfx::Rect display_bounds = root_window_->bounds();
+  ::wm::ConvertRectToScreen(root_window_, &display_bounds);
   gfx::Rect widget_bounds;
 
   // Calculate the nudge's size to ensure the label text accurately fits.
@@ -188,6 +202,26 @@
   if (base::i18n::IsRTL())
     widget_bounds.set_x(display_bounds.right() - nudge_width - kNudgeMargin);
 
+  // Set the nudge's bounds above the hotseat when it is extended.
+  HotseatWidget* hotseat_widget =
+      RootWindowController::ForWindow(root_window_)->shelf()->hotseat_widget();
+  if (hotseat_widget->state() == HotseatState::kExtended) {
+    widget_bounds.set_y(hotseat_widget->GetTargetBounds().y() - nudge_height -
+                        kNudgeMargin);
+  }
+
+  // Only run the widget bounds animation if the widget's bounds have already
+  // been initialized.
+  std::unique_ptr<ui::ScopedLayerAnimationSettings> settings;
+  if (widget_->GetWindowBoundsInScreen().size() != gfx::Size()) {
+    settings = std::make_unique<ui::ScopedLayerAnimationSettings>(
+        widget_->GetLayer()->GetAnimator());
+    settings->SetPreemptionStrategy(
+        ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
+    settings->SetTransitionDuration(kNudgeBoundsAnimationTime);
+    settings->SetTweenType(gfx::Tween::EASE_OUT);
+  }
+
   widget_->SetBounds(widget_bounds);
 }
 
diff --git a/ash/clipboard/clipboard_nudge.h b/ash/clipboard/clipboard_nudge.h
index 2724461..e5010eb 100644
--- a/ash/clipboard/clipboard_nudge.h
+++ b/ash/clipboard/clipboard_nudge.h
@@ -6,18 +6,24 @@
 #define ASH_CLIPBOARD_CLIPBOARD_NUDGE_H_
 
 #include "ash/ash_export.h"
+#include "ash/shelf/shelf.h"
+#include "ash/shelf/shelf_observer.h"
+#include "base/scoped_observer.h"
 #include "ui/views/widget/widget.h"
 
 namespace ash {
 
 // Implements a contextual nudge for multipaste.
-class ASH_EXPORT ClipboardNudge {
+class ASH_EXPORT ClipboardNudge : public ShelfObserver {
  public:
   ClipboardNudge();
   ClipboardNudge(const ClipboardNudge&) = delete;
   ClipboardNudge& operator=(const ClipboardNudge&) = delete;
-  ~ClipboardNudge();
+  ~ClipboardNudge() override;
 
+  // ShelfObserver overrides:
+  void OnHotseatStateChanged(HotseatState old_state,
+                             HotseatState new_state) override;
   void Close();
 
  private:
@@ -30,6 +36,10 @@
   std::unique_ptr<views::Widget> widget_;
 
   ClipboardNudgeView* nudge_view_ = nullptr;  // not_owned
+
+  aura::Window* const root_window_;
+
+  ScopedObserver<Shelf, ShelfObserver> shelf_observer_{this};
 };
 
 }  // namespace ash
diff --git a/ash/public/cpp/resources/unscaled_resources/settings_logo_192.png b/ash/public/cpp/resources/unscaled_resources/settings_logo_192.png
index 5fe10aaa..0966334 100644
--- a/ash/public/cpp/resources/unscaled_resources/settings_logo_192.png
+++ b/ash/public/cpp/resources/unscaled_resources/settings_logo_192.png
Binary files differ
diff --git a/ash/public/cpp/resources/unscaled_resources/shortcut_viewer_logo_192.png b/ash/public/cpp/resources/unscaled_resources/shortcut_viewer_logo_192.png
index 8add363..eb154ba6c40 100644
--- a/ash/public/cpp/resources/unscaled_resources/shortcut_viewer_logo_192.png
+++ b/ash/public/cpp/resources/unscaled_resources/shortcut_viewer_logo_192.png
Binary files differ
diff --git a/ash/search_box/search_box_view_base.cc b/ash/search_box/search_box_view_base.cc
index 2f945b8..ac2e4fe 100644
--- a/ash/search_box/search_box_view_base.cc
+++ b/ash/search_box/search_box_view_base.cc
@@ -175,19 +175,6 @@
   ~SearchBoxTextfield() override = default;
 
   // Overridden from views::View:
-  void ShowContextMenu(const gfx::Point& p,
-                       ui::MenuSourceType source_type) override {
-    views::View* selected_view =
-        search_box_view_->GetSelectedViewInContentsView();
-    if (source_type != ui::MENU_SOURCE_KEYBOARD || !selected_view) {
-      views::Textfield::ShowContextMenu(p, source_type);
-      return;
-    }
-    selected_view->ShowContextMenu(
-        selected_view->GetKeyboardContextMenuLocation(),
-        ui::MENU_SOURCE_KEYBOARD);
-  }
-
   void OnFocus() override {
     search_box_view_->OnSearchBoxFocusedChanged();
     Textfield::OnFocus();
@@ -451,10 +438,6 @@
   NotifyQueryChanged();
 }
 
-views::View* SearchBoxViewBase::GetSelectedViewInContentsView() {
-  return nullptr;
-}
-
 void SearchBoxViewBase::NotifyQueryChanged() {
   DCHECK(delegate_);
   delegate_->QueryChanged(this);
diff --git a/ash/search_box/search_box_view_base.h b/ash/search_box/search_box_view_base.h
index 0a8ada2..ac963e2 100644
--- a/ash/search_box/search_box_view_base.h
+++ b/ash/search_box/search_box_view_base.h
@@ -118,9 +118,6 @@
 
   virtual void ClearSearch();
 
-  // Returns selected view in contents view.
-  virtual views::View* GetSelectedViewInContentsView();
-
  protected:
   // Fires query change notification.
   void NotifyQueryChanged();
diff --git a/base/allocator/partition_allocator/partition_alloc.cc b/base/allocator/partition_allocator/partition_alloc.cc
index c00e46d..7c05850 100644
--- a/base/allocator/partition_allocator/partition_alloc.cc
+++ b/base/allocator/partition_allocator/partition_alloc.cc
@@ -320,7 +320,10 @@
   // this operation is idempotent, so there is no harm.
   InitBucketIndexLookup(this);
 
-#if !defined(PA_THREAD_CACHE_SUPPORTED)
+  // Temporarily disabled for PartitionAlloc-Everywhere builds on Windows, as it
+  // breaks the build.
+#if !defined(PA_THREAD_CACHE_SUPPORTED) || \
+    (defined(OS_WIN) && BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC))
   // TLS in ThreadCache not supported on other OSes.
   with_thread_cache = false;
 #else
@@ -329,7 +332,8 @@
 
   if (with_thread_cache)
     internal::ThreadCache::Init(this);
-#endif  // !defined(OS_POSIX)
+#endif  // !defined(PA_THREAD_CACHE_SUPPORTED) || \
+        // (defined(OS_WIN) && BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC))
 
   initialized = true;
 }
diff --git a/base/memory/checked_ptr.h b/base/memory/checked_ptr.h
index bde08373..92ec669 100644
--- a/base/memory/checked_ptr.h
+++ b/base/memory/checked_ptr.h
@@ -38,12 +38,8 @@
 #define CHECKED_PTR2_USE_NO_OP_WRAPPER 0
 #define CHECKED_PTR2_USE_TRIVIAL_UNWRAPPER 0
 
-// Set it to 1 to avoid branches when checking if per-pointer protection is
-// enabled.
-#define CHECKED_PTR2_AVOID_BRANCH_WHEN_CHECKING_ENABLED 0
 // Set it to 1 to avoid branches when dereferencing the pointer.
-// Must be 1 if the above is 1.
-#define CHECKED_PTR2_AVOID_BRANCH_WHEN_DEREFERENCING 0
+#define CHECKED_PTR2_AVOID_BRANCH_WHEN_DEREFERENCING 1
 
 namespace base {
 
@@ -159,20 +155,6 @@
   static ALWAYS_INLINE void* TagPointer(void* ptr) {
     return PartitionTagPointer(ptr);
   }
-
-#if CHECKED_PTR2_AVOID_BRANCH_WHEN_CHECKING_ENABLED
-  // Returns offset of the tag from the beginning of the slot. Works only with
-  // CheckedPtr2 algorithm.
-  static constexpr size_t TagOffset() {
-#if ENABLE_TAG_FOR_CHECKED_PTR2
-    return kPartitionTagOffset;
-#else
-    // Unreachable, but can't use NOTREACHED() due to constexpr. Return
-    // something weird so that the caller is very likely to crash.
-    return 0x87654321FEDCBA98;
-#endif
-  }
-#endif
 };
 #endif  // BUILDFLAG(USE_PARTITION_ALLOC) && ENABLE_CHECKED_PTR2_OR_MTE_IMPL
 
@@ -209,10 +191,6 @@
 
     generation <<= kValidAddressBits;
     addr |= generation;
-#if CHECKED_PTR2_AVOID_BRANCH_WHEN_CHECKING_ENABLED
-    // Always set top bit to 1, to indicated that the protection is enabled.
-    addr |= kTopBit;
-#endif  // CHECKED_PTR2_AVOID_BRANCH_WHEN_CHECKING_ENABLED
 #endif  // !CHECKED_PTR2_USE_NO_OP_WRAPPER
     return addr;
   }
@@ -231,86 +209,6 @@
   // hasn't been freed. The function is allowed to crash on nullptr.
   static ALWAYS_INLINE void* SafelyUnwrapPtrForDereference(
       uintptr_t wrapped_ptr) {
-#if CHECKED_PTR2_AVOID_BRANCH_WHEN_CHECKING_ENABLED
-    // This variant can only be used with CheckedPtr2 algorithm, because it
-    // relies on the generation to exist at a constant offset before the
-    // allocation.
-    static_assert(ENABLE_TAG_FOR_CHECKED_PTR2, "");
-
-    // Top bit tells if the protection is enabled. Use it to decide whether to
-    // read the word before the allocation, which exists only if the protection
-    // is enabled. Otherwise it may crash, in which case read the data from the
-    // beginning of the allocation instead and ignore it later. All this magic
-    // is to avoid a branch, for performance reasons.
-    //
-    // A couple examples, assuming 64-bit system (continued below):
-    //   Ex.1: wrapped_ptr=0x8442000012345678
-    //           => enabled=0x8000000000000000
-    //           => offset=1
-    //   Ex.2: wrapped_ptr=0x0000000012345678
-    //           => enabled=0x0000000000000000
-    //           => offset=0
-    uintptr_t enabled = wrapped_ptr & kTopBit;
-    // We can't have protection disabled and generation set in the same time.
-    DCHECK(!(enabled == 0 && (ExtractGeneration(wrapped_ptr)) != 0));
-    uintptr_t offset = enabled >> kTopBitShift;  // 0 or 1
-    // Use offset to decide if the generation should be read at the beginning or
-    // before the allocation.
-    // TODO(bartekn): Do something about 1-byte allocations. Reading 2-byte
-    // generation at the allocation could crash. This case is executed
-    // specifically for non-PartitionAlloc pointers, so we can't make
-    // assumptions about alignment.
-    //
-    // Cast to volatile to ensure memory is read. E.g. in a tight loop, the
-    // compiler could cache the value in a register and thus could miss that
-    // another thread freed memory and cleared generation.
-    //
-    // Examples (continued):
-    //   Ex.1: generation_ptr=0x0000000012345676
-    //     a) if pointee wasn't freed, read e.g. generation=0x0442 (could be
-    //        also 0x8442, the top bit is overwritten later)
-    //     b) if pointee was freed, read e.g. generation=0x1234 (could be
-    //        anything)
-    //   Ex.2: generation_ptr=0x0000000012345678, read e.g. 0x2345 (doesn't
-    //         matter what we read, as long as this read doesn't crash)
-    volatile PartitionTag* generation_ptr =
-        static_cast<volatile PartitionTag*>(ExtractPtr(wrapped_ptr)) -
-        offset * (PartitionAllocSupport::TagOffset() / sizeof(PartitionTag));
-    uintptr_t generation = *generation_ptr;
-    // Shift generation into the right place and add back the enabled bit.
-    //
-    // Examples (continued):
-    //   Ex.1:
-    //     a) generation=0x8442000000000000
-    //     a) generation=0x9234000000000000
-    //   Ex.2: generation=0x2345000000000000
-    generation <<= kValidAddressBits;
-    generation |= enabled;
-
-    // If the protection isn't enabled, clear top bits. Casting to a signed
-    // type makes >> sign extend the last bit.
-    //
-    // Examples (continued):
-    //   Ex.1: mask=0xffff000000000000
-    //     a) generation=0x8442000000000000
-    //     b) generation=0x9234000000000000
-    //   Ex.2: mask=0x0000000000000000 => generation=0x0000000000000000
-    uintptr_t mask = static_cast<intptr_t>(enabled) >> (kGenerationBits - 1);
-    generation &= mask;
-
-    // Use hardware to detect generation mismatch. CPU will crash if top bits
-    // aren't all 0 (technically it won't if all bits are 1, but that's a kernel
-    // mode address, which isn't allowed either... also, top bit will be always
-    // zeroed out).
-    //
-    // Examples (continued):
-    //   Ex.1:
-    //     a) returning 0x0000000012345678
-    //     b) returning 0x1676000012345678 (this will generate a desired crash)
-    //   Ex.2: returning 0x0000000012345678
-    static_assert(CHECKED_PTR2_AVOID_BRANCH_WHEN_DEREFERENCING, "");
-    return reinterpret_cast<void*>(generation ^ wrapped_ptr);
-#else  // CHECKED_PTR2_AVOID_BRANCH_WHEN_CHECKING_ENABLED
     uintptr_t ptr_generation = wrapped_ptr >> kValidAddressBits;
     if (ptr_generation > 0) {
       // Read the generation provided by PartitionAlloc.
@@ -333,25 +231,14 @@
 #endif  // CHECKED_PTR2_AVOID_BRANCH_WHEN_DEREFERENCING
     }
     return reinterpret_cast<void*>(wrapped_ptr);
-#endif  // CHECKED_PTR2_AVOID_BRANCH_WHEN_CHECKING_ENABLED
   }
 
   // Unwraps the pointer's uintptr_t representation, while asserting that memory
   // hasn't been freed. The function must handle nullptr gracefully.
   static ALWAYS_INLINE void* SafelyUnwrapPtrForExtraction(
       uintptr_t wrapped_ptr) {
-#if CHECKED_PTR2_AVOID_BRANCH_WHEN_CHECKING_ENABLED
-    // In this implementation, SafelyUnwrapPtrForDereference doesn't tolerate
-    // nullptr, because it reads unconditionally to avoid branches. Handle the
-    // nullptr case here.
-    if (wrapped_ptr == kWrappedNullPtr)
-      return nullptr;
+    // SafelyUnwrapPtrForDereference handles nullptr case well.
     return SafelyUnwrapPtrForDereference(wrapped_ptr);
-#else
-    // In this implementation, SafelyUnwrapPtrForDereference handles nullptr
-    // case well.
-    return SafelyUnwrapPtrForDereference(wrapped_ptr);
-#endif
   }
 
   // Unwraps the pointer's uintptr_t representation, without making an assertion
diff --git a/base/memory/checked_ptr_unittest.cc b/base/memory/checked_ptr_unittest.cc
index 8f5d9bc..38586ac 100644
--- a/base/memory/checked_ptr_unittest.cc
+++ b/base/memory/checked_ptr_unittest.cc
@@ -719,10 +719,6 @@
   static ALWAYS_INLINE void* TagPointer(void* ptr) {
     return static_cast<char*>(ptr) - kTagOffsetForTest;
   }
-
-#if CHECKED_PTR2_AVOID_BRANCH_WHEN_CHECKING_ENABLED
-  static constexpr size_t TagOffset() { return kTagOffsetForTest; }
-#endif
 };
 
 using CheckedPtr2OrMTEImplForTest =
@@ -748,10 +744,6 @@
   ASSERT_EQ(0x78, *static_cast<char*>(ptr));
   uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
 
-  uintptr_t set_top_bit = 0x0000000000000000;
-#if CHECKED_PTR2_AVOID_BRANCH_WHEN_CHECKING_ENABLED
-  set_top_bit = 0x8000000000000000;
-#endif
   uintptr_t mask = 0xFFFFFFFFFFFFFFFF;
   if (sizeof(PartitionTag) < 2)
     mask = 0x00FFFFFFFFFFFFFF;
@@ -761,10 +753,9 @@
   // order due to little-endianness).
 #if CHECKED_PTR2_USE_NO_OP_WRAPPER
   ASSERT_EQ(wrapped, addr);
-  std::ignore = set_top_bit;
   std::ignore = mask;
 #else
-  ASSERT_EQ(wrapped, (addr | 0x42BA000000000000) & mask | set_top_bit);
+  ASSERT_EQ(wrapped, (addr | 0x42BA000000000000) & mask);
 #endif
   ASSERT_EQ(CheckedPtr2OrMTEImplForTest::SafelyUnwrapPtrForDereference(wrapped),
             ptr);
@@ -775,7 +766,7 @@
 #if CHECKED_PTR2_USE_NO_OP_WRAPPER
   ASSERT_EQ(wrapped, addr);
 #else
-  ASSERT_EQ(wrapped, (addr | 0x42FA000000000000) & mask | set_top_bit);
+  ASSERT_EQ(wrapped, (addr | 0x42FA000000000000) & mask);
 #endif
   ASSERT_EQ(CheckedPtr2OrMTEImplForTest::SafelyUnwrapPtrForDereference(wrapped),
             ptr);
@@ -784,16 +775,12 @@
   // Clear the generation associated with the fake allocation.
   bytes[0] = 0;
   bytes[1] = 0;
-#if CHECKED_PTR2_AVOID_BRANCH_WHEN_CHECKING_ENABLED
-  mask &= 0x7FFFFFFFFFFFFFFF;
-#endif
 
   // Mask out the top bit, because in some cases (not all), it may differ.
   ASSERT_EQ(
       reinterpret_cast<uintptr_t>(
-          CheckedPtr2OrMTEImplForTest::SafelyUnwrapPtrForDereference(wrapped)) &
-          mask,
-      wrapped & mask);
+          CheckedPtr2OrMTEImplForTest::SafelyUnwrapPtrForDereference(wrapped)),
+      wrapped);
 #endif  // CHECKED_PTR2_AVOID_BRANCH_WHEN_DEREFERENCING
 }
 
diff --git a/base/metrics/sparse_histogram_unittest.cc b/base/metrics/sparse_histogram_unittest.cc
index 4bada66..1376e851 100644
--- a/base/metrics/sparse_histogram_unittest.cc
+++ b/base/metrics/sparse_histogram_unittest.cc
@@ -400,10 +400,10 @@
 TEST_P(SparseHistogramTest, CheckGetCountAndBucketData) {
   std::unique_ptr<SparseHistogram> histogram(NewSparseHistogram("Sparse"));
   // Add samples in reverse order and make sure the output is in correct order.
-  histogram->AddCount(/*sample=*/200, /*value=*/15);
-  histogram->AddCount(/*sample=*/100, /*value=*/5);
+  histogram->AddCount(/*sample=*/200, /*count=*/15);
+  histogram->AddCount(/*sample=*/100, /*count=*/5);
   // Add samples to the same bucket and make sure they'll be aggregated.
-  histogram->AddCount(/*sample=*/100, /*value=*/5);
+  histogram->AddCount(/*sample=*/100, /*count=*/5);
 
   base::Histogram::Count total_count;
   int64_t sum;
@@ -438,8 +438,8 @@
 TEST_P(SparseHistogramTest, WriteAscii) {
   HistogramBase* histogram =
       SparseHistogram::FactoryGet("AsciiOut", HistogramBase::kNoFlags);
-  histogram->AddCount(/*sample=*/4, /*value=*/5);
-  histogram->AddCount(/*sample=*/10, /*value=*/15);
+  histogram->AddCount(/*sample=*/4, /*count=*/5);
+  histogram->AddCount(/*sample=*/10, /*count=*/15);
 
   std::string output;
   histogram->WriteAscii(&output);
@@ -455,8 +455,8 @@
 TEST_P(SparseHistogramTest, ToGraphDict) {
   HistogramBase* histogram =
       SparseHistogram::FactoryGet("HTMLOut", HistogramBase::kNoFlags);
-  histogram->AddCount(/*sample=*/4, /*value=*/5);
-  histogram->AddCount(/*sample=*/10, /*value=*/15);
+  histogram->AddCount(/*sample=*/4, /*count=*/5);
+  histogram->AddCount(/*sample=*/10, /*count=*/15);
 
   base::DictionaryValue output = histogram->ToGraphDict();
   std::string* header = output.FindStringKey("header");
diff --git a/base/task/post_job.h b/base/task/post_job.h
index 7063379..59d8167 100644
--- a/base/task/post_job.h
+++ b/base/task/post_job.h
@@ -36,7 +36,7 @@
               internal::PooledTaskRunnerDelegate* pooled_task_runner_delegate);
   ~JobDelegate();
 
-  // Returns true if this thread should return from the worker task on the
+  // Returns true if this thread *must* return from the worker task on the
   // current thread ASAP. Workers should periodically invoke ShouldYield (or
   // YieldIfNeeded()) as often as is reasonable.
   bool ShouldYield();
diff --git a/base/task/thread_pool/job_task_source_unittest.cc b/base/task/thread_pool/job_task_source_unittest.cc
index e8e98b0..2c98944 100644
--- a/base/task/thread_pool/job_task_source_unittest.cc
+++ b/base/task/thread_pool/job_task_source_unittest.cc
@@ -27,7 +27,7 @@
  public:
   MOCK_METHOD2(PostTaskWithSequence,
                bool(Task task, scoped_refptr<Sequence> sequence));
-  MOCK_CONST_METHOD1(ShouldYield, bool(const TaskSource* task_source));
+  MOCK_METHOD1(ShouldYield, bool(const TaskSource* task_source));
   MOCK_METHOD1(EnqueueJobTaskSource,
                bool(scoped_refptr<JobTaskSource> task_source));
   MOCK_METHOD1(RemoveJobTaskSource,
diff --git a/base/task/thread_pool/pooled_task_runner_delegate.h b/base/task/thread_pool/pooled_task_runner_delegate.h
index b4db5e3..05aac04 100644
--- a/base/task/thread_pool/pooled_task_runner_delegate.h
+++ b/base/task/thread_pool/pooled_task_runner_delegate.h
@@ -27,10 +27,10 @@
   // outlives the ThreadPoolInstance that created it.
   static bool Exists();
 
-  // Returns true if |task_source| currently running must return ASAP.
+  // Returns true if |task_source| currently running *must* return ASAP.
   // Thread-safe but may return an outdated result (if a task unnecessarily
   // yields due to this, it will simply be re-scheduled).
-  virtual bool ShouldYield(const TaskSource* task_source) const = 0;
+  virtual bool ShouldYield(const TaskSource* task_source) = 0;
 
   // Invoked when a |task| is posted to the PooledParallelTaskRunner or
   // PooledSequencedTaskRunner. The implementation must post |task| to
diff --git a/base/task/thread_pool/test_utils.cc b/base/task/thread_pool/test_utils.cc
index 738f1d24..470d3048 100644
--- a/base/task/thread_pool/test_utils.cc
+++ b/base/task/thread_pool/test_utils.cc
@@ -203,8 +203,7 @@
   }
 }
 
-bool MockPooledTaskRunnerDelegate::ShouldYield(
-    const TaskSource* task_source) const {
+bool MockPooledTaskRunnerDelegate::ShouldYield(const TaskSource* task_source) {
   return thread_group_->ShouldYield(task_source->GetSortKey());
 }
 
diff --git a/base/task/thread_pool/test_utils.h b/base/task/thread_pool/test_utils.h
index 3d13b4a..987b3d3 100644
--- a/base/task/thread_pool/test_utils.h
+++ b/base/task/thread_pool/test_utils.h
@@ -63,7 +63,7 @@
                             scoped_refptr<Sequence> sequence) override;
   bool EnqueueJobTaskSource(scoped_refptr<JobTaskSource> task_source) override;
   void RemoveJobTaskSource(scoped_refptr<JobTaskSource> task_source) override;
-  bool ShouldYield(const TaskSource* task_source) const override;
+  bool ShouldYield(const TaskSource* task_source) override;
   void UpdatePriority(scoped_refptr<TaskSource> task_source,
                       TaskPriority priority) override;
 
diff --git a/base/task/thread_pool/thread_group.cc b/base/task/thread_pool/thread_group.cc
index a6f0c73..9d5f7b9 100644
--- a/base/task/thread_pool/thread_group.cc
+++ b/base/task/thread_pool/thread_group.cc
@@ -34,6 +34,8 @@
 
 }  // namespace
 
+constexpr ThreadGroup::YieldSortKey ThreadGroup::kMaxYieldSortKey;
+
 void ThreadGroup::BaseScopedCommandsExecutor::ScheduleReleaseTaskSource(
     RegisteredTaskSource task_source) {
   task_sources_to_release_.push_back(std::move(task_source));
@@ -245,7 +247,8 @@
   replacement_thread_group_ = destination_thread_group;
 }
 
-bool ThreadGroup::ShouldYield(TaskSourceSortKey sort_key) const {
+bool ThreadGroup::ShouldYield(TaskSourceSortKey sort_key) {
+  DCHECK(TS_UNCHECKED_READ(max_allowed_sort_key_).is_lock_free());
   if (!task_tracker_->CanRunPriority(sort_key.priority()))
     return true;
   // It is safe to read |max_allowed_sort_key_| without a lock since this
@@ -253,8 +256,7 @@
   // the new value when it is updated.
   auto max_allowed_sort_key =
       TS_UNCHECKED_READ(max_allowed_sort_key_).load(std::memory_order_relaxed);
-  if (sort_key.priority() < max_allowed_sort_key.priority)
-    return true;
+
   // To reduce unnecessary yielding, a task will never yield to a BEST_EFFORT
   // task regardless of its worker_count.
   if (sort_key.priority() > max_allowed_sort_key.priority ||
@@ -264,7 +266,19 @@
   // Otherwise, a task only yields to a task of equal priority if its
   // worker_count would be greater still after yielding, e.g. a job with 1
   // worker doesn't yield to a job with 0 workers.
-  return sort_key.worker_count() > max_allowed_sort_key.worker_count + 1;
+  if (sort_key.priority() == max_allowed_sort_key.priority &&
+      sort_key.worker_count() <= max_allowed_sort_key.worker_count + 1) {
+    return false;
+  }
+
+  // Reset |max_allowed_sort_key_| so that only one thread should yield at a
+  // time for a given task.
+  max_allowed_sort_key =
+      TS_UNCHECKED_READ(max_allowed_sort_key_)
+          .exchange(kMaxYieldSortKey, std::memory_order_relaxed);
+  // Another thread might have decided to yield and racily reset
+  // |max_allowed_sort_key_|, in which case this thread doesn't yield.
+  return max_allowed_sort_key.priority != TaskPriority::BEST_EFFORT;
 }
 
 #if defined(OS_WIN)
diff --git a/base/task/thread_pool/thread_group.h b/base/task/thread_pool/thread_group.h
index 59cc62d..66f5c50 100644
--- a/base/task/thread_pool/thread_group.h
+++ b/base/task/thread_pool/thread_group.h
@@ -97,7 +97,7 @@
   // work of higher priority is pending. Thread-safe but may return an outdated
   // result (if a task unnecessarily yields due to this, it will simply be
   // re-scheduled).
-  bool ShouldYield(TaskSourceSortKey sort_key) const;
+  bool ShouldYield(TaskSourceSortKey sort_key);
 
   // Prevents new tasks from starting to run and waits for currently running
   // tasks to complete their execution. It is guaranteed that no thread will do
@@ -228,17 +228,21 @@
     TaskPriority priority;
     uint8_t worker_count;
   };
+  // Sort key which compares greater than or equal to any other sort key.
+  static constexpr YieldSortKey kMaxYieldSortKey = {TaskPriority::BEST_EFFORT,
+                                                    0U};
 
-  // When the thread group is at or above capacity and has pending work, this
-  // contains the priority and worker count of the next TaskSource to schedule.
-  // Otherwise, it contains |priority| = BEST_EFFORT and |worker_count| = 0.
-  // This is used to decide whether a TaskSource should yield. This is expected
-  // to be always kept up-to-date by derived classes when |lock_| is released.
-  // It is annotated as GUARDED_BY(lock_) because it is always updated under the
-  // lock (to avoid races with other state during the update) but it is
-  // nonetheless always safe to read it without the lock (since it's atomic).
+  // When the thread group is at or above capacity and has pending work, this is
+  // set to contain the priority and worker count of the next TaskSource to
+  // schedule, or kMaxYieldSortKey otherwise. This is used to decide whether a
+  // TaskSource should yield. Once ShouldYield() returns true, it is reset to
+  // kMaxYieldSortKey to prevent additional from unnecessary yielding. This is
+  // expected to be always kept up-to-date by derived classes when |lock_| is
+  // released. It is annotated as GUARDED_BY(lock_) because it is always updated
+  // under the lock (to avoid races with other state during the update) but it
+  // is nonetheless always safe to read it without the lock (since it's atomic).
   std::atomic<YieldSortKey> max_allowed_sort_key_ GUARDED_BY(lock_){
-      {TaskPriority::BEST_EFFORT, 0U}};
+      kMaxYieldSortKey};
 
   // If |replacement_thread_group_| is non-null, this ThreadGroup is invalid and
   // all task sources should be scheduled on |replacement_thread_group_|. Used
diff --git a/base/task/thread_pool/thread_group_impl.cc b/base/task/thread_pool/thread_group_impl.cc
index 67e0b0e..c911c47 100644
--- a/base/task/thread_pool/thread_group_impl.cc
+++ b/base/task/thread_pool/thread_group_impl.cc
@@ -1115,8 +1115,7 @@
 
 void ThreadGroupImpl::UpdateMinAllowedPriorityLockRequired() {
   if (priority_queue_.IsEmpty() || num_running_tasks_ < max_tasks_) {
-    max_allowed_sort_key_.store({TaskPriority::BEST_EFFORT, 0},
-                                std::memory_order_relaxed);
+    max_allowed_sort_key_.store(kMaxYieldSortKey, std::memory_order_relaxed);
   } else {
     max_allowed_sort_key_.store({priority_queue_.PeekSortKey().priority(),
                                  priority_queue_.PeekSortKey().worker_count()},
diff --git a/base/task/thread_pool/thread_group_impl_unittest.cc b/base/task/thread_pool/thread_group_impl_unittest.cc
index 911c792..68d29a4 100644
--- a/base/task/thread_pool/thread_group_impl_unittest.cc
+++ b/base/task/thread_pool/thread_group_impl_unittest.cc
@@ -344,18 +344,23 @@
 
   // Posting a USER_VISIBLE task should cause BEST_EFFORT and USER_VISIBLE with
   // higher worker_count tasks to yield.
-  test::CreatePooledTaskRunner({TaskPriority::USER_VISIBLE},
-                               &mock_pooled_task_runner_delegate_)
-      ->PostTask(FROM_HERE, BindLambdaForTesting([&]() {
-                   EXPECT_FALSE(thread_group_->ShouldYield(
-                       {TaskPriority::USER_VISIBLE, TimeTicks(),
-                        /* worker_count=*/1}));
-                 }));
+  auto post_user_visible = [&]() {
+    test::CreatePooledTaskRunner({TaskPriority::USER_VISIBLE},
+                                 &mock_pooled_task_runner_delegate_)
+        ->PostTask(FROM_HERE, BindLambdaForTesting([&]() {
+                     EXPECT_FALSE(thread_group_->ShouldYield(
+                         {TaskPriority::USER_VISIBLE, TimeTicks(),
+                          /* worker_count=*/1}));
+                   }));
+  };
   // A USER_VISIBLE task with too many workers should yield.
+  post_user_visible();
   EXPECT_TRUE(thread_group_->ShouldYield(
       {TaskPriority::USER_VISIBLE, TimeTicks(), /* worker_count=*/2}));
+  post_user_visible();
   EXPECT_TRUE(thread_group_->ShouldYield(
       {TaskPriority::BEST_EFFORT, TimeTicks(), /* worker_count=*/0}));
+  post_user_visible();
   EXPECT_FALSE(thread_group_->ShouldYield(
       {TaskPriority::USER_VISIBLE, TimeTicks(), /* worker_count=*/1}));
   EXPECT_FALSE(thread_group_->ShouldYield(
@@ -363,21 +368,28 @@
 
   // Posting a USER_BLOCKING task should cause BEST_EFFORT, USER_VISIBLE and
   // USER_BLOCKING with higher worker_count tasks to yield.
-  test::CreatePooledTaskRunner({TaskPriority::USER_BLOCKING},
-                               &mock_pooled_task_runner_delegate_)
-      ->PostTask(FROM_HERE, BindLambdaForTesting([&]() {
-                   // Once this task got to start, no other task needs to yield.
-                   EXPECT_FALSE(thread_group_->ShouldYield(
-                       {TaskPriority::USER_BLOCKING, TimeTicks(),
-                        /* worker_count=*/1}));
-                 }));
+  auto post_user_blocking = [&]() {
+    test::CreatePooledTaskRunner({TaskPriority::USER_BLOCKING},
+                                 &mock_pooled_task_runner_delegate_)
+        ->PostTask(FROM_HERE, BindLambdaForTesting([&]() {
+                     // Once this task got to start, no other task needs to
+                     // yield.
+                     EXPECT_FALSE(thread_group_->ShouldYield(
+                         {TaskPriority::USER_BLOCKING, TimeTicks(),
+                          /* worker_count=*/1}));
+                   }));
+  };
   // A USER_BLOCKING task with too many workers should have to yield.
+  post_user_blocking();
   EXPECT_TRUE(thread_group_->ShouldYield(
       {TaskPriority::USER_BLOCKING, TimeTicks(), /* worker_count=*/2}));
+  post_user_blocking();
   EXPECT_TRUE(thread_group_->ShouldYield(
       {TaskPriority::BEST_EFFORT, TimeTicks(), /* worker_count=*/0}));
+  post_user_blocking();
   EXPECT_TRUE(thread_group_->ShouldYield(
       {TaskPriority::USER_VISIBLE, TimeTicks(), /* worker_count=*/0}));
+  post_user_blocking();
   EXPECT_FALSE(thread_group_->ShouldYield(
       {TaskPriority::USER_BLOCKING, TimeTicks(), /* worker_count=*/1}));
 
diff --git a/base/task/thread_pool/thread_group_native.cc b/base/task/thread_pool/thread_group_native.cc
index 39d8828..b689cb8 100644
--- a/base/task/thread_pool/thread_group_native.cc
+++ b/base/task/thread_pool/thread_group_native.cc
@@ -103,8 +103,7 @@
   // Tasks should yield as soon as there is work of higher priority in
   // |priority_queue_|.
   if (priority_queue_.IsEmpty()) {
-    max_allowed_sort_key_.store({TaskPriority::BEST_EFFORT, 0},
-                                std::memory_order_relaxed);
+    max_allowed_sort_key_.store(kMaxYieldSortKey, std::memory_order_relaxed);
   } else {
     max_allowed_sort_key_.store({priority_queue_.PeekSortKey().priority(),
                                  priority_queue_.PeekSortKey().worker_count()},
diff --git a/base/task/thread_pool/thread_pool_impl.cc b/base/task/thread_pool/thread_pool_impl.cc
index cce0da5..ed84c6cc 100644
--- a/base/task/thread_pool/thread_pool_impl.cc
+++ b/base/task/thread_pool/thread_pool_impl.cc
@@ -429,7 +429,7 @@
   return true;
 }
 
-bool ThreadPoolImpl::ShouldYield(const TaskSource* task_source) const {
+bool ThreadPoolImpl::ShouldYield(const TaskSource* task_source) {
   const TaskPriority priority = task_source->priority_racy();
   auto* const thread_group =
       GetThreadGroupForTraits({priority, task_source->thread_policy()});
diff --git a/base/task/thread_pool/thread_pool_impl.h b/base/task/thread_pool/thread_pool_impl.h
index 512f29c..0069b06 100644
--- a/base/task/thread_pool/thread_pool_impl.h
+++ b/base/task/thread_pool/thread_pool_impl.h
@@ -149,7 +149,7 @@
   // PooledTaskRunnerDelegate:
   bool PostTaskWithSequence(Task task,
                             scoped_refptr<Sequence> sequence) override;
-  bool ShouldYield(const TaskSource* task_source) const override;
+  bool ShouldYield(const TaskSource* task_source) override;
 
   const std::unique_ptr<TaskTrackerImpl> task_tracker_;
   std::unique_ptr<Thread> service_thread_;
diff --git a/build/android/gyp/proguard.py b/build/android/gyp/proguard.py
index 9975ad69..79d0f1ab 100755
--- a/build/android/gyp/proguard.py
+++ b/build/android/gyp/proguard.py
@@ -288,7 +288,15 @@
       for main_dex_rule in options.main_dex_rules_path:
         cmd += ['--main-dex-rules', main_dex_rule]
 
-    module_input_jars = set(base_dex_context.input_paths)
+    base_jars = set(base_dex_context.input_paths)
+    # If a jar is present in multiple features, it should be moved to the base
+    # module.
+    all_feature_jars = set()
+    for feature in feature_contexts:
+      base_jars.update(all_feature_jars.intersection(feature.input_paths))
+      all_feature_jars.update(feature.input_paths)
+
+    module_input_jars = base_jars.copy()
     for feature in feature_contexts:
       feature_input_jars = [
           p for p in feature.input_paths if p not in module_input_jars
@@ -297,7 +305,7 @@
       for in_jar in feature_input_jars:
         cmd += ['--feature', in_jar, feature.staging_dir]
 
-    cmd += base_dex_context.input_paths
+    cmd += sorted(base_jars)
     # Add any extra input jars to the base module (e.g. desugar runtime).
     extra_jars = set(options.input_paths) - module_input_jars
     cmd += sorted(extra_jars)
diff --git a/build/android/pylib/results/json_results.py b/build/android/pylib/results/json_results.py
index 38ede80e..4a97842 100644
--- a/build/android/pylib/results/json_results.py
+++ b/build/android/pylib/results/json_results.py
@@ -122,8 +122,7 @@
   """
 
   tests = {}
-  pass_count = 0
-  fail_count = 0
+  counts = {'PASS': 0, 'FAIL': 0}
 
   for test_run_result in test_run_results:
     if isinstance(test_run_result, list):
@@ -140,12 +139,16 @@
 
       element['expected'] = 'PASS'
 
-      if r.GetType() == base_test_result.ResultType.PASS:
-        element['actual'] = 'PASS'
-        pass_count += 1
+      result = 'PASS' if r.GetType(
+      ) == base_test_result.ResultType.PASS else 'FAIL'
+
+      if 'actual' in element:
+        element['actual'] += ' ' + result
       else:
-        element['actual'] = 'FAIL'
-        fail_count += 1
+        counts[result] += 1
+        element['actual'] = result
+        if result == 'FAIL':
+          element['is_unexpected'] = True
 
       if r.GetDuration() != 0:
         element['time'] = r.GetDuration()
@@ -153,10 +156,7 @@
   # Fill in required fields.
   return {
       'interrupted': False,
-      'num_failures_by_type': {
-          'FAIL': fail_count,
-          'PASS': pass_count,
-      },
+      'num_failures_by_type': counts,
       'path_delimiter': '.',
       'seconds_since_epoch': time.time(),
       'tests': tests,
diff --git a/build/android/pylib/results/json_results_test.py b/build/android/pylib/results/json_results_test.py
index 2c1a422..ac26c2c3 100755
--- a/build/android/pylib/results/json_results_test.py
+++ b/build/android/pylib/results/json_results_test.py
@@ -219,6 +219,10 @@
     self.assertEquals(
         'PASS', results_dict['tests']['test']['package']['TestName']['actual'])
 
+    # Note: technically a missing entry counts as zero.
+    self.assertEquals(1, results_dict['num_failures_by_type']['PASS'])
+    self.assertEquals(0, results_dict['num_failures_by_type']['FAIL'])
+
   def testGenerateJsonTestResultFormatDict_failedResult(self):
     result = base_test_result.BaseTestResult('test.package.TestName',
                                              base_test_result.ResultType.FAIL)
@@ -235,6 +239,50 @@
         results_dict['tests']['test']['package']['TestName']['expected'])
     self.assertEquals(
         'FAIL', results_dict['tests']['test']['package']['TestName']['actual'])
+    self.assertEquals(
+        True,
+        results_dict['tests']['test']['package']['TestName']['is_unexpected'])
+    self.assertEquals(2, len(results_dict['num_failures_by_type']))
+
+    # Note: technically a missing entry counts as zero.
+    self.assertEquals(0, results_dict['num_failures_by_type']['PASS'])
+    self.assertEquals(1, results_dict['num_failures_by_type']['FAIL'])
+
+  def testGenerateJsonTestResultFormatDict_failedResultWithRetry(self):
+    result_1 = base_test_result.BaseTestResult('test.package.TestName',
+                                               base_test_result.ResultType.FAIL)
+    run_results_1 = base_test_result.TestRunResults()
+    run_results_1.AddResult(result_1)
+
+    # Simulate a second retry with failure.
+    result_2 = base_test_result.BaseTestResult('test.package.TestName',
+                                               base_test_result.ResultType.FAIL)
+    run_results_2 = base_test_result.TestRunResults()
+    run_results_2.AddResult(result_2)
+
+    all_results = [run_results_1, run_results_2]
+
+    results_dict = json_results.GenerateJsonTestResultFormatDict(all_results)
+    self.assertEquals(1, len(results_dict['tests']))
+    self.assertEquals(1, len(results_dict['tests']['test']))
+    self.assertEquals(1, len(results_dict['tests']['test']['package']))
+    self.assertEquals(
+        'PASS',
+        results_dict['tests']['test']['package']['TestName']['expected'])
+    self.assertEquals(
+        'FAIL FAIL',
+        results_dict['tests']['test']['package']['TestName']['actual'])
+    self.assertEquals(
+        True,
+        results_dict['tests']['test']['package']['TestName']['is_unexpected'])
+
+    # Note: technically a missing entry counts as zero.
+    self.assertEquals(2, len(results_dict['num_failures_by_type']))
+    self.assertEquals(0, results_dict['num_failures_by_type']['PASS'])
+
+    # According to the spec: If a test was run more than once, only the first
+    # invocation's result is included in the totals.
+    self.assertEquals(1, results_dict['num_failures_by_type']['FAIL'])
 
 
 if __name__ == '__main__':
diff --git a/build/args/headless.gn b/build/args/headless.gn
index 4c2e8d9ff..f5f6607 100644
--- a/build/args/headless.gn
+++ b/build/args/headless.gn
@@ -48,3 +48,4 @@
 
 # TODO(1096425): Remove this once use_x11 goes away.
 use_x11 = false
+dawn_use_x11 = false
diff --git a/build/config/fuchsia/config.gni b/build/config/fuchsia/config.gni
index b32fe9a..8e9e2be 100644
--- a/build/config/fuchsia/config.gni
+++ b/build/config/fuchsia/config.gni
@@ -4,10 +4,8 @@
 
 assert(is_fuchsia)
 
-# Compute the emulator paths.
+# Compute the AEMU path.
 aemu_root = "//third_party/aemu-${host_os}-${host_cpu}"
-qemu_root = "//third_party/qemu-${host_os}-${host_cpu}"
-qemu_arm64_root = "//third_party/qemu-${host_os}-arm64"
 
 # Compute the path to the arch-specific boot image directory.
 boot_image_root = "//third_party/fuchsia-sdk/images/${target_cpu}"
diff --git a/build/config/fuchsia/generate_runner_scripts.gni b/build/config/fuchsia/generate_runner_scripts.gni
index 05d4752c..84b7b5b 100644
--- a/build/config/fuchsia/generate_runner_scripts.gni
+++ b/build/config/fuchsia/generate_runner_scripts.gni
@@ -17,12 +17,13 @@
   # will be used.
   default_fuchsia_build_dir_for_installation = ""
 
-  # Architecture of the host tools included in Fuchsia test targets.
-  # Defaults to target_cpu.
-  fuchsia_override_host_tool_arch_for_isolated_testing = target_cpu
+  # CPU architecture of the host used to run the tests.
+  test_host_cpu = host_cpu
 
-  # A list that contains additional Fuchsia boot images to include in the test
-  # targets.
+  # Sets whether emulators need to be included in the test isolates
+  test_isolate_uses_emulator = true
+
+  # A list of additional Fuchsia boot images to include in the test isolates.
   fuchsia_additional_boot_images = []
 }
 
@@ -101,31 +102,40 @@
       "//third_party/fuchsia-sdk/sdk/bin/fpave.sh",
       "//third_party/fuchsia-sdk/sdk/bin/fuchsia-common.sh",
       "//third_party/fuchsia-sdk/sdk/meta/manifest.json",
-      "${boot_image_root}/qemu/qemu-kernel.kernel",
-      "${boot_image_root}/qemu/storage-full.blk",
-      "${boot_image_root}/qemu/zircon-a.zbi",
     ]
 
-    if (host_cpu == "x64" && (host_os == "linux" || host_os == "mac")) {
-      data += [ "${aemu_root}/" ]
+    # TODO(crbug.com/1137662): Remove checkout_fuchsia_for_arm64_host from
+    # gclient_gn_args in //DEPS as well as this condition when builders have
+    # test_host_cpu set correctly.
+    if (checkout_fuchsia_for_arm64_host) {
+      test_host_cpu = "arm64"
+    }
+
+    if (test_host_cpu == "x64") {
+      data += [ "//third_party/llvm-build/Release+Asserts/bin/llvm-symbolizer" ]
     }
 
     data += [
-      "//third_party/fuchsia-sdk/sdk/tools/${fuchsia_override_host_tool_arch_for_isolated_testing}/device-finder",
-      "//third_party/fuchsia-sdk/sdk/tools/${fuchsia_override_host_tool_arch_for_isolated_testing}/fvm",
-      "//third_party/fuchsia-sdk/sdk/tools/${fuchsia_override_host_tool_arch_for_isolated_testing}/merkleroot",
-      "//third_party/fuchsia-sdk/sdk/tools/${fuchsia_override_host_tool_arch_for_isolated_testing}/pm",
-      "//third_party/fuchsia-sdk/sdk/tools/${fuchsia_override_host_tool_arch_for_isolated_testing}/symbolize",
-      "//third_party/fuchsia-sdk/sdk/tools/${fuchsia_override_host_tool_arch_for_isolated_testing}/zbi",
+      "//third_party/fuchsia-sdk/sdk/tools/${test_host_cpu}/device-finder",
+      "//third_party/fuchsia-sdk/sdk/tools/${test_host_cpu}/fvm",
+      "//third_party/fuchsia-sdk/sdk/tools/${test_host_cpu}/merkleroot",
+      "//third_party/fuchsia-sdk/sdk/tools/${test_host_cpu}/pm",
+      "//third_party/fuchsia-sdk/sdk/tools/${test_host_cpu}/symbolize",
+      "//third_party/fuchsia-sdk/sdk/tools/${test_host_cpu}/zbi",
     ]
 
-    if (target_cpu == "arm64") {
-      data += [ "${qemu_arm64_root}/" ]
-    } else {
+    if (test_isolate_uses_emulator) {
       data += [
-        "${qemu_root}/",
-        "//third_party/llvm-build/Release+Asserts/bin/llvm-symbolizer",
+        "${boot_image_root}/qemu/qemu-kernel.kernel",
+        "${boot_image_root}/qemu/storage-full.blk",
+        "${boot_image_root}/qemu/zircon-a.zbi",
+        "//third_party/qemu-${host_os}-${test_host_cpu}/",
       ]
+
+      # Include AEMU for x64 emulator hosts.
+      if (test_host_cpu == "x64") {
+        data += [ "${aemu_root}/" ]
+      }
     }
 
     foreach(fuchsia_additional_boot_image, fuchsia_additional_boot_images) {
diff --git a/build/config/win/BUILD.gn b/build/config/win/BUILD.gn
index 615efc5..4cae6b9 100644
--- a/build/config/win/BUILD.gn
+++ b/build/config/win/BUILD.gn
@@ -383,7 +383,6 @@
 # tests with the full browser.
 config("delayloads") {
   ldflags = [
-    "/DELAYLOAD:api-ms-win-core-path-l1-1-0.dll",
     "/DELAYLOAD:api-ms-win-core-winrt-error-l1-1-0.dll",
     "/DELAYLOAD:api-ms-win-core-winrt-l1-1-0.dll",
     "/DELAYLOAD:api-ms-win-core-winrt-string-l1-1-0.dll",
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index 53227bc..2affec6a 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-0.20201014.2.1
+0.20201014.3.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index 7d7fc21..2affec6a 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-0.20201014.1.1
+0.20201014.3.1
diff --git a/build/fuchsia/qemu_target.py b/build/fuchsia/qemu_target.py
index d43e9d3..47cb7a3 100644
--- a/build/fuchsia/qemu_target.py
+++ b/build/fuchsia/qemu_target.py
@@ -72,8 +72,9 @@
                       'in for the change to take effect.'
         raise FuchsiaTargetException(kvm_error)
       else:
-        raise FuchsiaTargetException('KVM unavailable when CPU architecture of'\
-                                     ' host is different from that of target.')
+        raise FuchsiaTargetException('KVM unavailable when CPU architecture '\
+                                     'of host is different from that of'\
+                                     ' target. See --allow-no-kvm.')
     else:
       return False
 
@@ -146,7 +147,7 @@
       else:
         kvm_command.append('host,migratable=no,+invtsc')
     else:
-      logging.warning('Unable to launch %s with KVM acceleration.'
+      logging.warning('Unable to launch %s with KVM acceleration. '
                       'The guest VM will be slow.' % (self.EMULATOR_NAME))
       if self._target_cpu == 'arm64':
         kvm_command = ['-cpu', 'cortex-a53']
diff --git a/build/fuchsia/update_images.py b/build/fuchsia/update_images.py
index 165ae77..790c6ac7 100755
--- a/build/fuchsia/update_images.py
+++ b/build/fuchsia/update_images.py
@@ -128,13 +128,13 @@
     try:
       DownloadSdkBootImages(bucket, sdk_hash, args.boot_images,
                             args.image_root_dir)
+      with open(signature_filename, 'w') as f:
+        f.write(new_signature)
+
     except subprocess.CalledProcessError as e:
       logging.error(("command '%s' failed with status %d.%s"), " ".join(e.cmd),
                     e.returncode, " Details: " + e.output if e.output else "")
 
-    with open(signature_filename, 'w') as f:
-      f.write(new_signature)
-
   return 0
 
 
diff --git a/chrome/VERSION b/chrome/VERSION
index 1359219..a290c17 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=88
 MINOR=0
-BUILD=4293
+BUILD=4294
 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index f1eb99b5..f9395c95 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -2075,7 +2075,7 @@
   ]
   deps = [
     ":base_module_java",
-    "//android_webview:android_webview_java",
+    "//android_webview:android_webview_no_weblayer_java",
     "//base:base_java",
     "//chrome/browser/version:java",
     "//components/version_info/android:version_constants_java",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
index a2a9345..10c50452d 100644
--- a/chrome/android/chrome_java_sources.gni
+++ b/chrome/android/chrome_java_sources.gni
@@ -88,6 +88,7 @@
   "java/src/org/chromium/chrome/browser/app/tabmodel/ChromeTabModelFilterFactory.java",
   "java/src/org/chromium/chrome/browser/app/tabmodel/DefaultTabModelSelectorFactory.java",
   "java/src/org/chromium/chrome/browser/app/tabmodel/TabWindowManagerSingleton.java",
+  "java/src/org/chromium/chrome/browser/app/video_tutorials/ChromeLanguageInfoProvider.java",
   "java/src/org/chromium/chrome/browser/app/video_tutorials/NewTabPageVideoIPHManager.java",
   "java/src/org/chromium/chrome/browser/app/video_tutorials/VideoPlayerActivity.java",
   "java/src/org/chromium/chrome/browser/app/video_tutorials/VideoTutorialListActivity.java",
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedStreamSurface.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedStreamSurface.java
index 8ab3c16..a3060f3 100644
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedStreamSurface.java
+++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedStreamSurface.java
@@ -6,6 +6,8 @@
 
 import android.app.Activity;
 import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Build;
 import android.os.Handler;
 import android.view.ContextThemeWrapper;
 import android.view.View;
@@ -25,6 +27,7 @@
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
 import org.chromium.base.annotations.NativeMethods;
+import org.chromium.base.compat.ApiHelperForO;
 import org.chromium.base.task.PostTask;
 import org.chromium.base.task.TaskTraits;
 import org.chromium.chrome.R;
@@ -70,6 +73,7 @@
 import org.chromium.ui.mojom.WindowOpenDisposition;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -84,6 +88,8 @@
 public class FeedStreamSurface implements SurfaceActionsHandler, FeedActionsHandler {
     private static final String TAG = "FeedStreamSurface";
 
+    private static final String FEED_SPLIT_NAME = "feedv2";
+
     private static final int SNACKBAR_DURATION_MS_SHORT = 4000;
     private static final int SNACKBAR_DURATION_MS_LONG = 10000;
 
@@ -211,15 +217,17 @@
      */
     private static class FeedProcessScopeDependencyProvider
             implements ProcessScopeDependencyProvider {
+        private Context mContext;
         private ImageFetchClient mImageFetchClient;
 
         FeedProcessScopeDependencyProvider() {
+            mContext = createFeedContext(ContextUtils.getApplicationContext());
             mImageFetchClient = new FeedImageFetchClient();
         }
 
         @Override
         public Context getContext() {
-            return ContextUtils.getApplicationContext();
+            return mContext;
         }
 
         @Deprecated
@@ -288,7 +296,7 @@
         final boolean mDarkMode;
 
         FeedSurfaceScopeDependencyProvider(Context activityContext, boolean darkMode) {
-            mActivityContext = activityContext;
+            mActivityContext = createFeedContext(activityContext);
             mDarkMode = darkMode;
         }
 
@@ -1008,6 +1016,27 @@
         mScrollReporter.trackScroll(dx, dy);
     }
 
+    private static Context createFeedContext(Context context) {
+        // Isolated splits are only supported in O+, so just return the base context on other
+        // versions, since it will have access to all splits.
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
+            return context;
+        }
+
+        // If the feed split does not exist, return the original context.
+        String[] splitNames = ApiHelperForO.getSplitNames(context.getApplicationInfo());
+        if (splitNames == null || !Arrays.asList(splitNames).contains(FEED_SPLIT_NAME)) {
+            return context;
+        }
+
+        try {
+            return ApiHelperForO.createContextForSplit(context, FEED_SPLIT_NAME);
+        } catch (PackageManager.NameNotFoundException e) {
+            // Feed is not in a split.
+            return context;
+        }
+    }
+
     // Detects animation finishes in RecyclerView.
     // https://stackoverflow.com/questions/33710605/detect-animation-finish-in-androids-recyclerview
     private class RecyclerViewAnimationFinishDetector implements ItemAnimatorFinishedListener {
diff --git a/chrome/android/java/res/values/ids.xml b/chrome/android/java/res/values/ids.xml
index 235378d8..b65e21d 100644
--- a/chrome/android/java/res/values/ids.xml
+++ b/chrome/android/java/res/values/ids.xml
@@ -26,6 +26,12 @@
     <!-- Media playback notification -->
     <item type="id" name="media_playback_notification" />
 
+    <!-- Remote Playback API notification -->
+    <item type="id" name="remote_playback_notification" />
+
+    <!-- Presentation API notification -->
+    <item type="id" name="presentation_notification" />
+
     <!-- Sync UI constants -->
     <item type="id" name="passphrase_type_list" />
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/video_tutorials/ChromeLanguageInfoProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/app/video_tutorials/ChromeLanguageInfoProvider.java
new file mode 100644
index 0000000..c03d8f1
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/video_tutorials/ChromeLanguageInfoProvider.java
@@ -0,0 +1,24 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.app.video_tutorials;
+
+import org.chromium.chrome.browser.language.settings.LanguageItem;
+import org.chromium.chrome.browser.language.settings.LanguagesManager;
+import org.chromium.chrome.browser.video_tutorials.Language;
+import org.chromium.chrome.browser.video_tutorials.LanguageInfoProvider;
+
+/**
+ * See {@link LanguageInfoProvider}.
+ */
+public class ChromeLanguageInfoProvider implements LanguageInfoProvider {
+    @Override
+    public Language getLanguageInfo(String locale) {
+        LanguageItem languageItem = LanguagesManager.getInstance().getLanguageMap().get(locale);
+        if (languageItem == null) return null;
+
+        return new Language(languageItem.getCode(), languageItem.getDisplayName(),
+                languageItem.getNativeDisplayName());
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/video_tutorials/VideoPlayerActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/video_tutorials/VideoPlayerActivity.java
index 8b8488b..17c9854a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/video_tutorials/VideoPlayerActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/video_tutorials/VideoPlayerActivity.java
@@ -47,8 +47,9 @@
         VideoTutorialService videoTutorialService =
                 VideoTutorialServiceFactory.getForProfile(Profile.getLastUsedRegularProfile());
         mWindowAndroid = new ActivityWindowAndroid(this);
-        mCoordinator = VideoTutorialServiceFactory.createVideoPlayerCoordinator(
-                this, videoTutorialService, this::createWebContents, this::tryNow, this::finish);
+        mCoordinator = VideoTutorialServiceFactory.createVideoPlayerCoordinator(this,
+                videoTutorialService, this::createWebContents, new ChromeLanguageInfoProvider(),
+                this::tryNow, this::finish);
         setContentView(mCoordinator.getView());
 
         int featureType =
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/language/settings/LanguagesManager.java b/chrome/android/java/src/org/chromium/chrome/browser/language/settings/LanguagesManager.java
index 46a8a49..a0fefa6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/language/settings/LanguagesManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/language/settings/LanguagesManager.java
@@ -21,7 +21,7 @@
  *
  *The LanguagesManager is responsible for fetching languages details from native.
  */
-class LanguagesManager {
+public class LanguagesManager {
     /**
      * An observer interface that allows other classes to know when the accept language list is
      * updated in native side.
@@ -169,6 +169,14 @@
     }
 
     /**
+     * Called to get all languages available in chrome.
+     * @return A map of language code to {@code LanguageItem} for all available languages.
+     */
+    public Map<String, LanguageItem> getLanguageMap() {
+        return mLanguagesMap;
+    }
+
+    /**
      * Get the static instance of ChromePreferenceManager if it exists else create it.
      * @return the LanguagesManager singleton.
      */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/router/ChromeMediaRouterClient.java b/chrome/android/java/src/org/chromium/chrome/browser/media/router/ChromeMediaRouterClient.java
index 1202e05..790e581 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/router/ChromeMediaRouterClient.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/router/ChromeMediaRouterClient.java
@@ -12,6 +12,7 @@
 import org.chromium.base.ApplicationStatus;
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
+import org.chromium.chrome.R;
 import org.chromium.chrome.browser.document.ChromeIntentUtil;
 import org.chromium.chrome.browser.media.ui.ChromeMediaNotificationManager;
 import org.chromium.chrome.browser.tab.Tab;
@@ -42,6 +43,16 @@
     }
 
     @Override
+    public int getPresentationNotificationId() {
+        return R.id.presentation_notification;
+    }
+
+    @Override
+    public int getRemotingNotificationId() {
+        return R.id.remote_playback_notification;
+    }
+
+    @Override
     public FragmentManager getSupportFragmentManager(WebContents initiator) {
         FragmentActivity currentActivity =
                 (FragmentActivity) ApplicationStatus.getLastTrackedFocusedActivity();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/ChromeMediaNotificationControllerDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/ChromeMediaNotificationControllerDelegate.java
index 18da1931..a8a1b0b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/ChromeMediaNotificationControllerDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/ChromeMediaNotificationControllerDelegate.java
@@ -187,7 +187,7 @@
      * This class is used internally but has to be public to be able to launch the service.
      */
     public static final class CastListenerServiceImpl extends ListenerServiceImpl {
-        static final int NOTIFICATION_ID = R.id.remote_notification;
+        static final int NOTIFICATION_ID = R.id.remote_playback_notification;
 
         public CastListenerServiceImpl() {
             super(NOTIFICATION_ID);
diff --git a/chrome/android/modules/buildflags.gni b/chrome/android/modules/buildflags.gni
index fe809d67..c60310e 100644
--- a/chrome/android/modules/buildflags.gni
+++ b/chrome/android/modules/buildflags.gni
@@ -6,6 +6,13 @@
 import("//build/config/compiler/compiler.gni")
 import("//device/vr/buildflags/buildflags.gni")
 
+declare_args() {
+  # Whether //chrome code and resources are in a DFM for Monochrome and
+  # Trichrome bundles. This module will also include code and resources from all
+  # other DFMs.
+  enable_chrome_module = false
+}
+
 # If true, lld is used to partition feature code into separate libraries, which
 # in turn are included in Dynamic Feature Modules.
 use_native_partitions = is_android && is_clang && use_lld && !is_component_build
diff --git a/chrome/android/modules/chrome_bundle_tmpl.gni b/chrome/android/modules/chrome_bundle_tmpl.gni
index 3710457b..e099318 100644
--- a/chrome/android/modules/chrome_bundle_tmpl.gni
+++ b/chrome/android/modules/chrome_bundle_tmpl.gni
@@ -8,13 +8,6 @@
 import("//chrome/android/modules/chrome_feature_module_tmpl.gni")
 import("//components/module_installer/android/module_desc_java.gni")
 
-declare_args() {
-  # Whether //chrome code and resources are in a DFM for Monochrome and
-  # Trichrome bundles. This module will also include code and resources from all
-  # other DFMs.
-  enable_chrome_module = false
-}
-
 # Instantiates a Chrome-specific app bundle.
 #
 # Supports most variables of chrome_feature_module and android_app_bundle, plus:
@@ -51,21 +44,27 @@
     _paks = []
     _pak_deps = []
     foreach(_module_desc, invoker.module_descs) {
-      _module_desc_target_name =
-          "${target_name}__${_module_desc.name}__module_desc_java"
-      module_desc_java(_module_desc_target_name) {
-        module_name = _module_desc.name
+      if (defined(_module_desc.supports_isolated_split) &&
+          _module_desc.supports_isolated_split) {
+        _module_descs += [ _module_desc ]
+      } else {
+        _module_desc_target_name =
+            "${target_name}__${_module_desc.name}__module_desc_java"
+        module_desc_java(_module_desc_target_name) {
+          module_name = _module_desc.name
+          if (defined(_module_desc.pak_deps)) {
+            paks = _module_desc.paks
+          }
+          if (defined(_module_desc.load_native_on_get_impl)) {
+            load_native_on_get_impl = _module_desc.load_native_on_get_impl
+          }
+        }
+        _java_deps +=
+            _module_desc.java_deps + [ ":${_module_desc_target_name}" ]
         if (defined(_module_desc.pak_deps)) {
-          paks = _module_desc.paks
+          _paks += _module_desc.paks
+          _pak_deps += _module_desc.pak_deps
         }
-        if (defined(_module_desc.load_native_on_get_impl)) {
-          load_native_on_get_impl = _module_desc.load_native_on_get_impl
-        }
-      }
-      _java_deps += _module_desc.java_deps + [ ":${_module_desc_target_name}" ]
-      if (defined(_module_desc.pak_deps)) {
-        _paks += _module_desc.paks
-        _pak_deps += _module_desc.pak_deps
       }
     }
     chrome_module_desc = {
diff --git a/chrome/android/modules/chrome_feature_modules.gni b/chrome/android/modules/chrome_feature_modules.gni
index 57e3d58..b3b35e34 100644
--- a/chrome/android/modules/chrome_feature_modules.gni
+++ b/chrome/android/modules/chrome_feature_modules.gni
@@ -16,6 +16,8 @@
 import("//chrome/android/modules/stack_unwinder/stack_unwinder_module.gni")
 import("//chrome/android/modules/test_dummy/test_dummy_module.gni")
 import("//device/vr/buildflags/buildflags.gni")
+import("//weblayer/variables.gni")
+import("//weblayer/weblayer_module.gni")
 
 if (enable_vr) {
   import("//chrome/android/features/vr/vr_module.gni")
@@ -40,6 +42,8 @@
 #     library files going into module if the module is executed in 64 bit.
 #   pak_deps: (Optional) Grit or repack targets of PAKs going into module.
 #   paks: (Optional) PAKs going into module.
+#   supports_isolated_split: (Optional) Whether this module can be in its own
+#     isolated split.
 # Each new module needs to add a desc to one of the lists below.
 
 # Modules shipped in Chrome Modern (Android L+).
@@ -76,3 +80,9 @@
 
 # Modules shipped in Trichrome (Android Q+).
 trichrome_module_descs = monochrome_module_descs
+
+# Add this after we assign trichrome_module_descs, since WebLayer should only be
+# part of Monochrome.
+if (enable_chrome_module && webview_includes_weblayer) {
+  monochrome_module_descs += [ weblayer_module_desc ]
+}
diff --git a/chrome/android/monochrome/scripts/monochrome_python_tests.py b/chrome/android/monochrome/scripts/monochrome_python_tests.py
index 13df49c..2966bed 100755
--- a/chrome/android/monochrome/scripts/monochrome_python_tests.py
+++ b/chrome/android/monochrome/scripts/monochrome_python_tests.py
@@ -41,6 +41,9 @@
       '--system-webview-pathmap',
       help='The system webview APK resources pathmap path.')
 
+  # --avd-config parameter is unused. Add it to the parser because typ.Runner
+  # checks that all arguments are known. crbug.com/1084351
+  parser.add_argument('--avd-config', help='Unused')
   return parser
 
 
diff --git a/chrome/app/nearby_share_strings.grdp b/chrome/app/nearby_share_strings.grdp
index 0563226..8db6302 100644
--- a/chrome/app/nearby_share_strings.grdp
+++ b/chrome/app/nearby_share_strings.grdp
@@ -66,7 +66,7 @@
 
   <!-- Discovery page -->
   <message name="IDS_NEARBY_DISCOVERY_PAGE_INFO" desc="Help text on how to use the Nearby Share feature. Explains how to enable it on a nearby Chromebook to share with it.">
-    Make sure both devices are unlocked, close together, and have Bluetooth turned on. If you’re sharing with a Chromebook, make sure it has Nearby Sharing turned on (open the status area by selecting the time, then select Nearby Share).
+    Make sure both devices are unlocked, close together, and have Bluetooth turned on. If you’re sharing with a Chromebook, make sure it has Nearby Sharing turned on (open the status area by selecting the time, then select Nearby Share). <ph name="LINK_BEGIN">&lt;a&gt;</ph>Learn more<ph name="LINK_END">&lt;/a&gt;</ph>
   </message>
   <message name="IDS_NEARBY_DISCOVERY_PAGE_SUBTITLE" desc="Subtitle of the Nearby Share device discovery page. This is where users select a device to share files with.">
     Select the device you’d like to share files with
diff --git a/chrome/app/nearby_share_strings_grdp/IDS_NEARBY_DISCOVERY_PAGE_INFO.png.sha1 b/chrome/app/nearby_share_strings_grdp/IDS_NEARBY_DISCOVERY_PAGE_INFO.png.sha1
index 659bc35..828b14c5 100644
--- a/chrome/app/nearby_share_strings_grdp/IDS_NEARBY_DISCOVERY_PAGE_INFO.png.sha1
+++ b/chrome/app/nearby_share_strings_grdp/IDS_NEARBY_DISCOVERY_PAGE_INFO.png.sha1
@@ -1 +1 @@
-629702181a7d79b35060b405495b98cba09e5a93
\ No newline at end of file
+2ee345a76fb36c02485d4dd7afe01e4a44b2fe44
\ No newline at end of file
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp
index ec9823f..19021b26 100644
--- a/chrome/app/os_settings_strings.grdp
+++ b/chrome/app/os_settings_strings.grdp
@@ -159,6 +159,15 @@
   <message name="IDS_SETTINGS_ABOUT_PAGE_SHOW_RELEASE_NOTES" desc="Text of the button which shows user the release notes.">
     See what's new
   </message>
+  <message name="IDS_SETTINGS_ABOUT_PAGE_EDIT_DEVICE_NAME" desc="The title of the dialog that allows the user to edit the device hostname.">
+    Edit device name
+  </message>
+  <message name="IDS_SETTINGS_ABOUT_PAGE_DEVICE_NAME_INFO" desc="Label describing which areas of the Chrome OS system broadcast the device hostname to external networks.">
+    This name is visible to other devices for Bluetooth and network connections
+  </message>
+  <message name="IDS_SETTINGS_ABOUT_PAGE_DEVICE_NAME_CONSTRAINTS" desc="Label describing the requirements for the text of the device hostname.">
+    Name can use letters, numbers, and hyphens (-)
+  </message>
   <message name="IDS_SETTINGS_UPGRADE_UP_TO_DATE" desc="Status label: Already up to date (ChromiumOS/ChromeOS)">
     Your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> is up to date
   </message>
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_DEVICE_NAME_CONSTRAINTS.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_DEVICE_NAME_CONSTRAINTS.png.sha1
new file mode 100644
index 0000000..4be5a02
--- /dev/null
+++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_DEVICE_NAME_CONSTRAINTS.png.sha1
@@ -0,0 +1 @@
+31dad1de7fc497e6de0ac0eadc949e9e5691c738
\ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_DEVICE_NAME_INFO.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_DEVICE_NAME_INFO.png.sha1
new file mode 100644
index 0000000..4be5a02
--- /dev/null
+++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_DEVICE_NAME_INFO.png.sha1
@@ -0,0 +1 @@
+31dad1de7fc497e6de0ac0eadc949e9e5691c738
\ No newline at end of file
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_EDIT_DEVICE_NAME.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_EDIT_DEVICE_NAME.png.sha1
new file mode 100644
index 0000000..9edfc705
--- /dev/null
+++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_EDIT_DEVICE_NAME.png.sha1
@@ -0,0 +1 @@
+ea5e72dd37d73d9c447039ee2f216b4d0a903d55
\ No newline at end of file
diff --git a/chrome/app/vector_icons/BUILD.gn b/chrome/app/vector_icons/BUILD.gn
index 1043d27..ddf23ee3 100644
--- a/chrome/app/vector_icons/BUILD.gn
+++ b/chrome/app/vector_icons/BUILD.gn
@@ -93,8 +93,8 @@
     "remove_box.icon",
     "resize_handle.icon",
     "sad_tab.icon",
-    "scrolling_tabstrip_left.icon",
-    "scrolling_tabstrip_right.icon",
+    "scrolling_tabstrip_leading.icon",
+    "scrolling_tabstrip_trailing.icon",
     "security.icon",
     "send_tab_to_self.icon",
     "sign_out.icon",
diff --git a/chrome/app/vector_icons/scrolling_tabstrip_left.icon b/chrome/app/vector_icons/scrolling_tabstrip_leading.icon
similarity index 100%
rename from chrome/app/vector_icons/scrolling_tabstrip_left.icon
rename to chrome/app/vector_icons/scrolling_tabstrip_leading.icon
diff --git a/chrome/app/vector_icons/scrolling_tabstrip_right.icon b/chrome/app/vector_icons/scrolling_tabstrip_trailing.icon
similarity index 100%
rename from chrome/app/vector_icons/scrolling_tabstrip_right.icon
rename to chrome/app/vector_icons/scrolling_tabstrip_trailing.icon
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 52e13a8..77b0d8d 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -4200,10 +4200,6 @@
      FEATURE_VALUE_TYPE(features::kBlockInsecurePrivateNetworkRequests)},
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
-    {"cors-for-content-scripts", flag_descriptions::kCorsForContentScriptsName,
-     flag_descriptions::kCorsForContentScriptsDescription, kOsDesktop,
-     FEATURE_VALUE_TYPE(network::features::kCorbAllowlistAlsoAppliesToOorCors)},
-
     {"force-empty-CORB-and-CORS-allowlist",
      flag_descriptions::kForceEmptyCorbAndCorsAllowlistName,
      flag_descriptions::kForceEmptyCorbAndCorsAllowlistDescription, kOsDesktop,
diff --git a/chrome/browser/apps/app_service/app_icon_factory.cc b/chrome/browser/apps/app_service/app_icon_factory.cc
index eeab319..23fc909 100644
--- a/chrome/browser/apps/app_service/app_icon_factory.cc
+++ b/chrome/browser/apps/app_service/app_icon_factory.cc
@@ -158,6 +158,7 @@
   gfx::ImageSkia subset_image;
   for (const auto& rep : image_skia.image_reps()) {
     if (IsConsistentPixelSize(rep, image_skia)) {
+      subset_image.AddRepresentation(rep);
       continue;
     }
 
@@ -953,7 +954,7 @@
       ++it;
     }
 
-    if (it == icon_bitmaps.end()) {
+    if (it == icon_bitmaps.end() || it->second.empty()) {
       MaybeApplyEffectsAndComplete(gfx::ImageSkia());
       return;
     }
diff --git a/chrome/browser/background_fetch/background_fetch_browsertest.cc b/chrome/browser/background_fetch/background_fetch_browsertest.cc
index 68e1482..21c3f78 100644
--- a/chrome/browser/background_fetch/background_fetch_browsertest.cc
+++ b/chrome/browser/background_fetch/background_fetch_browsertest.cc
@@ -135,7 +135,8 @@
 
 // Observes the offline item collection's content provider and then invokes the
 // associated test callbacks when one has been provided.
-class OfflineContentProviderObserver : public OfflineContentProvider::Observer {
+class OfflineContentProviderObserver final
+    : public OfflineContentProvider::Observer {
  public:
   using ItemsAddedCallback =
       base::OnceCallback<void(const std::vector<OfflineItem>&)>;
diff --git a/chrome/browser/browsing_data/browsing_data_media_license_helper.cc b/chrome/browser/browsing_data/browsing_data_media_license_helper.cc
index 9123581..4b15063 100644
--- a/chrome/browser/browsing_data/browsing_data_media_license_helper.cc
+++ b/chrome/browser/browsing_data/browsing_data_media_license_helper.cc
@@ -27,7 +27,7 @@
 // An implementation of the BrowsingDataMediaLicenseHelper interface that
 // determine data on media licenses in a given |filesystem_context| and
 // returns a list of MediaLicenseInfo items to a client.
-class BrowsingDataMediaLicenseHelperImpl
+class BrowsingDataMediaLicenseHelperImpl final
     : public BrowsingDataMediaLicenseHelper {
  public:
   // BrowsingDataMediaLicenseHelper implementation
diff --git a/chrome/browser/chromeos/chromebox_for_meetings/cfm_browser_service.cc b/chrome/browser/chromeos/chromebox_for_meetings/cfm_browser_service.cc
index 47ebce4f..e74efca 100644
--- a/chrome/browser/chromeos/chromebox_for_meetings/cfm_browser_service.cc
+++ b/chrome/browser/chromeos/chromebox_for_meetings/cfm_browser_service.cc
@@ -37,8 +37,8 @@
   receivers_.Clear();
 }
 
-void CfmBrowserService::BindService(
-    ::mojo::ScopedMessagePipeHandle receiver_pipe) {
+void CfmBrowserService::OnBindService(
+    mojo::ScopedMessagePipeHandle receiver_pipe) {
   receivers_.Add(
       this, mojo::PendingReceiver<mojom::CfmBrowser>(std::move(receiver_pipe)));
 }
diff --git a/chrome/browser/chromeos/chromebox_for_meetings/cfm_browser_service.h b/chrome/browser/chromeos/chromebox_for_meetings/cfm_browser_service.h
index 1d4781e..d767ab9 100644
--- a/chrome/browser/chromeos/chromebox_for_meetings/cfm_browser_service.h
+++ b/chrome/browser/chromeos/chromebox_for_meetings/cfm_browser_service.h
@@ -39,7 +39,7 @@
   // Forward |ServiceAdaptorDelegate| implementation
   void OnAdaptorConnect(bool success) override;
   void OnAdaptorDisconnect() override;
-  void BindService(::mojo::ScopedMessagePipeHandle receiver_pipe) override;
+  void OnBindService(mojo::ScopedMessagePipeHandle receiver_pipe) override;
 
   virtual void OnServiceDisconnect();
 
diff --git a/chrome/browser/chromeos/chromebox_for_meetings/fake_service_context.cc b/chrome/browser/chromeos/chromebox_for_meetings/fake_service_context.cc
index e51d5894..431e815 100644
--- a/chrome/browser/chromeos/chromebox_for_meetings/fake_service_context.cc
+++ b/chrome/browser/chromeos/chromebox_for_meetings/fake_service_context.cc
@@ -19,12 +19,12 @@
            std::move(callback));
 }
 
-void FakeCfmServiceContext::BindRegistry(
+void FakeCfmServiceContext::RequestBindService(
     const std::string& interface_name,
-    mojo::PendingReceiver<mojom::CfmServiceRegistry> broker_receiver,
-    BindRegistryCallback callback) {
-  std::move(bind_registry_callback_)
-      .Run(std::move(interface_name), std::move(broker_receiver),
+    mojo::ScopedMessagePipeHandle receiver_pipe,
+    RequestBindServiceCallback callback) {
+  std::move(request_bind_service_callback_)
+      .Run(std::move(interface_name), std::move(receiver_pipe),
            std::move(callback));
 }
 
@@ -33,9 +33,9 @@
   provide_adaptor_callback_ = std::move(callback);
 }
 
-void FakeCfmServiceContext::SetFakeBindRegistryCallback(
-    FakeBindRegistryCallback callback) {
-  bind_registry_callback_ = std::move(callback);
+void FakeCfmServiceContext::SetFakeRequestBindServiceCallback(
+    FakeRequestBindServiceCallback callback) {
+  request_bind_service_callback_ = std::move(callback);
 }
 
 }  // namespace cfm
diff --git a/chrome/browser/chromeos/chromebox_for_meetings/fake_service_context.h b/chrome/browser/chromeos/chromebox_for_meetings/fake_service_context.h
index 3de0103..0c6775b 100644
--- a/chrome/browser/chromeos/chromebox_for_meetings/fake_service_context.h
+++ b/chrome/browser/chromeos/chromebox_for_meetings/fake_service_context.h
@@ -21,10 +21,10 @@
       mojo::PendingRemote<mojom::CfmServiceAdaptor> adaptor_remote,
       ProvideAdaptorCallback callback)>;
 
-  using FakeBindRegistryCallback = base::OnceCallback<void(
-      const std::string& interface_name,
-      mojo::PendingReceiver<mojom::CfmServiceRegistry> broker_receiver,
-      BindRegistryCallback callback)>;
+  using FakeRequestBindServiceCallback =
+      base::OnceCallback<void(const std::string& interface_name,
+                              mojo::ScopedMessagePipeHandle receiver_pipe,
+                              RequestBindServiceCallback callback)>;
 
   FakeCfmServiceContext();
   FakeCfmServiceContext(const FakeCfmServiceContext&) = delete;
@@ -36,18 +36,18 @@
       mojo::PendingRemote<mojom::CfmServiceAdaptor> adaptor_remote,
       ProvideAdaptorCallback callback) override;
 
-  void BindRegistry(
-      const std::string& interface_name,
-      mojo::PendingReceiver<mojom::CfmServiceRegistry> broker_receiver,
-      BindRegistryCallback callback) override;
+  void RequestBindService(const std::string& interface_name,
+                          mojo::ScopedMessagePipeHandle receiver_pipe,
+                          RequestBindServiceCallback callback) override;
 
   void SetFakeProvideAdaptorCallback(FakeProvideAdaptorCallback callback);
 
-  void SetFakeBindRegistryCallback(FakeBindRegistryCallback callback);
+  void SetFakeRequestBindServiceCallback(
+      FakeRequestBindServiceCallback callback);
 
  private:
   FakeProvideAdaptorCallback provide_adaptor_callback_;
-  FakeBindRegistryCallback bind_registry_callback_;
+  FakeRequestBindServiceCallback request_bind_service_callback_;
 };
 
 }  // namespace cfm
diff --git a/chrome/browser/chromeos/chromebox_for_meetings/service_adaptor.cc b/chrome/browser/chromeos/chromebox_for_meetings/service_adaptor.cc
index 9b934d0..e0e352bd 100644
--- a/chrome/browser/chromeos/chromebox_for_meetings/service_adaptor.cc
+++ b/chrome/browser/chromeos/chromebox_for_meetings/service_adaptor.cc
@@ -40,8 +40,9 @@
       &ServiceAdaptor::OnAdaptorDisconnect, base::Unretained(this)));
 }
 
-void ServiceAdaptor::BindService(mojo::ScopedMessagePipeHandle receiver_pipe) {
-  delegate_->BindService(std::move(receiver_pipe));
+void ServiceAdaptor::OnBindService(
+    mojo::ScopedMessagePipeHandle receiver_pipe) {
+  delegate_->OnBindService(std::move(receiver_pipe));
 }
 
 void ServiceAdaptor::OnAdaptorConnect(bool success) {
diff --git a/chrome/browser/chromeos/chromebox_for_meetings/service_adaptor.h b/chrome/browser/chromeos/chromebox_for_meetings/service_adaptor.h
index b5ab22b..49f7b6cd 100644
--- a/chrome/browser/chromeos/chromebox_for_meetings/service_adaptor.h
+++ b/chrome/browser/chromeos/chromebox_for_meetings/service_adaptor.h
@@ -32,7 +32,7 @@
 
     // Called when attempting to Bind a mojom using using a message pipe of the
     // given types PendingReceiver.
-    virtual void BindService(mojo::ScopedMessagePipeHandle receiver_pipe) = 0;
+    virtual void OnBindService(mojo::ScopedMessagePipeHandle receiver_pipe) = 0;
 
    protected:
     Delegate() = default;
@@ -51,7 +51,7 @@
 
  protected:
   // Forward |mojom::CfmServiceAdaptor| implementation
-  void BindService(mojo::ScopedMessagePipeHandle receiver_pipe) override;
+  void OnBindService(mojo::ScopedMessagePipeHandle receiver_pipe) override;
 
   // Called when the Service Adaptor has successfully connected to the
   // |mojom::CfmServiceContext|
diff --git a/chrome/browser/chromeos/chromebox_for_meetings/service_adaptor_unittest.cc b/chrome/browser/chromeos/chromebox_for_meetings/service_adaptor_unittest.cc
index 2fd935c..939e2b3 100644
--- a/chrome/browser/chromeos/chromebox_for_meetings/service_adaptor_unittest.cc
+++ b/chrome/browser/chromeos/chromebox_for_meetings/service_adaptor_unittest.cc
@@ -48,7 +48,7 @@
     disconnect_callback_.Run();
   }
 
-  void BindService(mojo::ScopedMessagePipeHandle) override {
+  void OnBindService(mojo::ScopedMessagePipeHandle) override {
     bind_request_count++;
     bind_service_callback_.Run();
   }
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 83e6c18..2815e8a 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
@@ -716,12 +716,12 @@
   PRINT_IF_NOT_DEFAULT(mount_volumes)
   PRINT_IF_NOT_DEFAULT(native_smb)
   PRINT_IF_NOT_DEFAULT(offline)
+  PRINT_IF_NOT_DEFAULT(single_partition_format)
   PRINT_IF_NOT_DEFAULT(smbfs)
   PRINT_IF_NOT_DEFAULT(tablet_mode)
   PRINT_IF_NOT_DEFAULT(trash)
   PRINT_IF_NOT_DEFAULT(zip)
   PRINT_IF_NOT_DEFAULT(zip_no_nacl)
-  PRINT_IF_NOT_DEFAULT(single_partition_format)
 
 #undef PRINT_IF_NOT_DEFAULT
 
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
index 0569781..c2feaf5 100644
--- a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
+++ b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
@@ -54,7 +54,7 @@
 
 void InitInputMethod() {
   auto* comp_ime_manager = new ComponentExtensionIMEManager;
-  auto* delegate = new MockComponentExtIMEManagerDelegate;
+  auto* delegate = new MockComponentExtensionIMEManagerDelegate;
 
   ComponentExtensionIME ext1;
   ext1.id = kTestExtensionId;
diff --git a/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc b/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc
index ba3ec3d..8c2a805 100644
--- a/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc
+++ b/chrome/browser/chromeos/input_method/input_method_manager_impl_unittest.cc
@@ -188,7 +188,7 @@
  protected:
   // Helper function to initialize component extension stuff for testing.
   void InitComponentExtension() {
-    mock_delegate_ = new MockComponentExtIMEManagerDelegate();
+    mock_delegate_ = new MockComponentExtensionIMEManagerDelegate();
     mock_delegate_->set_ime_list(ime_list_);
     std::unique_ptr<ComponentExtensionIMEManagerDelegate> delegate(
         mock_delegate_);
@@ -368,7 +368,7 @@
   MockCandidateWindowController* candidate_window_controller_;
   std::unique_ptr<MockInputMethodEngine> mock_engine_handler_;
   FakeImeKeyboard* keyboard_;
-  MockComponentExtIMEManagerDelegate* mock_delegate_;
+  MockComponentExtensionIMEManagerDelegate* mock_delegate_;
   std::vector<ComponentExtensionIME> ime_list_;
   ui::ime::InputMethodMenuManager* menu_manager_;
 
diff --git a/chrome/browser/chromeos/phonehub/phone_hub_manager_factory.cc b/chrome/browser/chromeos/phonehub/phone_hub_manager_factory.cc
index 29a294e..a70a62a 100644
--- a/chrome/browser/chromeos/phonehub/phone_hub_manager_factory.cc
+++ b/chrome/browser/chromeos/phonehub/phone_hub_manager_factory.cc
@@ -15,6 +15,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sync/session_sync_service_factory.h"
 #include "chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.h"
+#include "chromeos/components/phonehub/multidevice_setup_state_updater.h"
 #include "chromeos/components/phonehub/notification_access_manager_impl.h"
 #include "chromeos/components/phonehub/onboarding_ui_tracker_impl.h"
 #include "chromeos/components/phonehub/phone_hub_manager_impl.h"
@@ -111,6 +112,7 @@
 
 void PhoneHubManagerFactory::RegisterProfilePrefs(
     user_prefs::PrefRegistrySyncable* registry) {
+  MultideviceSetupStateUpdater::RegisterPrefs(registry);
   NotificationAccessManagerImpl::RegisterPrefs(registry);
   OnboardingUiTrackerImpl::RegisterPrefs(registry);
 }
diff --git a/chrome/browser/chromeos/policy/remote_commands/device_command_run_routine_job.cc b/chrome/browser/chromeos/policy/remote_commands/device_command_run_routine_job.cc
index d759d1bb..55ec64bd 100644
--- a/chrome/browser/chromeos/policy/remote_commands/device_command_run_routine_job.cc
+++ b/chrome/browser/chromeos/policy/remote_commands/device_command_run_routine_job.cc
@@ -521,6 +521,15 @@
               std::move(failed_callback)));
       break;
     }
+    case chromeos::cros_healthd::mojom::DiagnosticRoutineEnum::
+        kHasSecureWiFiConnection: {
+      chromeos::cros_healthd::ServiceConnection::GetInstance()
+          ->RunHasSecureWiFiConnectionRoutine(base::BindOnce(
+              &DeviceCommandRunRoutineJob::OnCrosHealthdResponseReceived,
+              weak_ptr_factory_.GetWeakPtr(), std::move(succeeded_callback),
+              std::move(failed_callback)));
+      break;
+    }
   }
 }
 
diff --git a/chrome/browser/chromeos/preferences_unittest.cc b/chrome/browser/chromeos/preferences_unittest.cc
index 91ad679..57ba062 100644
--- a/chrome/browser/chromeos/preferences_unittest.cc
+++ b/chrome/browser/chromeos/preferences_unittest.cc
@@ -253,8 +253,8 @@
 
   void InitComponentExtensionIMEManager() {
     // Set our custom IME list on the mock delegate.
-    input_method::MockComponentExtIMEManagerDelegate* mock_delegate =
-        new input_method::MockComponentExtIMEManagerDelegate();
+    input_method::MockComponentExtensionIMEManagerDelegate* mock_delegate =
+        new input_method::MockComponentExtensionIMEManagerDelegate();
     mock_delegate->set_ime_list(CreateImeList());
 
     // Pass the mock delegate to a new ComponentExtensionIMEManager.
diff --git a/chrome/browser/chromeos/scanning/scan_service.cc b/chrome/browser/chromeos/scanning/scan_service.cc
index 1660a0a..cea7fe8a 100644
--- a/chrome/browser/chromeos/scanning/scan_service.cc
+++ b/chrome/browser/chromeos/scanning/scan_service.cc
@@ -64,7 +64,7 @@
   lorgnette_scanner_manager_->Scan(
       scanner_name, mojo::ConvertTo<lorgnette::ScanSettings>(settings),
       base::BindRepeating(&ScanService::OnPageReceived,
-                          weak_ptr_factory_.GetWeakPtr()),
+                          weak_ptr_factory_.GetWeakPtr(), settings->file_type),
       base::BindOnce(&ScanService::OnScanCompleted,
                      weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
 }
@@ -113,8 +113,17 @@
       mojo::ConvertTo<mojo_ipc::ScannerCapabilitiesPtr>(capabilities.value()));
 }
 
-void ScanService::OnPageReceived(std::string scanned_image,
+void ScanService::OnPageReceived(const mojo_ipc::FileType file_type,
+                                 std::string scanned_image,
                                  uint32_t page_number) {
+  // TODO(jschettler): Add support for converting the scanned image to other
+  // file types.
+  if (file_type != mojo_ipc::FileType::kPng) {
+    LOG(ERROR) << "Selected file type not supported.";
+    save_failed_ = true;
+    return;
+  }
+
   // The |page_number| is 0-indexed.
   const std::string filename = base::StringPrintf(
       "scan_%02d%02d%02d-%02d%02d%02d_page_%d.png", start_time_.year,
diff --git a/chrome/browser/chromeos/scanning/scan_service.h b/chrome/browser/chromeos/scanning/scan_service.h
index 1fdd2bf7..226b9f1 100644
--- a/chrome/browser/chromeos/scanning/scan_service.h
+++ b/chrome/browser/chromeos/scanning/scan_service.h
@@ -66,8 +66,11 @@
       const base::Optional<lorgnette::ScannerCapabilities>& capabilities);
 
   // Processes each |scanned_image| received after calling
-  // LorgnetteScannerManager::Scan().
-  void OnPageReceived(std::string scanned_image, uint32_t page_number);
+  // LorgnetteScannerManager::Scan(). |file_type| specifies the file type to use
+  // when saving scanned images.
+  void OnPageReceived(const scanning::mojom::FileType file_type,
+                      std::string scanned_image,
+                      uint32_t page_number);
 
   // Processes the final result of calling LorgnetteScannerManager::Scan().
   void OnScanCompleted(ScanCallback callback, bool success);
diff --git a/chrome/browser/chromeos/scanning/scan_service_unittest.cc b/chrome/browser/chromeos/scanning/scan_service_unittest.cc
index f5acc7d..4fdc9fb 100644
--- a/chrome/browser/chromeos/scanning/scan_service_unittest.cc
+++ b/chrome/browser/chromeos/scanning/scan_service_unittest.cc
@@ -198,7 +198,11 @@
   fake_lorgnette_scanner_manager_.SetScanResponse("TestData");
   auto scanners = GetScanners();
   ASSERT_EQ(scanners.size(), 1u);
-  EXPECT_TRUE(Scan(scanners[0]->id, mojo_ipc::ScanSettings::New()));
+
+  // Saving scanned images is currently only supported for the PNG file type.
+  mojo_ipc::ScanSettings settings;
+  settings.file_type = mojo_ipc::FileType::kPng;
+  EXPECT_TRUE(Scan(scanners[0]->id, settings.Clone()));
 }
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/web_applications/help_app_integration_browsertest.cc b/chrome/browser/chromeos/web_applications/help_app_integration_browsertest.cc
index f2ad7db..377d7fb 100644
--- a/chrome/browser/chromeos/web_applications/help_app_integration_browsertest.cc
+++ b/chrome/browser/chromeos/web_applications/help_app_integration_browsertest.cc
@@ -7,6 +7,7 @@
 
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/metrics/user_action_tester.h"
+#include "base/test/scoped_feature_list.h"
 #include "build/branding_buildflags.h"
 #include "build/build_config.h"
 #include "chrome/browser/apps/app_service/app_launch_params.h"
diff --git a/chrome/browser/enterprise/browser_management/browser_management_status_provider.h b/chrome/browser/enterprise/browser_management/browser_management_status_provider.h
index fb4e061..6e74ecb 100644
--- a/chrome/browser/enterprise/browser_management/browser_management_status_provider.h
+++ b/chrome/browser/enterprise/browser_management/browser_management_status_provider.h
@@ -14,7 +14,7 @@
 
 class Profile;
 
-class BrowserCloudManagementStatusProvider
+class BrowserCloudManagementStatusProvider final
     : public policy::ManagementStatusProvider {
  public:
   BrowserCloudManagementStatusProvider();
@@ -23,7 +23,7 @@
   EnterpriseManagementAuthority GetAuthority() final;
 };
 
-class LocalBrowserManagementStatusProvider
+class LocalBrowserManagementStatusProvider final
     : public policy::ManagementStatusProvider {
  public:
   LocalBrowserManagementStatusProvider();
@@ -32,7 +32,7 @@
   EnterpriseManagementAuthority GetAuthority() final;
 };
 
-class ProfileCloudManagementStatusProvider
+class ProfileCloudManagementStatusProvider final
     : public policy::ManagementStatusProvider {
  public:
   explicit ProfileCloudManagementStatusProvider(Profile* profile);
diff --git a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api_unittest.cc b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api_unittest.cc
index bb6eff2..c875bf3e 100644
--- a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api_unittest.cc
+++ b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api_unittest.cc
@@ -367,7 +367,7 @@
   TestInputMethodManager() : state_(new TestState), util_(&delegate_) {
     util_.AppendInputMethods(state_->input_methods_);
     mock_delegate_ =
-        new chromeos::input_method::MockComponentExtIMEManagerDelegate();
+        new chromeos::input_method::MockComponentExtensionIMEManagerDelegate();
     component_ext_mgr_ =
         std::make_unique<chromeos::ComponentExtensionIMEManager>();
     component_ext_mgr_->Initialize(base::WrapUnique(mock_delegate_));
@@ -391,7 +391,8 @@
   input_method::FakeInputMethodDelegate delegate_;
   input_method::InputMethodUtil util_;
   std::unique_ptr<chromeos::ComponentExtensionIMEManager> component_ext_mgr_;
-  chromeos::input_method::MockComponentExtIMEManagerDelegate* mock_delegate_;
+  chromeos::input_method::MockComponentExtensionIMEManagerDelegate*
+      mock_delegate_;
 
   DISALLOW_COPY_AND_ASSIGN(TestInputMethodManager);
 };
diff --git a/chrome/browser/extensions/api/management/management_api_browsertest.cc b/chrome/browser/extensions/api/management/management_api_browsertest.cc
index b813d92..a4abd2f 100644
--- a/chrome/browser/extensions/api/management/management_api_browsertest.cc
+++ b/chrome/browser/extensions/api/management/management_api_browsertest.cc
@@ -133,8 +133,8 @@
   ExtensionTestMessageListener app_launched_listener("app_launched", false);
   ASSERT_TRUE(
       LoadExtension(test_data_dir_.AppendASCII("management/packaged_app")));
-  ASSERT_TRUE(
-      LoadExtension(test_data_dir_.AppendASCII("management/launch_app")));
+  ASSERT_TRUE(LoadExtensionWithParamFlags(
+      test_data_dir_.AppendASCII("management/launch_app")));
   ASSERT_TRUE(app_launched_listener.WaitUntilSatisfied());
 
   // Should still see 0 apps launched from the API in the histogram.
@@ -154,8 +154,8 @@
   ExtensionTestMessageListener app_launched_listener("app_launched", false);
   ASSERT_TRUE(
       LoadExtension(test_data_dir_.AppendASCII("management/packaged_app")));
-  ASSERT_TRUE(
-      LoadExtension(test_data_dir_.AppendASCII("management/launch_app")));
+  ASSERT_TRUE(LoadExtensionWithParamFlags(
+      test_data_dir_.AppendASCII("management/launch_app")));
   ASSERT_TRUE(app_launched_listener.WaitUntilSatisfied());
 
   // Should see 1 app launched from the highlights app  in the histogram.
@@ -171,7 +171,7 @@
   ExtensionTestMessageListener listener1("success", false);
   ASSERT_TRUE(LoadExtension(
       test_data_dir_.AppendASCII("management/packaged_app")));
-  ASSERT_TRUE(LoadExtension(
+  ASSERT_TRUE(LoadExtensionWithParamFlags(
       test_data_dir_.AppendASCII("management/launch_app_from_background")));
   ASSERT_TRUE(listener1.WaitUntilSatisfied());
 }
diff --git a/chrome/browser/extensions/api/tab_capture/tab_capture_api.h b/chrome/browser/extensions/api/tab_capture/tab_capture_api.h
index 699090b..a30fcc0 100644
--- a/chrome/browser/extensions/api/tab_capture/tab_capture_api.h
+++ b/chrome/browser/extensions/api/tab_capture/tab_capture_api.h
@@ -22,7 +22,7 @@
 // Extension ids for the chromecast.
 extern const char* const kChromecastExtensionIds[6];
 
-class TabCaptureCaptureFunction : public ExtensionFunction {
+class TabCaptureCaptureFunction final : public ExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("tabCapture.capture", TABCAPTURE_CAPTURE)
 
@@ -33,7 +33,7 @@
   ResponseAction Run() final;
 };
 
-class TabCaptureGetCapturedTabsFunction : public ExtensionFunction {
+class TabCaptureGetCapturedTabsFunction final : public ExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("tabCapture.getCapturedTabs",
                              TABCAPTURE_GETCAPTUREDTABS)
@@ -45,7 +45,7 @@
   ResponseAction Run() final;
 };
 
-class TabCaptureCaptureOffscreenTabFunction : public ExtensionFunction {
+class TabCaptureCaptureOffscreenTabFunction final : public ExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("tabCapture.captureOffscreenTab",
                              TABCAPTURE_CAPTUREOFFSCREENTAB)
@@ -62,7 +62,7 @@
   ResponseAction Run() final;
 };
 
-class TabCaptureGetMediaStreamIdFunction : public ExtensionFunction {
+class TabCaptureGetMediaStreamIdFunction final : public ExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("tabCapture.getMediaStreamId",
                              TABCAPTURE_GETMEDIASTREAMID)
diff --git a/chrome/browser/extensions/corb_and_cors_extension_browsertest.cc b/chrome/browser/extensions/corb_and_cors_extension_browsertest.cc
index 536f60a..14264e52 100644
--- a/chrome/browser/extensions/corb_and_cors_extension_browsertest.cc
+++ b/chrome/browser/extensions/corb_and_cors_extension_browsertest.cc
@@ -77,9 +77,6 @@
   // //extensions/browser/url_loader_factory_manager.cc).
   kAllowlisted = 1 << 0,
 
-  // Whether network::features::kCorbAllowlistAlsoAppliesToOorCors is enabled.
-  kCorsForContentScripts = 1 << 1,
-
   // Whether network::features::
   // kDeriveOriginFromUrlForNeitherGetNorHeadRequestWhenHavingSpecialAccess is
   // enabled.
@@ -220,15 +217,6 @@
               kDeriveOriginFromUrlForNeitherGetNorHeadRequestWhenHavingSpecialAccess);
     }
 
-    if (IsCorsForContentScriptsEnabled()) {
-      enabled_features.emplace_back(
-          network::features::kCorbAllowlistAlsoAppliesToOorCors,
-          base::FieldTrialParams());
-    } else {
-      disabled_features.push_back(
-          network::features::kCorbAllowlistAlsoAppliesToOorCors);
-    }
-
     if (IsExtensionAllowlisted()) {
       base::FieldTrialParams field_trial_params;
       field_trial_params.emplace(
@@ -254,11 +242,6 @@
     return (GetParam() & TestParam::kAllowlisted) != 0;
   }
 
-  // This returns true if content scripts are not exempt from CORS.
-  bool IsCorsForContentScriptsEnabled() {
-    return (GetParam() & TestParam::kCorsForContentScripts) != 0;
-  }
-
   bool DeriveOriginFromUrl() {
     return (GetParam() & TestParam::kDeriveOriginFromUrl) != 0;
   }
@@ -409,24 +392,18 @@
     metrics::SubprocessMetricsProvider::MergeHistogramDeltasForTesting();
 
     if (AreContentScriptFetchesExpectedToBeBlocked()) {
-      if (IsCorsForContentScriptsEnabled()) {
-        // Verify the fetch was blocked by CORS.
-        EXPECT_EQ(kCorsErrorWhenFetching, actual_fetch_result);
-        VerifyFetchWasBlockedByCors(console_observer);
+      // Verify the fetch was blocked by CORS.
+      EXPECT_EQ(kCorsErrorWhenFetching, actual_fetch_result);
+      VerifyFetchWasBlockedByCors(console_observer);
 
-        // No verification if the request was blocked by CORB, because
-        // 1) once request_initiator is trustworthy, CORB should only
-        //    apply to no-cors requests
-        // 2) some CORS-blocked requests may not reach CORB/response-started
-        //    stage at all (e.g. if CORS blocks a redirect).
+      // No verification if the request was blocked by CORB, because
+      // 1) once request_initiator is trustworthy, CORB should only
+      //    apply to no-cors requests
+      // 2) some CORS-blocked requests may not reach CORB/response-started
+      //    stage at all (e.g. if CORS blocks a redirect).
 
-        // TODO(lukasza): Verify that the request was made in CORS mode (e.g.
-        // included an Origin header).
-      } else {
-        // Verify the fetch was blocked by CORB, but not blocked by CORS.
-        EXPECT_EQ(std::string(), actual_fetch_result);
-        VerifyFetchFromContentScriptWasBlockedByCorb(histograms);
-      }
+      // TODO(lukasza): Verify that the request was made in CORS mode (e.g.
+      // included an Origin header).
     } else {
       // Verify the fetch was allowed.
       EXPECT_EQ(expected_fetch_result, actual_fetch_result);
@@ -443,8 +420,7 @@
     VerifyFetchFromContentScriptWasAllowedByCorb(histograms,
                                                  true /* expecting_sniffing */);
 
-    if (IsCorsForContentScriptsEnabled() &&
-        AreContentScriptFetchesExpectedToBeBlocked()) {
+    if (AreContentScriptFetchesExpectedToBeBlocked()) {
       // Verify that the response body was blocked by CORS.
       EXPECT_EQ(kCorsErrorWhenFetching, actual_fetch_result);
       VerifyFetchWasBlockedByCors(console_observer);
@@ -1310,8 +1286,7 @@
 };
 INSTANTIATE_TEST_SUITE_P(Allowlisted_AllowlistForCors,
                          TrustTokenExtensionBrowserTest,
-                         ::testing::Values(TestParam::kAllowlisted |
-                                           TestParam::kCorsForContentScripts));
+                         ::testing::Values(TestParam::kAllowlisted));
 IN_PROC_BROWSER_TEST_P(
     TrustTokenExtensionBrowserTest,
     FromProgrammaticContentScript_TrustTokenRedemptionAllowed) {
@@ -2066,8 +2041,7 @@
   if (it != headers_map.end())
     actual_origin_header = it->second;
 
-  if (AreContentScriptFetchesExpectedToBeBlocked() &&
-      IsCorsForContentScriptsEnabled()) {
+  if (AreContentScriptFetchesExpectedToBeBlocked()) {
     // Verify the Origin header uses the page's origin (not the extension
     // origin).
     EXPECT_EQ(url::Origin::Create(page_url).Serialize(), actual_origin_header);
@@ -2279,7 +2253,7 @@
 
   // Verify the request headers (e.g. Origin and Sec-Fetch-Site headers).
   cors_request.WaitForRequest();
-  if (IsExtensionAllowlisted() || !IsCorsForContentScriptsEnabled()) {
+  if (IsExtensionAllowlisted()) {
     // Content scripts of allowlisted extensions should be exempted from CORS,
     // based on the websites the extension has permission for, via extension
     // manifest.  Therefore, there should be no "Origin" header.
@@ -2318,13 +2292,6 @@
   EXPECT_EQ("cors-allowed-body", fetch_result);
 }
 
-INSTANTIATE_TEST_SUITE_P(Allowlisted_AllowlistForCors,
-                         CorbAndCorsExtensionBrowserTest,
-                         ::testing::Values(TestParam::kAllowlisted |
-                                           TestParam::kCorsForContentScripts));
-INSTANTIATE_TEST_SUITE_P(NotAllowlisted_AllowlistForCors,
-                         CorbAndCorsExtensionBrowserTest,
-                         ::testing::Values(TestParam::kCorsForContentScripts));
 INSTANTIATE_TEST_SUITE_P(Allowlisted,
                          CorbAndCorsExtensionBrowserTest,
                          ::testing::Values(TestParam::kAllowlisted));
@@ -2332,25 +2299,6 @@
                          CorbAndCorsExtensionBrowserTest,
                          ::testing::Values(0));
 
-INSTANTIATE_TEST_SUITE_P(
-    Allowlisted_LegacyOriginHeaderBehavior_AllowlistForCors,
-    OriginHeaderExtensionBrowserTest,
-    ::testing::Values(TestParam::kAllowlisted |
-                      TestParam::kCorsForContentScripts));
-INSTANTIATE_TEST_SUITE_P(Allowlisted_NewOriginHeaderBehavior_AllowlistForCors,
-                         OriginHeaderExtensionBrowserTest,
-                         ::testing::Values(TestParam::kAllowlisted |
-                                           TestParam::kCorsForContentScripts |
-                                           TestParam::kDeriveOriginFromUrl));
-INSTANTIATE_TEST_SUITE_P(
-    NotAllowlisted_LegacyOriginHeaderBehavior_AllowlistForCors,
-    OriginHeaderExtensionBrowserTest,
-    ::testing::Values(TestParam::kCorsForContentScripts));
-INSTANTIATE_TEST_SUITE_P(
-    NotAllowlisted_NewOriginHeaderBehavior_AllowlistForCors,
-    OriginHeaderExtensionBrowserTest,
-    ::testing::Values(TestParam::kCorsForContentScripts |
-                      TestParam::kDeriveOriginFromUrl));
 INSTANTIATE_TEST_SUITE_P(Allowlisted_LegacyOriginHeaderBehavior,
                          OriginHeaderExtensionBrowserTest,
                          ::testing::Values(TestParam::kAllowlisted));
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index b8be0eaa..0f65939 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -2585,7 +2585,7 @@
   {
     "name": "font-access",
     "owners": [ "cmp", "oyiptong" ],
-    "expiry_milestone": 89
+    "expiry_milestone": 90
   },
   {
     "name": "force-color-profile",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 334e45c..2c58e50 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -832,14 +832,6 @@
     "public. This is a first step towards full enforcement of CORS-RFC1918: "
     "https://wicg.github.io/cors-rfc1918";
 
-const char kCorsForContentScriptsName[] = "CORS for content scripts";
-const char kCorsForContentScriptsDescription[] =
-    "Prevent content scripts of Chrome Extensions from bypassing CORS. "
-    "For more information about the allowlist and the changes to the "
-    "security model of content scripts, please see: "
-    "https://www.chromium.org/Home/chromium-security/"
-    "extension-content-script-fetches";
-
 const char kForceEmptyCorbAndCorsAllowlistName[] =
     "Force empty CORB and CORS allowlist";
 const char kForceEmptyCorbAndCorsAllowlistDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 18648fd..17baa69 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -463,8 +463,6 @@
 extern const char kBlockInsecurePrivateNetworkRequestsName[];
 extern const char kBlockInsecurePrivateNetworkRequestsDescription[];
 
-extern const char kCorsForContentScriptsName[];
-extern const char kCorsForContentScriptsDescription[];
 extern const char kForceEmptyCorbAndCorsAllowlistName[];
 extern const char kForceEmptyCorbAndCorsAllowlistDescription[];
 
diff --git a/chrome/browser/media/cast_remoting_connector.cc b/chrome/browser/media/cast_remoting_connector.cc
index e1c582c..5adeb37 100644
--- a/chrome/browser/media/cast_remoting_connector.cc
+++ b/chrome/browser/media/cast_remoting_connector.cc
@@ -37,7 +37,8 @@
 using media::mojom::RemotingStopReason;
 using media::mojom::RemotingSinkMetadata;
 
-class CastRemotingConnector::RemotingBridge : public media::mojom::Remoter {
+class CastRemotingConnector::RemotingBridge final
+    : public media::mojom::Remoter {
  public:
   // Constructs a "bridge" to delegate calls between the given |source| and
   // |connector|. |connector| must be valid at the time of construction, but is
diff --git a/chrome/browser/media/cast_remoting_connector.h b/chrome/browser/media/cast_remoting_connector.h
index 59a45db..a60e150a 100644
--- a/chrome/browser/media/cast_remoting_connector.h
+++ b/chrome/browser/media/cast_remoting_connector.h
@@ -75,8 +75,8 @@
 // Please see the unit tests in cast_remoting_connector_unittest.cc as a
 // reference for how CastRemotingConnector and a MediaRemoter interact to
 // start/execute/stop remoting sessions.
-class CastRemotingConnector : public base::SupportsUserData::Data,
-                              public media::mojom::RemotingSource {
+class CastRemotingConnector final : public base::SupportsUserData::Data,
+                                    public media::mojom::RemotingSource {
  public:
   ~CastRemotingConnector() final;
 
diff --git a/chrome/browser/media/offscreen_tab.cc b/chrome/browser/media/offscreen_tab.cc
index b763d90..3455173d 100644
--- a/chrome/browser/media/offscreen_tab.cc
+++ b/chrome/browser/media/offscreen_tab.cc
@@ -48,7 +48,7 @@
 // capture functionality. The WebContents native view, although attached to the
 // window tree, does not become visible on-screen (until it is properly made
 // visible by the user, for example by switching to the tab).
-class OffscreenTab::WindowAdoptionAgent : protected aura::WindowObserver {
+class OffscreenTab::WindowAdoptionAgent final : protected aura::WindowObserver {
  public:
   explicit WindowAdoptionAgent(aura::Window* content_window)
       : content_window_(content_window) {
diff --git a/chrome/browser/media/offscreen_tab.h b/chrome/browser/media/offscreen_tab.h
index 46da60a4..361d4d7e 100644
--- a/chrome/browser/media/offscreen_tab.h
+++ b/chrome/browser/media/offscreen_tab.h
@@ -43,9 +43,9 @@
 //   3. Automatically, when the associated profile is destroyed.
 //
 // This class operates exclusively on the UI thread and so is not thread-safe.
-class OffscreenTab : public ProfileObserver,
-                     protected content::WebContentsDelegate,
-                     protected content::WebContentsObserver {
+class OffscreenTab final : public ProfileObserver,
+                           protected content::WebContentsDelegate,
+                           protected content::WebContentsObserver {
  public:
   class Owner {
    public:
diff --git a/chrome/browser/media/router/providers/cast/cast_activity_manager.cc b/chrome/browser/media/router/providers/cast/cast_activity_manager.cc
index 90e0180..57cc677e 100644
--- a/chrome/browser/media/router/providers/cast/cast_activity_manager.cc
+++ b/chrome/browser/media/router/providers/cast/cast_activity_manager.cc
@@ -73,7 +73,7 @@
   // browser shuts down.  This works when the browser is closed through its UI,
   // or when it is given an opportunity to shut down gracefully, e.g. with
   // SIGINT on Linux, but not SIGTERM.
-  TerminateAllMirroringActivities();
+  TerminateAllLocalMirroringActivities();
 
   message_handler_->RemoveObserver(this);
   session_tracker_->RemoveObserver(this);
@@ -910,14 +910,16 @@
   return source.app_infos()[0].app_id;
 }
 
-void CastActivityManager::TerminateAllMirroringActivities() {
+void CastActivityManager::TerminateAllLocalMirroringActivities() {
   // Save all route IDs so we aren't iterating over |activities_| when it's
   // modified.
   std::vector<MediaRoute::Id> route_ids;
   for (const auto& pair : activities_) {
-    // Anything that isn't an app activity is a mirroring activity.
-    if (app_activities_.find(pair.first) == app_activities_.end())
+    if (pair.second->route().is_local() &&
+        // Anything that isn't an app activity is a mirroring activity.
+        app_activities_.find(pair.first) == app_activities_.end()) {
       route_ids.push_back(pair.first);
+    }
   }
 
   // Terminate the activities.
diff --git a/chrome/browser/media/router/providers/cast/cast_activity_manager.h b/chrome/browser/media/router/providers/cast/cast_activity_manager.h
index 87186c1..cdda0ed 100644
--- a/chrome/browser/media/router/providers/cast/cast_activity_manager.h
+++ b/chrome/browser/media/router/providers/cast/cast_activity_manager.h
@@ -273,7 +273,7 @@
   std::string ChooseAppId(const CastMediaSource& source,
                           const MediaSinkInternal& sink) const;
 
-  void TerminateAllMirroringActivities();
+  void TerminateAllLocalMirroringActivities();
 
   static CastActivityFactoryForTest* cast_activity_factory_for_test_;
 
diff --git a/chrome/browser/media/router/providers/cast/cast_activity_manager_unittest.cc b/chrome/browser/media/router/providers/cast/cast_activity_manager_unittest.cc
index 4c8187f..5df8f77 100644
--- a/chrome/browser/media/router/providers/cast/cast_activity_manager_unittest.cc
+++ b/chrome/browser/media/router/providers/cast/cast_activity_manager_unittest.cc
@@ -325,10 +325,20 @@
     DCHECK(mirroring_activity_);
   }
 
-  void ExpectMirroringActivityStopped() {
+  void AddRemoteMirroringSession() {
+    auto session =
+        CastSession::From(sink2_, MakeReceiverStatus(kCastStreamingAppId));
+    manager_->OnSessionAddedOrUpdated(sink2_, *session);
+    SetSessionForTest(sink2_.id(), std::move(session));
     DCHECK(mirroring_activity_);
-    EXPECT_CALL(message_handler_, StopSession).Times(1);
-    EXPECT_CALL(*mirroring_activity_, SendStopSessionMessageToClients).Times(1);
+    DCHECK(!mirroring_activity_->route().is_local());
+  }
+
+  void ExpectMirroringActivityStoppedTimes(int times) {
+    DCHECK(mirroring_activity_);
+    EXPECT_CALL(message_handler_, StopSession).Times(times);
+    EXPECT_CALL(*mirroring_activity_, SendStopSessionMessageToClients)
+        .Times(times);
   }
 
   void TerminateSession(bool expect_success) {
@@ -444,7 +454,7 @@
 
 TEST_F(CastActivityManagerTest, MirroringSessionStopped) {
   LaunchMirroringSession();
-  ExpectMirroringActivityStopped();
+  ExpectMirroringActivityStoppedTimes(1);
   mirroring_activity_->DidStop();
 }
 
@@ -613,9 +623,15 @@
   TerminateSession(false);
 }
 
-TEST_F(CastActivityManagerTest, DestructorClosesMirroringSession) {
+TEST_F(CastActivityManagerTest, DestructorClosesLocalMirroringSession) {
   LaunchMirroringSession();
-  ExpectMirroringActivityStopped();
+  ExpectMirroringActivityStoppedTimes(1);
+  manager_.reset();
+}
+
+TEST_F(CastActivityManagerTest, DestructorIgnoresNonlocalMirroringSession) {
+  AddRemoteMirroringSession();
+  ExpectMirroringActivityStoppedTimes(0);
   manager_.reset();
 }
 
diff --git a/chrome/browser/media/router/providers/dial/dial_media_route_provider.cc b/chrome/browser/media/router/providers/dial/dial_media_route_provider.cc
index 68a1654..a2ec04b 100644
--- a/chrome/browser/media/router/providers/dial/dial_media_route_provider.cc
+++ b/chrome/browser/media/router/providers/dial/dial_media_route_provider.cc
@@ -11,6 +11,8 @@
 #include "base/containers/flat_map.h"
 #include "base/no_destructor.h"
 #include "base/stl_util.h"
+#include "base/strings/strcat.h"
+#include "base/strings/stringprintf.h"
 #include "chrome/browser/media/router/data_decoder_util.h"
 #include "chrome/browser/media/router/providers/dial/dial_media_route_provider_metrics.h"
 #include "components/media_router/common/media_source.h"
@@ -19,6 +21,7 @@
 namespace media_router {
 
 namespace {
+constexpr char kLoggerComponent[] = "DialMediaRouteProvider";
 
 url::Origin CreateOrigin(const std::string& url) {
   return url::Origin::Create(GURL(url));
@@ -60,6 +63,8 @@
   media_router_.Bind(std::move(media_router));
   media_sink_service_->AddObserver(this);
 
+  media_router_->GetLogger(logger_.BindNewPipeAndPassReceiver());
+
   // |activity_manager_| might have already been set in tests.
   if (!activity_manager_)
     activity_manager_ = std::make_unique<DialActivityManager>();
@@ -91,6 +96,10 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   const MediaSinkInternal* sink = media_sink_service_->GetSinkById(sink_id);
   if (!sink) {
+    logger_->LogError(
+        mojom::LogCategory::kRoute, kLoggerComponent,
+        "Failed to create route. Cannot find sink with the sink id", sink_id,
+        media_source, presentation_id);
     std::move(callback).Run(base::nullopt, nullptr, "Unknown sink " + sink_id,
                             RouteRequestResult::SINK_NOT_FOUND);
     DialMediaRouteProviderMetrics::RecordCreateRouteResult(
@@ -101,6 +110,9 @@
   auto activity =
       DialActivity::From(presentation_id, *sink, media_source, incognito);
   if (!activity) {
+    logger_->LogError(mojom::LogCategory::kRoute, kLoggerComponent,
+                      "Failed to create route. Unsupported source.", sink_id,
+                      media_source, presentation_id);
     std::move(callback).Run(base::nullopt, nullptr,
                             "Unsupported source " + media_source,
                             RouteRequestResult::NO_SUPPORTED_PROVIDER);
@@ -112,6 +124,9 @@
   const MediaRoute::Id& route_id = activity->route.media_route_id();
   if (activity_manager_->GetActivity(route_id) ||
       activity_manager_->GetActivityBySinkId(sink_id)) {
+    logger_->LogError(mojom::LogCategory::kRoute, kLoggerComponent,
+                      "Failed to create route. Route already exists.", sink_id,
+                      media_source, presentation_id);
     std::move(callback).Run(base::nullopt, nullptr, "Activity already exists",
                             RouteRequestResult::ROUTE_ALREADY_EXISTS);
     DialMediaRouteProviderMetrics::RecordCreateRouteResult(
@@ -120,6 +135,9 @@
   }
 
   activity_manager_->AddActivity(*activity);
+  logger_->LogInfo(mojom::LogCategory::kRoute, kLoggerComponent,
+                   "Successfully created a new route.", sink_id, media_source,
+                   presentation_id);
   std::move(callback).Run(activity->route, nullptr, base::nullopt,
                           RouteRequestResult::OK);
 
@@ -168,6 +186,11 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   const DialActivity* activity = activity_manager_->GetActivity(route_id);
   if (!activity) {
+    logger_->LogInfo(
+        mojom::LogCategory::kRoute, kLoggerComponent,
+        "Failed to terminate route. Route not found with route id.", "",
+        MediaRoute::GetMediaSourceIdFromMediaRouteId(route_id),
+        MediaRoute::GetPresentationIdFromMediaRouteId(route_id));
     std::move(callback).Run("Activity not found",
                             RouteRequestResult::ROUTE_NOT_FOUND);
     DialMediaRouteProviderMetrics::RecordTerminateRouteResult(
@@ -179,6 +202,11 @@
   const MediaSinkInternal* sink =
       media_sink_service_->GetSinkById(route.media_sink_id());
   if (!sink) {
+    logger_->LogError(mojom::LogCategory::kRoute, kLoggerComponent,
+                      "Failed to terminate route. Sink not found with sink id.",
+                      route.media_sink_id(),
+                      MediaRoute::GetMediaSourceIdFromMediaRouteId(route_id),
+                      MediaRoute::GetPresentationIdFromMediaRouteId(route_id));
     std::move(callback).Run("Sink not found",
                             RouteRequestResult::SINK_NOT_FOUND);
     DialMediaRouteProviderMetrics::RecordTerminateRouteResult(
@@ -201,6 +229,11 @@
     const MediaRoute::Id& route_id,
     data_decoder::DataDecoder::ValueOrError result) {
   if (!result.value) {
+    logger_->LogError(
+        mojom::LogCategory::kRoute, kLoggerComponent,
+        base::StrCat({"Failed to parse the route message. ", *result.error}),
+        "", MediaRoute::GetMediaSourceIdFromMediaRouteId(route_id),
+        MediaRoute::GetPresentationIdFromMediaRouteId(route_id));
     ReportParseError(DialParseMessageResult::kParseError, *result.error);
     return;
   }
@@ -209,6 +242,10 @@
   std::unique_ptr<DialInternalMessage> internal_message =
       DialInternalMessage::From(std::move(*result.value), &error);
   if (!internal_message) {
+    logger_->LogError(mojom::LogCategory::kRoute, kLoggerComponent,
+                      base::StrCat({"Invalid route message. ", error}), "",
+                      MediaRoute::GetMediaSourceIdFromMediaRouteId(route_id),
+                      MediaRoute::GetPresentationIdFromMediaRouteId(route_id));
     ReportParseError(DialParseMessageResult::kInvalidMessage, error);
     return;
   }
@@ -218,6 +255,11 @@
 
   const DialActivity* activity = activity_manager_->GetActivity(route_id);
   if (!activity) {
+    logger_->LogError(
+        mojom::LogCategory::kRoute, kLoggerComponent,
+        "Failed to handle the route message. Route not found with route id.",
+        "", MediaRoute::GetMediaSourceIdFromMediaRouteId(route_id),
+        MediaRoute::GetPresentationIdFromMediaRouteId(route_id));
     return;
   }
 
@@ -225,6 +267,12 @@
   const MediaSinkInternal* sink =
       media_sink_service_->GetSinkById(route.media_sink_id());
   if (!sink) {
+    logger_->LogError(
+        mojom::LogCategory::kRoute, kLoggerComponent,
+        "Failed to handle the route message. Sink not found with sink id.",
+        route.media_sink_id(),
+        MediaRoute::GetMediaSourceIdFromMediaRouteId(route_id),
+        MediaRoute::GetPresentationIdFromMediaRouteId(route_id));
     return;
   }
 
@@ -237,6 +285,10 @@
              DialInternalMessageType::kCustomDialLaunch) {
     HandleCustomDialLaunchResponse(*activity, *internal_message);
   } else if (DialInternalMessageUtil::IsStopSessionMessage(*internal_message)) {
+    logger_->LogInfo(mojom::LogCategory::kRoute, kLoggerComponent,
+                     "Received a stop session message.", route.media_sink_id(),
+                     MediaRoute::GetMediaSourceIdFromMediaRouteId(route_id),
+                     MediaRoute::GetPresentationIdFromMediaRouteId(route_id));
     DoTerminateRoute(*activity, *sink, base::DoNothing());
   }
 }
@@ -262,6 +314,11 @@
 
   // Check if there is app info.
   if (!result.app_info) {
+    logger_->LogError(
+        mojom::LogCategory::kRoute, kLoggerComponent,
+        "Failed to send custom app launch message. Cannot find app info.",
+        sink_id, MediaRoute::GetMediaSourceIdFromMediaRouteId(route_id),
+        MediaRoute::GetPresentationIdFromMediaRouteId(route_id));
     // Note: this leaves the route in a stuck state; the client must terminate
     // the route. Maybe we should clean up the route here.
     DialMediaRouteProviderMetrics::RecordCreateRouteResult(
@@ -272,15 +329,30 @@
   // Check if activity still exists.
   auto* activity = activity_manager_->GetActivity(route_id);
   if (!activity) {
+    logger_->LogError(
+        mojom::LogCategory::kRoute, kLoggerComponent,
+        "Failed to send custom app launch message. The route is closed.",
+        sink_id, MediaRoute::GetMediaSourceIdFromMediaRouteId(route_id),
+        MediaRoute::GetPresentationIdFromMediaRouteId(route_id));
     return;
   }
 
   auto* sink = media_sink_service_->GetSinkById(sink_id);
   if (!sink) {
+    logger_->LogError(
+        mojom::LogCategory::kRoute, kLoggerComponent,
+        "Failed to send custom app launch message. Sink not found.", sink_id,
+        MediaRoute::GetMediaSourceIdFromMediaRouteId(route_id),
+        MediaRoute::GetPresentationIdFromMediaRouteId(route_id));
     // TODO(imcheng): We should remove the route when the sink is removed.
     return;
   }
 
+  logger_->LogInfo(mojom::LogCategory::kRoute, kLoggerComponent,
+                   "Sending custom app launch message", sink->id(),
+                   MediaRoute::GetMediaSourceIdFromMediaRouteId(route_id),
+                   MediaRoute::GetPresentationIdFromMediaRouteId(route_id));
+
   auto message_and_seq_number =
       internal_message_util_.CreateCustomDialLaunchMessage(
           activity->launch_info, *sink, *result.app_info);
@@ -311,9 +383,21 @@
 void DialMediaRouteProvider::HandleAppLaunchResult(
     const MediaRoute::Id& route_id,
     bool success) {
-  DialMediaRouteProviderMetrics::RecordCreateRouteResult(
-      success ? DialCreateRouteResult::kSuccess
-              : DialCreateRouteResult::kAppLaunchFailed);
+  if (success) {
+    logger_->LogInfo(mojom::LogCategory::kRoute, kLoggerComponent,
+                     "Successfully launched app.", "",
+                     MediaRoute::GetMediaSourceIdFromMediaRouteId(route_id),
+                     MediaRoute::GetPresentationIdFromMediaRouteId(route_id));
+    DialMediaRouteProviderMetrics::RecordCreateRouteResult(
+        DialCreateRouteResult::kSuccess);
+  } else {
+    logger_->LogError(mojom::LogCategory::kRoute, kLoggerComponent,
+                      "Failed to launch app.", "",
+                      MediaRoute::GetMediaSourceIdFromMediaRouteId(route_id),
+                      MediaRoute::GetPresentationIdFromMediaRouteId(route_id));
+    DialMediaRouteProviderMetrics::RecordCreateRouteResult(
+        DialCreateRouteResult::kAppLaunchFailed);
+  }
   NotifyAllOnRoutesUpdated();
 }
 
@@ -334,6 +418,14 @@
         base::BindOnce(&DialMediaRouteProvider::HandleStopAppResult,
                        base::Unretained(this), route_id, std::move(callback)));
   } else {
+    logger_->LogError(
+        mojom::LogCategory::kRoute, kLoggerComponent,
+        base::StringPrintf(
+            "Failed to terminate route. %s RouteRequestResult: %d",
+            can_stop_app.first.value_or("").c_str(),
+            static_cast<int>(can_stop_app.second)),
+        sink.id(), MediaRoute::GetMediaSourceIdFromMediaRouteId(route_id),
+        MediaRoute::GetPresentationIdFromMediaRouteId(route_id));
     std::move(callback).Run(can_stop_app.first, can_stop_app.second);
   }
 }
@@ -349,9 +441,20 @@
     NotifyAllOnRoutesUpdated();
     DialMediaRouteProviderMetrics::RecordTerminateRouteResult(
         DialTerminateRouteResult::kSuccess);
+    logger_->LogInfo(mojom::LogCategory::kRoute, kLoggerComponent,
+                     "Successfully terminated route.", "",
+                     MediaRoute::GetMediaSourceIdFromMediaRouteId(route_id),
+                     MediaRoute::GetPresentationIdFromMediaRouteId(route_id));
   } else {
     DialMediaRouteProviderMetrics::RecordTerminateRouteResult(
         DialTerminateRouteResult::kStopAppFailed);
+    logger_->LogError(
+        mojom::LogCategory::kRoute, kLoggerComponent,
+        base::StringPrintf(
+            "Failed to terminate route. %s RouteRequestResult: %d",
+            message.value_or("").c_str(), static_cast<int>(result_code)),
+        "", MediaRoute::GetMediaSourceIdFromMediaRouteId(route_id),
+        MediaRoute::GetPresentationIdFromMediaRouteId(route_id));
   }
   std::move(callback).Run(message, result_code);
 }
diff --git a/chrome/browser/media/router/providers/dial/dial_media_route_provider.h b/chrome/browser/media/router/providers/dial/dial_media_route_provider.h
index 9377ccc..339dbcd 100644
--- a/chrome/browser/media/router/providers/dial/dial_media_route_provider.h
+++ b/chrome/browser/media/router/providers/dial/dial_media_route_provider.h
@@ -200,6 +200,9 @@
 
   DialInternalMessageUtil internal_message_util_;
 
+  // Mojo remote to the logger owned by the Media Router.
+  mojo::Remote<mojom::Logger> logger_;
+
   SEQUENCE_CHECKER(sequence_checker_);
   base::WeakPtrFactory<DialMediaRouteProvider> weak_ptr_factory_{this};
   DISALLOW_COPY_AND_ASSIGN(DialMediaRouteProvider);
diff --git a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc
index 21c925f8..3b393ced 100644
--- a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc
+++ b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc
@@ -157,7 +157,7 @@
     EXPECT_FALSE(in_picture_in_picture);
   }
 
-  class WidgetBoundsChangeWaiter : public views::WidgetObserver {
+  class WidgetBoundsChangeWaiter final : public views::WidgetObserver {
    public:
     explicit WidgetBoundsChangeWaiter(views::Widget* widget)
         : widget_(widget), initial_bounds_(widget->GetWindowBoundsInScreen()) {
diff --git a/chrome/browser/picture_in_picture/picture_in_picture_window_manager.cc b/chrome/browser/picture_in_picture/picture_in_picture_window_manager.cc
index 2ee0075..215d231 100644
--- a/chrome/browser/picture_in_picture/picture_in_picture_window_manager.cc
+++ b/chrome/browser/picture_in_picture/picture_in_picture_window_manager.cc
@@ -11,7 +11,7 @@
 #include "content/public/browser/web_contents_observer.h"
 #include "ui/gfx/geometry/size.h"
 
-class PictureInPictureWindowManager::ContentsObserver
+class PictureInPictureWindowManager::ContentsObserver final
     : public content::WebContentsObserver {
  public:
   ContentsObserver(PictureInPictureWindowManager* owner,
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/user_action_monitor.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/user_action_monitor.js
index 5f9d198..bb28b4ac 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/user_action_monitor.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/user_action_monitor.js
@@ -55,15 +55,16 @@
       this.actions_.push(
           UserActionMonitor.Action.fromActionInfo(actionInfos[i]));
     }
-    if (this.actions_[0].opt_beforeActionCallback) {
-      this.actions_[0].opt_beforeActionCallback();
+    if (this.actions_[0].beforeActionCallback) {
+      this.actions_[0].beforeActionCallback();
     }
   }
 
   // Public methods.
 
   /**
-   * Returns true if the key sequence was matched. Returns false otherwise.
+   * Returns true if the key sequence should be allowed to propagate to other
+   * handlers. Returns false otherwise.
    * @param {!KeySequence} actualSequence
    * @return {boolean}
    */
@@ -85,7 +86,7 @@
     }
 
     this.expectedActionMatched_();
-    return true;
+    return expectedAction.shouldPropagate;
   }
 
   // Private methods.
@@ -93,8 +94,8 @@
   /** @private */
   expectedActionMatched_() {
     const action = this.getExpectedAction_();
-    if (action.opt_afterActionCallback) {
-      action.opt_afterActionCallback();
+    if (action.afterActionCallback) {
+      action.afterActionCallback();
     }
 
     this.nextAction_();
@@ -114,8 +115,8 @@
     }
 
     const action = this.getExpectedAction_();
-    if (action.opt_beforeActionCallback) {
-      action.opt_beforeActionCallback();
+    if (action.beforeActionCallback) {
+      action.beforeActionCallback();
     }
   }
 
@@ -155,8 +156,9 @@
  * @typedef {{
  *    type: ActionType,
  *    value: (string|Object),
+ *    shouldPropagate: (boolean|undefined),
  *    beforeActionMsg: (string|undefined),
- *    afterActionMsg: (string|undefined)
+ *    afterActionMsg: (string|undefined),
  * }}
  */
 UserActionMonitor.ActionInfo;
@@ -164,38 +166,49 @@
 // Represents an expected action.
 UserActionMonitor.Action = class {
   /**
-   * @param {ActionType} type
-   * @param {string|!KeySequence} value
-   * @param {(function():void)=} opt_beforeActionCallback Runs once before this
-   *     action is seen.
-   * @param {(function():void)=} opt_afterActionCallback Runs once after this
-   *     action is seen.
+   * Please see below for more information on arguments:
+   * type: The type of action.
+   * value: The action value.
+   * shouldPropagate: Whether or not this action should propagate to other
+   *  handlers e.g. CommandHandler.
+   * beforeActionCallback: A callback that runs once before this action is seen.
+   * afterActionCallback: A callback that runs once after this action is seen.
+   * @param {!{
+   *  type: ActionType,
+   *  value: (string|!KeySequence),
+   *  shouldPropagate: (boolean|undefined),
+   *  beforeActionCallback: (function(): void|undefined),
+   *  afterActionCallback: (function(): void|undefined)
+   * }} params
    */
-  constructor(type, value, opt_beforeActionCallback, opt_afterActionCallback) {
-    switch (type) {
+  constructor(params) {
+    /** @type {ActionType} */
+    this.type = params.type;
+    /** @type {string|!KeySequence} */
+    this.value = params.value;
+    /** @type {boolean} */
+    this.shouldPropagate =
+        (params.shouldPropagate !== undefined) ? params.shouldPropagate : true;
+    /** @type {(function():void)|undefined} */
+    this.beforeActionCallback = params.beforeActionCallback;
+    /** @type {(function():void)|undefined} */
+    this.afterActionCallback = params.afterActionCallback;
+
+    switch (this.type) {
       case ActionType.KEY_SEQUENCE:
-        if (!(value instanceof KeySequence)) {
+        if (!(this.value instanceof KeySequence)) {
           throw new Error(
               'UserActionMonitor: Must provide a KeySequence value for ' +
               'Actions of type ActionType.KEY_SEQUENCE');
         }
         break;
       default:
-        if (typeof value !== 'string') {
+        if (typeof this.value !== 'string') {
           throw new Error(
               'UserActionMonitor: Must provide a string value for Actions ' +
               'if type is other than ActionType.KEY_SEQUENCE');
         }
     }
-
-    /** @type {ActionType} */
-    this.type = type;
-    /** @type {string|!KeySequence} */
-    this.value = value;
-    /** @type {(function():void)|undefined} */
-    this.opt_beforeActionCallback = opt_beforeActionCallback;
-    /** @type {(function():void)|undefined} */
-    this.opt_afterActionCallback = opt_afterActionCallback;
   }
 
   /**
@@ -225,6 +238,7 @@
     const value = (typeof info.value === 'object') ?
         KeySequence.deserialize(info.value) :
         info.value;
+    const shouldPropagate = info.shouldPropagate;
     const beforeActionMsg = info.beforeActionMsg;
     const afterActionMsg = info.afterActionMsg;
 
@@ -244,8 +258,13 @@
       UserActionMonitor.Action.output_(afterActionMsg);
     };
 
-    return new UserActionMonitor.Action(
-        type, value, beforeActionCallback, afterActionCallback);
+    return new UserActionMonitor.Action({
+      type,
+      value,
+      shouldPropagate,
+      beforeActionCallback,
+      afterActionCallback
+    });
   }
 
   /**
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/user_action_monitor_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/user_action_monitor_test.js
index 5613428..6ae491b0 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/user_action_monitor_test.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/user_action_monitor_test.js
@@ -68,13 +68,14 @@
   this.runWithLoadedTree(this.simpleDoc, function() {
     const keySequenceActionOne = UserActionMonitor.Action.fromActionInfo(
         {type: 'key_sequence', value: {keys: {keyCode: [KeyCode.SPACE]}}});
-    const keySequenceActionTwo = new UserActionMonitor.Action(
-        'key_sequence',
-        new KeySequence(TestUtils.createMockKeyEvent(KeyCode.A)));
+    const keySequenceActionTwo = new UserActionMonitor.Action({
+      type: 'key_sequence',
+      value: new KeySequence(TestUtils.createMockKeyEvent(KeyCode.A))
+    });
     const gestureActionOne = UserActionMonitor.Action.fromActionInfo(
         {type: 'gesture', value: 'swipeUp1'});
     const gestureActionTwo =
-        new UserActionMonitor.Action('gesture', 'swipeUp2');
+        new UserActionMonitor.Action({type: 'gesture', value: 'swipeUp2'});
 
     assertFalse(keySequenceActionOne.equals(keySequenceActionTwo));
     assertFalse(keySequenceActionOne.equals(gestureActionOne));
@@ -86,7 +87,7 @@
     const cloneKeySequenceActionOne = UserActionMonitor.Action.fromActionInfo(
         {type: 'key_sequence', value: {keys: {keyCode: [KeyCode.SPACE]}}});
     const cloneGestureActionOne =
-        new UserActionMonitor.Action('gesture', 'swipeUp1');
+        new UserActionMonitor.Action({type: 'gesture', value: 'swipeUp1'});
     assertTrue(keySequenceActionOne.equals(cloneKeySequenceActionOne));
     assertTrue(gestureActionOne.equals(cloneGestureActionOne));
   });
@@ -119,7 +120,7 @@
     }
     assertCaughtAndReset();
     try {
-      new UserActionMonitor.Action('key_sequence', 'invalid');
+      new UserActionMonitor.Action({type: 'key_sequence', value: 'invalid'});
       assertTrue(false);  // Shouldn't execute
     } catch (error) {
       assertEquals(
@@ -417,3 +418,30 @@
     assertFalse(finished);
   });
 });
+
+// Tests that we can stop propagation of an action, even if it is matched.
+// In this test, we stop propagation of the Control key to avoid executing the
+// stopSpeech command.
+TEST_F('ChromeVoxUserActionMonitorTest', 'StopPropagation', function() {
+  this.runWithLoadedTree(this.simpleDoc, function() {
+    const keyboardHandler = ChromeVoxState.instance.keyboardHandler_;
+    let finished = false;
+    let executedCommand = false;
+    const actions = [{
+      type: 'key_sequence',
+      value: {keys: {keyCode: [KeyCode.CONTROL]}},
+      shouldPropagate: false
+    }];
+    const onFinished = () => finished = true;
+    ChromeVoxState.instance.createUserActionMonitor(actions, onFinished);
+    ChromeVoxKbHandler.commandHandler = function(command) {
+      executedCommand = true;
+    };
+    assertFalse(finished);
+    assertFalse(executedCommand);
+    keyboardHandler.onKeyDown(TestUtils.createMockKeyEvent(KeyCode.CONTROL));
+    keyboardHandler.onKeyUp(TestUtils.createMockKeyEvent(KeyCode.CONTROL));
+    assertFalse(executedCommand);
+    assertTrue(finished);
+  });
+});
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/common/keyboard_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/common/keyboard_handler.js
index 3e3855da..b3dc66f7 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/common/keyboard_handler.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/common/keyboard_handler.js
@@ -89,9 +89,8 @@
   const chromeVoxState = ChromeVoxState.instance;
   const monitor = chromeVoxState ? chromeVoxState.getUserActionMonitor() : null;
   if (monitor && !monitor.onKeySequence(keySequence)) {
-    // UserActionMonitor returns true if this key sequence was matched. If a
-    // key sequence is matched by the UserActionMonitor, allow it to process.
-    // Otherwise, prevent the default action.
+    // UserActionMonitor returns true if this key sequence should propagate.
+    // Prevent the default action if it returns false.
     return false;
   }
 
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/i_tutorial/components/i_tutorial.js b/chrome/browser/resources/chromeos/accessibility/chromevox/i_tutorial/components/i_tutorial.js
index be54944..24765fac4 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/i_tutorial/components/i_tutorial.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/i_tutorial/components/i_tutorial.js
@@ -170,9 +170,11 @@
             key.`],
           medium: InteractionMedium.KEYBOARD,
           curriculums: [Curriculum.QUICK_ORIENTATION],
-          actions: [
-            {type: 'key_sequence', value: {keys: {keyCode: [17 /* Ctrl */]}}}
-          ],
+          actions: [{
+            type: 'key_sequence',
+            value: {keys: {keyCode: [17 /* Ctrl */]}},
+            shouldPropagate: false
+          }],
           autoInteractive: true,
         },
 
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/tutorial_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/tutorial_test.js
index 4e6b0b04c..ecec1d3 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/tutorial_test.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/tutorial_test.js
@@ -363,8 +363,8 @@
         .call(doCmd('nextObject'))
         .expectSpeech('On, Off, and Stop', 'Button')
         .call(doCmd('forceClickOnCurrentItem'))
-        .call(this.assertActiveScreen.bind(this, 'lesson'))
         .expectSpeech('On, Off, and Stop', 'Heading 1')
+        .call(this.assertActiveScreen.bind(this, 'lesson'))
         .call(doCmd('nextButton'))
         .expectSpeech('Next lesson')
         .call(doCmd('nextButton'))
@@ -496,9 +496,10 @@
     // Helper functions. For this test, activate commands by hooking into the
     // BackgroundKeyboardHandler. This is necessary because UserActionMonitor
     // intercepts key sequences before they are routed to CommandHandler.
-    const getRangeStart = () => {
+    const getRangeStartNode = () => {
       return ChromeVoxState.instance.getCurrentRange().start.node;
     };
+
     const simulateKeyPress = (keyCode, opt_modifiers) => {
       const keyEvent = TestUtils.createMockKeyEvent(keyCode, opt_modifiers);
       keyboardHandler.onKeyDown(keyEvent);
@@ -517,25 +518,33 @@
         .expectSpeech(/Welcome to the ChromeVox tutorial./)
         .call(() => {
           assertEquals(0, tutorial.activeLessonNum);
-          firstLessonNode = getRangeStart();
+          firstLessonNode = getRangeStartNode();
         })
         .call(simulateKeyPress.bind(this, KeyCode.RIGHT, {searchKeyHeld: true}))
         .call(() => {
-          assertEquals(firstLessonNode, getRangeStart());
+          assertEquals(firstLessonNode, getRangeStartNode());
           assertEquals(0, tutorial.activeLessonNum);
         })
         .call(simulateKeyPress.bind(this, KeyCode.LEFT, {searchKeyHeld: true}))
         .call(() => {
-          assertEquals(firstLessonNode, getRangeStart());
+          assertEquals(firstLessonNode, getRangeStartNode());
           assertEquals(0, tutorial.activeLessonNum);
         })
         // Pressing space, which is the desired key sequence, should move us to
         // the next lesson.
         .call(simulateKeyPress.bind(this, KeyCode.SPACE, {}))
         .expectSpeech('Essential Keys: Control')
+        .expectSpeech(/Let's start with a few keys you'll use regularly:/)
         .call(() => {
-          assertNotEquals(firstLessonNode, getRangeStart());
           assertEquals(1, tutorial.activeLessonNum);
+          assertNotEquals(firstLessonNode, getRangeStartNode());
+        })
+        // Pressing control, which is the desired key sequence, should move us
+        // to the next lesson.
+        .call(simulateKeyPress.bind(this, KeyCode.CONTROL, {}))
+        .expectSpeech('Essential Keys: Shift')
+        .call(() => {
+          assertEquals(2, tutorial.activeLessonNum);
         })
         .replay();
   });
diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/images/icon192.png b/chrome/browser/resources/chromeos/wallpaper_manager/images/icon192.png
index 86cc40b1..95aecff 100644
--- a/chrome/browser/resources/chromeos/wallpaper_manager/images/icon192.png
+++ b/chrome/browser/resources/chromeos/wallpaper_manager/images/icon192.png
Binary files differ
diff --git a/chrome/browser/resources/nearby_share/nearby_device.html b/chrome/browser/resources/nearby_share/nearby_device.html
index 71de158..3d477918 100644
--- a/chrome/browser/resources/nearby_share/nearby_device.html
+++ b/chrome/browser/resources/nearby_share/nearby_device.html
@@ -1,9 +1,10 @@
 <style>
-  :host {
+  #wrapper {
     align-items: center;
     border: 1px solid rgba(216, 216, 216, 0.76);
     border-radius: 8px;
     box-sizing: border-box;
+    cursor: pointer;
     display: flex;
     height: 40px;
     margin-block-end: 6px;
@@ -14,19 +15,22 @@
   }
 
   :host(:focus) {
-    border-color: rgb(95, 99, 104);
     outline: none;
   }
 
-  :host([is-selected]) {
+  :host(:focus) #wrapper {
+    border-color: rgb(95, 99, 104);
+  }
+
+  :host([is-selected]) #wrapper {
     border-color: rgb(66, 133, 244);
   }
 
-  :host([is-selected]) > #done {
+  :host([is-selected]) #done {
     display: flex;
   }
 
-  :host([is-selected]) > #name {
+  :host([is-selected]) #name {
     color: rgb(26, 115, 232);
   }
 
@@ -58,7 +62,9 @@
   }
 </style>
 
-<nearby-device-icon id="icon" share-target="[[shareTarget]]">
-</nearby-device-icon>
-<div id="name">[[shareTarget.name]]</div>
-<iron-icon id="done" icon="nearby-share:done"></iron-icon>
+<div id="wrapper">
+  <nearby-device-icon id="icon" share-target="[[shareTarget]]">
+  </nearby-device-icon>
+  <div id="name">[[shareTarget.name]]</div>
+  <iron-icon id="done" icon="nearby-share:done"></iron-icon>
+</div>
diff --git a/chrome/browser/resources/nearby_share/nearby_discovery_page.html b/chrome/browser/resources/nearby_share/nearby_discovery_page.html
index 10d1bec..109bf84 100644
--- a/chrome/browser/resources/nearby_share/nearby_discovery_page.html
+++ b/chrome/browser/resources/nearby_share/nearby_discovery_page.html
@@ -28,13 +28,31 @@
   }
 
   #help {
+    align-items: flex-start;
     color: rgb(95, 99, 104);
+    display: flex;
+    flex-direction: row;
     font-size: 9px;
     line-height: 12px;
-    margin-block-end: 12px;
-    margin-block-start: 12px;
     margin-inline-end:  var(--nearby-page-space-inline);
     margin-inline-start: var(--nearby-page-space-inline);
+    padding: 8px;
+  }
+
+  #helpText {
+    margin: auto;
+  }
+
+  #helpText a {
+    color: rgb(26, 115, 232);
+    text-decoration: none;
+  }
+
+  #infoIcon {
+    flex-shrink: 0;
+    height: 20px;
+    margin-inline-end: 12px;
+    width: 20px;
   }
 
   #process-row {
@@ -69,6 +87,13 @@
         </template>
       </iron-list>
     </div>
-    <div id="help">[[i18n('nearbyShareDiscoveryPageInfo')]]</div>
+    <div id="help">
+      <iron-icon id="infoIcon" icon="nearby20:info"></iron-icon>
+      <!-- TODO(vecore): add correct url for learn more link -->
+      <!-- TODO(crbug.com/1138445) link doesn't work -->
+      <div id="helpText"
+          inner-h-t-m-l="[[getAriaLabelledHelpText_('https://google.com')]]">
+      </div>
+    </div>
   </div>
 </nearby-page-template>
diff --git a/chrome/browser/resources/nearby_share/nearby_discovery_page.js b/chrome/browser/resources/nearby_share/nearby_discovery_page.js
index e2fa14f..e4888b1 100644
--- a/chrome/browser/resources/nearby_share/nearby_discovery_page.js
+++ b/chrome/browser/resources/nearby_share/nearby_discovery_page.js
@@ -18,7 +18,7 @@
 import './shared/nearby_page_template.m.js';
 import './strings.m.js';
 
-import {assert} from 'chrome://resources/js/assert.m.js';
+import {assert, assertNotReached} from 'chrome://resources/js/assert.m.js';
 import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
 import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
@@ -206,7 +206,9 @@
 
   /** @private */
   clearShareTargets_() {
-    this.shareTargetMap_.clear();
+    if (this.shareTargetMap_) {
+      this.shareTargetMap_.clear();
+    }
     this.lastSelectedShareTarget_ = null;
     this.selectedShareTarget = null;
     this.shareTargets_ = [];
@@ -297,4 +299,64 @@
       this.selectedShareTarget = shareTarget;
     }
   },
+
+  /**
+   * Builds the html for the help text, applying the appropriate aria labels,
+   * and setting the href of the link to |linkUrl|. This function is largely
+   * copied from getAriaLabelledContent_ in <settings-localized-link>, which
+   * can't be used directly because this isn't part of settings.
+   * @param {string} linkUrl
+   * @return {string}
+   * @private
+   */
+  getAriaLabelledHelpText_(linkUrl) {
+    const tempEl = document.createElement('div');
+    const localizedString = this.i18nAdvanced('nearbyShareDiscoveryPageInfo');
+    tempEl.innerHTML = localizedString;
+
+    const ariaLabelledByIds = [];
+    tempEl.childNodes.forEach((node, index) => {
+      // Text nodes should be aria-hidden and associated with an element id
+      // that the anchor element can be aria-labelledby.
+      if (node.nodeType == Node.TEXT_NODE) {
+        const spanNode = document.createElement('span');
+        spanNode.textContent = node.textContent;
+        spanNode.id = `helpText${index}`;
+        ariaLabelledByIds.push(spanNode.id);
+        spanNode.setAttribute('aria-hidden', true);
+        node.replaceWith(spanNode);
+        return;
+      }
+      // The single element node with anchor tags should also be aria-labelledby
+      // itself in-order with respect to the entire string.
+      if (node.nodeType == Node.ELEMENT_NODE && node.nodeName == 'A') {
+        node.id = `helpLink`;
+        ariaLabelledByIds.push(node.id);
+        return;
+      }
+
+      // Only text and <a> nodes are allowed.
+      assertNotReached('nearbyShareDiscoveryPageInfo has invalid node types');
+    });
+
+    const anchorTags = tempEl.getElementsByTagName('a');
+    // In the event the localizedString contains only text nodes, populate the
+    // contents with the localizedString.
+    if (anchorTags.length == 0) {
+      return localizedString;
+    }
+
+    assert(
+        anchorTags.length == 1,
+        'nearbyShareDiscoveryPageInfo should contain exactly one anchor tag');
+    const anchorTag = anchorTags[0];
+    anchorTag.setAttribute('aria-labelledby', ariaLabelledByIds.join(' '));
+
+    if (linkUrl != '') {
+      anchorTag.href = linkUrl;
+      anchorTag.target = '_blank';
+    }
+
+    return tempEl.innerHTML;
+  },
 });
diff --git a/chrome/browser/resources/nearby_share/nearby_preview.html b/chrome/browser/resources/nearby_share/nearby_preview.html
index 947755c..a5c7903 100644
--- a/chrome/browser/resources/nearby_share/nearby_preview.html
+++ b/chrome/browser/resources/nearby_share/nearby_preview.html
@@ -23,6 +23,10 @@
     letter-spacing: 0.2px;
     line-height: 20px;
     margin-top: 6px;
+    max-height: 40px;
+    max-width: 200px;
+    overflow: hidden;
+    overflow-wrap: break-word;
     text-align: center;
   }
 </style>
diff --git a/chrome/browser/resources/new_tab_page/most_visited.html b/chrome/browser/resources/new_tab_page/most_visited.html
index caec7de8..8ec3df4 100644
--- a/chrome/browser/resources/new_tab_page/most_visited.html
+++ b/chrome/browser/resources/new_tab_page/most_visited.html
@@ -1,10 +1,11 @@
 <style include="cr-hidden-style cr-icons">
   :host {
-    --icon-size: 48px;
-    --tile-size: 112px;
-    --icon-button-color: var(--google-grey-600);
     --icon-button-color-active: var(--google-grey-refresh-700);
+    --icon-button-color: var(--google-grey-600);
+    --icon-size: 48px;
     --tile-hover-color: rgba(var(--google-grey-900-rgb), .1);
+    --tile-size: 112px;  /* top padding + icon + title margin + title */
+    --title-height: 32px;
   }
 
   #container {
@@ -26,7 +27,8 @@
     opacity: 1;
   }
 
-  #addShortcutIcon {
+  #addShortcutIcon,
+  .query-tile-icon {
     -webkit-mask-image: url(chrome://resources/images/add.svg);
     -webkit-mask-repeat: no-repeat;
     -webkit-mask-size: 100%;
@@ -35,10 +37,19 @@
     width: 24px;
   }
 
+  .query-tile-icon {
+    -webkit-mask-image: url(chrome://resources/images/icon_search.svg);
+    background-color: var(--google-grey-700);
+  }
+
   :host([use-white-add-icon]) #addShortcutIcon {
     background-color: white;
   }
 
+  :host([use-white-add-icon]) .query-tile-icon {
+    background-color: var(--google-grey-400);
+  }
+
   .tile,
   #addShortcut {
     -webkit-tap-highlight-color: transparent;
@@ -72,7 +83,7 @@
     background-color: transparent;
     border: none;
     box-shadow: none;
-    padding: 0;
+    padding: 16px 0 0;
   }
 
   :host(:not([reordering_])) .tile:hover,
@@ -101,8 +112,7 @@
     border-radius: 12px;
     color: var(--ntp-theme-text-color);
     display: flex;
-    height: 24px;
-    margin-top: 7px;
+    margin-top: 16px;
     padding: 0 8px;
     width: 88px;
   }
@@ -114,6 +124,8 @@
 
   .tile-title span {
     font-weight: 400;
+    height: var(--title-height);
+    line-height: calc(var(--title-height) / 2);
     overflow: hidden;
     text-align: center;
     text-overflow: ellipsis;
@@ -122,6 +134,13 @@
     width: 100%;
   }
 
+  .tile[query-tile] .tile-title span {
+    -webkit-box-orient: vertical;
+    -webkit-line-clamp: 2;
+    display: -webkit-box;
+    white-space: initial;
+  }
+
   :host([use-title-pill]) .tile-title span {
     text-shadow: none;
   }
@@ -176,11 +195,14 @@
     style="--column-count: [[columnCount_]]; --row-count: [[rowCount_]];">
   <dom-repeat id="tiles" items="[[tiles_]]" on-dom-change="onTilesRendered_">
     <template>
+      <!-- TOOD(crbug.com/1138578): replace the query-tile attr binding to
+      something that checks whether the tile is a repeatable query tile. -->
       <a class="tile" draggable="true" href$="[[item.url.url]]"
           title$="[[item.title]]" on-dragstart="onDragStart_"
           on-touchstart="onTouchStart_"
           hidden$="[[isHidden_(index, columnCount_)]]"
-          on-click="onTileClick_" on-keydown="onTileKeyDown_">
+          on-click="onTileClick_" on-keydown="onTileKeyDown_"
+          query-tile$="[[isHidden_(index, columnCount_)]]">
         <cr-icon-button id="actionMenuButton" class="icon-more-vert"
             title="$i18n{moreActions}" on-click="onTileActionButtonClick_"
             tabindex="0" hidden$="[[!customLinksEnabled_]]"></cr-icon-button>
@@ -188,7 +210,12 @@
             title="$i18n{linkRemove}" on-click="onTileRemoveButtonClick_"
             tabindex="0" hidden$="[[customLinksEnabled_]]"></cr-icon-button>
         <div class="tile-icon">
-          <img src$="[[getFaviconUrl_(item.url)]]" draggable="false"></img>
+          <!-- TOOD(crbug.com/1138578): replace the hidden attr binding to
+          something that checks whether the tile is a repeatable query tile. -->
+          <img src$="[[getFaviconUrl_(item.url)]]" draggable="false"
+              hidden$="[[isHidden_(index, columnCount_)]]"></img>
+          <div class="query-tile-icon" draggable="false"
+              hidden$="[[!isHidden_(index, columnCount_)]]"></div>
         </div>
         <div class$="tile-title [[getTileTitleDirectionClass_(item)]]">
           <span>[[item.title]]</span>
diff --git a/chrome/browser/resources/settings/a11y_page/a11y_page.html b/chrome/browser/resources/settings/a11y_page/a11y_page.html
index 346eacf..44d8b67 100644
--- a/chrome/browser/resources/settings/a11y_page/a11y_page.html
+++ b/chrome/browser/resources/settings/a11y_page/a11y_page.html
@@ -37,6 +37,7 @@
             class="hr"
             hidden$="[[!showFocusHighlightOption_]]"
             pref="{{prefs.settings.a11y.focus_highlight}}"
+            on-setting-boolean-control-change="onFocusHighlightChange_"
             label="$i18n{focusHighlightLabel}">
         </settings-toggle-button>
         <settings-toggle-button
diff --git a/chrome/browser/resources/settings/a11y_page/a11y_page.js b/chrome/browser/resources/settings/a11y_page/a11y_page.js
index 497f419..782f0b7 100644
--- a/chrome/browser/resources/settings/a11y_page/a11y_page.js
+++ b/chrome/browser/resources/settings/a11y_page/a11y_page.js
@@ -198,6 +198,15 @@
   onEnableLiveCaptionSubtitleChanged_(enableLiveCaptionSubtitle) {
     this.enableLiveCaptionSubtitle_ = enableLiveCaptionSubtitle;
   },
+
+  /**
+   * @private
+   * @param {!Event} event
+   */
+  onFocusHighlightChange_(event) {
+    chrome.metricsPrivate.recordBoolean(
+        'Accessibility.FocusHighlight.ToggleEnabled', event.target.checked);
+  },
   // </if>
 
   // <if expr="chromeos">
diff --git a/chrome/browser/resources/settings/chromeos/ambient_mode_page/album_list.html b/chrome/browser/resources/settings/chromeos/ambient_mode_page/album_list.html
index 95ac8c5..932f5115 100644
--- a/chrome/browser/resources/settings/chromeos/ambient_mode_page/album_list.html
+++ b/chrome/browser/resources/settings/chromeos/ambient_mode_page/album_list.html
@@ -18,16 +18,17 @@
 
       paper-spinner-lite {
         display: block;
-        height: 32px;
-        margin: auto;
-        width: 32px;
+        height: 28px;
+        margin: 150px auto;
+        width: 28px;
       }
 
       iron-list > :focus {
         background-color: var(--cr-focused-item-color);
       }
     </style>
-    <paper-spinner-lite active="[[!albums]]"></paper-spinner-lite>
+    <paper-spinner-lite active="[[!albums]]" hidden="[[albums]]">
+    </paper-spinner-lite>
 
     <iron-list grid scrollable scroll-target="document" items="{{albums}}">
       <template>
diff --git a/chrome/browser/resources/settings/chromeos/ambient_mode_page/ambient_mode_page.html b/chrome/browser/resources/settings/chromeos/ambient_mode_page/ambient_mode_page.html
index 9b68488..c17af5f9 100644
--- a/chrome/browser/resources/settings/chromeos/ambient_mode_page/ambient_mode_page.html
+++ b/chrome/browser/resources/settings/chromeos/ambient_mode_page/ambient_mode_page.html
@@ -6,6 +6,7 @@
 <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
 <link rel="import" href="chrome://resources/html/i18n_behavior.html">
 <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-spinner/paper-spinner-lite.html">
 <link rel="import" href="constants.html">
 <link rel="import" href="topic_source_list.html">
 <link rel="import" href="../deep_linking_behavior.html">
@@ -53,6 +54,12 @@
         padding-inline-start: var(--cr-section-padding);
       }
 
+      paper-spinner-lite {
+        display: block;
+        height: 28px;
+        margin: 100px auto;
+        width: 28px;
+      }
     </style>
     <h2 id="pageDescription">
       $i18n{ambientModePageDescription}
@@ -66,15 +73,20 @@
         deep-link-focus-id$="[[Setting.kAmbientModeOnOff]]">
     </settings-toggle-button>
 
-    <template is="dom-if" if="[[prefs.settings.ambient_mode.enabled.value]]">
-      <div id="topicSourceListDiv" class="layout vertical flex">
+    <paper-spinner-lite active='[[!showSettings_]]' hidden='[[showSettings_]]'>
+    </paper-spinner-lite>
+
+    <template is="dom-if" if="[[showSettings_]]">
+      <div id="topicSourceListDiv" class="layout vertical flex"
+          aria-hidden="[[disableSettings_]]">
         <topic-source-list topic-sources="[[topicSources_]]"
             selected-topic-source="[[selectedTopicSource_]]"
             has-google-photos-albums="[[hasGooglePhotosAlbums_]]"
-            disabled="[[!isValidTopicSource_(selectedTopicSource_)]]">
+            disabled='[[disableSettings_]]'>
         </topic-source-list>
       </div>
-      <div id="weatherDiv" class="layout vertical flex">
+      <div id="weatherDiv" class="layout vertical flex"
+          aria-hidden="[[disableSettings_]]">
         <h2 id="weatherTitle" aria-hidden="true">
           $i18n{ambientModeWeatherTitle}
         </h2>
@@ -82,7 +94,7 @@
           <cr-radio-group
               id="ambientTemperatureUnit"
               selected="{{selectedTemperatureUnit_}}"
-              disabled$="[[!isValidTemperatureUnit_(selectedTemperatureUnit_)]]"
+              disabled$='[[disableSettings_]]'
               aria-labelledby="weatherTitle">
             <cr-radio-button
                 name="[[AmbientModeTemperatureUnit_.FAHRENHEIT]]"
diff --git a/chrome/browser/resources/settings/chromeos/ambient_mode_page/ambient_mode_page.js b/chrome/browser/resources/settings/chromeos/ambient_mode_page/ambient_mode_page.js
index 1912009..6cb95ac6 100644
--- a/chrome/browser/resources/settings/chromeos/ambient_mode_page/ambient_mode_page.js
+++ b/chrome/browser/resources/settings/chromeos/ambient_mode_page/ambient_mode_page.js
@@ -72,6 +72,19 @@
         chromeos.settings.mojom.Setting.kAmbientModeSource,
       ]),
     },
+
+    /** @private */
+    showSettings_: {
+      type: Boolean,
+      computed: 'computeShowSettings_(' +
+          'selectedTopicSource_, selectedTemperatureUnit_)',
+    },
+
+    /** @private */
+    disableSettings_: {
+      type: Boolean,
+      computed: 'computeDisableSettings_(prefs.settings.ambient_mode.*)',
+    }
   },
 
   listeners: {
@@ -194,5 +207,24 @@
     params.append('topicSource', JSON.stringify(event.detail));
     settings.Router.getInstance().navigateTo(
         settings.routes.AMBIENT_MODE_PHOTOS, params);
+  },
+
+  /**
+   * Whether to show settings.
+   * @return {boolean}
+   * @private
+   */
+  computeShowSettings_() {
+    return this.isValidTopicSource_(this.selectedTopicSource_) &&
+        this.isValidTemperatureUnit_(this.selectedTemperatureUnit_);
+  },
+
+  /**
+   * Whether to disable settings.
+   * @return {boolean}
+   * @private
+   */
+  computeDisableSettings_() {
+    return !this.getPref('settings.ambient_mode.enabled').value;
   }
 });
diff --git a/chrome/browser/resources/settings/chromeos/ambient_mode_page/ambient_mode_photos_page.html b/chrome/browser/resources/settings/chromeos/ambient_mode_page/ambient_mode_photos_page.html
index d659fc3..0a20189 100644
--- a/chrome/browser/resources/settings/chromeos/ambient_mode_page/ambient_mode_photos_page.html
+++ b/chrome/browser/resources/settings/chromeos/ambient_mode_page/ambient_mode_photos_page.html
@@ -16,8 +16,13 @@
 <dom-module id="settings-ambient-mode-photos-page">
   <template>
     <style include="settings-shared">
+      #pageDescription {
+        display: flex;
+        min-height: 32px;
+        padding: 0 var(--cr-section-padding);
+      }
     </style>
-    <settings-localized-link class="cr-row first"
+    <settings-localized-link id="pageDescription"
         localized-string="[[getTitleInnerHtml_(topicSource)]]">
     </settings-localized-link>
 
diff --git a/chrome/browser/resources/settings/chromeos/ambient_mode_page/topic_source_item.html b/chrome/browser/resources/settings/chromeos/ambient_mode_page/topic_source_item.html
index 3de6b86..149a856 100644
--- a/chrome/browser/resources/settings/chromeos/ambient_mode_page/topic_source_item.html
+++ b/chrome/browser/resources/settings/chromeos/ambient_mode_page/topic_source_item.html
@@ -43,7 +43,8 @@
 
       <cr-icon-button class="subpage-arrow" id="subpage-button"
           on-click="onSubpageArrowClick_" tabindex$="[[tabindex]]"
-          aria-label$="[[buttonLabel]]">
+          aria-label$="[[buttonLabel]]"
+          disabled$="[[disabled]]">
       </cr-icon-button>
     </div>
   </template>
diff --git a/chrome/browser/resources/settings/chromeos/ambient_mode_page/topic_source_list.html b/chrome/browser/resources/settings/chromeos/ambient_mode_page/topic_source_list.html
index c1b2937..5cfa45f9 100644
--- a/chrome/browser/resources/settings/chromeos/ambient_mode_page/topic_source_list.html
+++ b/chrome/browser/resources/settings/chromeos/ambient_mode_page/topic_source_list.html
@@ -29,14 +29,16 @@
         background-color: var(--cr-focused-item-color);
       }
     </style>
-    <h2 id="topicSourceTitle">$i18n{ambientModeTopicSourceTitle}</h2>
+    <h2 id="topicSourceTitle" aria-hidden="true">
+      $i18n{ambientModeTopicSourceTitle}
+    </h2>
 
     <iron-list id="topicSourceList" items="[[topicSources]]">
       <template>
-        <topic-source-item item="[[item]]" tabindex$="[[tabIndex]]"
+        <topic-source-item item="[[item]]" disabled$="[[disabled]]"
+            tabindex$="[[computeTabIndex_(tabIndex, disabled)]]"
             has-google-photos-albums="[[hasGooglePhotosAlbums]]"
-            checked="[[isSelected_(item, selectedTopicSource)]]"
-            disabled$="[[disabled]]">
+            checked="[[isSelected_(item, selectedTopicSource)]]">
         </topic-source-item>
       </template>
     </iron-list>
diff --git a/chrome/browser/resources/settings/chromeos/ambient_mode_page/topic_source_list.js b/chrome/browser/resources/settings/chromeos/ambient_mode_page/topic_source_list.js
index 29aa2b2..ddb7ee5 100644
--- a/chrome/browser/resources/settings/chromeos/ambient_mode_page/topic_source_list.js
+++ b/chrome/browser/resources/settings/chromeos/ambient_mode_page/topic_source_list.js
@@ -30,6 +30,12 @@
     },
 
     hasGooglePhotosAlbums: Boolean,
+
+    /**
+     * The items in this list will be disabled when |selectedTopicSource| is
+     * |AmbientModeTopicSource.UNKNOWN|.
+     */
+    disabled: Boolean,
   },
 
   /**
@@ -39,4 +45,18 @@
   isSelected_(topic_source) {
     return this.selectedTopicSource === topic_source;
   },
+
+  /**
+   * @param {number} tabIndex
+   * @param {boolean} disabled
+   * @return {number}
+   * @private
+   */
+  computeTabIndex_(tabIndex, disabled) {
+    // Disabled "topic-source-item" cannot be navigated into.
+    if (disabled) {
+      return -1;
+    }
+    return tabIndex;
+  }
 });
diff --git a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_port_forwarding.html b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_port_forwarding.html
index 2199c05..ab2bd73 100644
--- a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_port_forwarding.html
+++ b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_port_forwarding.html
@@ -29,7 +29,7 @@
       }
 
       .column-title {
-        color: var(--google-grey-500);
+        color: var(--google-grey-700);
       }
 
       .label-column {
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_about_page/BUILD.gn
index 0f43363..a8d878d 100644
--- a/chrome/browser/resources/settings/chromeos/os_about_page/BUILD.gn
+++ b/chrome/browser/resources/settings/chromeos/os_about_page/BUILD.gn
@@ -9,6 +9,7 @@
   deps = [
     ":channel_switcher_dialog",
     ":detailed_build_info",
+    ":edit_hostname_dialog",
     ":os_about_page",
   ]
 }
@@ -33,6 +34,8 @@
 
 js_library("detailed_build_info") {
   deps = [
+    ":channel_switcher_dialog",
+    ":edit_hostname_dialog",
     "..:deep_linking_behavior",
     "..:os_route",
     "../..:router",
@@ -52,11 +55,19 @@
   ]
 }
 
+js_library("edit_hostname_dialog") {
+  deps = [
+    "../../about_page:about_page_browser_proxy",
+    "//ui/webui/resources/js:load_time_data",
+  ]
+}
+
 js_type_check("closure_compile_module") {
   is_polymer3 = true
   deps = [
     ":channel_switcher_dialog.m",
     ":detailed_build_info.m",
+    ":edit_hostname_dialog.m",
     ":os_about_page.m",
     ":update_warning_dialog.m",
   ]
@@ -76,6 +87,8 @@
 js_library("detailed_build_info.m") {
   sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_about_page/detailed_build_info.m.js" ]
   deps = [
+    ":channel_switcher_dialog.m",
+    ":edit_hostname_dialog.m",
     "..:deep_linking_behavior.m",
     "..:os_route.m",
     "../..:router.m",
@@ -87,6 +100,17 @@
   extra_deps = [ ":detailed_build_info_module" ]
 }
 
+js_library("edit_hostname_dialog.m") {
+  sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_about_page/edit_hostname_dialog.m.js" ]
+  deps = [
+    "../../about_page:about_page_browser_proxy.m",
+    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+    "//ui/webui/resources/js:assert.m",
+    "//ui/webui/resources/js:load_time_data.m",
+  ]
+  extra_deps = [ ":edit_hostname_dialog_module" ]
+}
+
 js_library("os_about_page.m") {
   sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.m.js" ]
   deps = [
@@ -122,6 +146,7 @@
   public_deps = [
     ":channel_switcher_dialog_module",
     ":detailed_build_info_module",
+    ":edit_hostname_dialog_module",
     ":os_about_page_module",
     ":update_warning_dialog_module",
   ]
@@ -145,6 +170,15 @@
   auto_imports = os_settings_auto_imports
 }
 
+polymer_modulizer("edit_hostname_dialog") {
+  js_file = "edit_hostname_dialog.js"
+  html_file = "edit_hostname_dialog.html"
+  html_type = "dom-module"
+  migrated_imports = settings_migrated_imports
+  namespace_rewrites = os_settings_namespace_rewrites
+  auto_imports = os_settings_auto_imports
+}
+
 polymer_modulizer("os_about_page") {
   js_file = "os_about_page.js"
   html_file = "os_about_page.html"
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/detailed_build_info.html b/chrome/browser/resources/settings/chromeos/os_about_page/detailed_build_info.html
index d43da74..c99b8b5 100644
--- a/chrome/browser/resources/settings/chromeos/os_about_page/detailed_build_info.html
+++ b/chrome/browser/resources/settings/chromeos/os_about_page/detailed_build_info.html
@@ -1,19 +1,20 @@
 <link rel="import" href="chrome://resources/html/polymer.html">
 
-<link rel="import" href="chrome://resources/html/assert.html">
-<link rel="import" href="chrome://resources/html/cr/ui/focus_without_ink.html">
-<link rel="import" href="../../about_page/about_page_browser_proxy.html">
-<link rel="import" href="channel_switcher_dialog.html">
-<link rel="import" href="../deep_linking_behavior.html">
-<link rel="import" href="../os_route.html">
-<link rel="import" href="../../router.html">
-<link rel="import" href="../../i18n_setup.html">
-<link rel="import" href="../../settings_shared_css.html">
-<link rel="import" href="../localized_link/localized_link.html">
 <link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
 <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator.html">
 <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator_behavior.html">
+<link rel="import" href="chrome://resources/html/assert.html">
+<link rel="import" href="chrome://resources/html/cr/ui/focus_without_ink.html">
 <link rel="import" href="chrome://resources/html/i18n_behavior.html">
+<link rel="import" href="../../about_page/about_page_browser_proxy.html">
+<link rel="import" href="../../i18n_setup.html">
+<link rel="import" href="../../router.html">
+<link rel="import" href="../../settings_shared_css.html">
+<link rel="import" href="../deep_linking_behavior.html">
+<link rel="import" href="../localized_link/localized_link.html">
+<link rel="import" href="../os_route.html">
+<link rel="import" href="channel_switcher_dialog.html">
+<link rel="import" href="edit_hostname_dialog.html">
 
 <dom-module id="settings-detailed-build-info">
   <template>
@@ -73,9 +74,14 @@
             ChromeOS-102938
           </div>
         </div>
-        <cr-icon-button class="icon-edit">
+        <cr-icon-button class="icon-edit" on-click="onEditHostnameTap_">
         </cr-icon-button>
       </div>
+      <template is="dom-if" if="[[showEditHostnameDialog_]]" restamp>
+        <edit-hostname-dialog
+            on-close="onEditHostnameDialogClosed_">
+        </edit-hostname-dialog>
+      </template>
     </template>
     <div id="buildDetailsLinkContainer" class="settings-box">
       <div class="start" id="aboutBuildDetailsTitle">
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/detailed_build_info.js b/chrome/browser/resources/settings/chromeos/os_about_page/detailed_build_info.js
index 91364439..7d01a66 100644
--- a/chrome/browser/resources/settings/chromeos/os_about_page/detailed_build_info.js
+++ b/chrome/browser/resources/settings/chromeos/os_about_page/detailed_build_info.js
@@ -30,6 +30,9 @@
     showChannelSwitcherDialog_: Boolean,
 
     /** @private */
+    showEditHostnameDialog_: Boolean,
+
+    /** @private */
     canChangeChannel_: Boolean,
 
     eolMessageWithMonthAndYear: {
@@ -141,6 +144,15 @@
   },
 
   /**
+   * @param {!Event} e
+   * @private
+   */
+  onEditHostnameTap_(e) {
+    e.preventDefault();
+    this.showEditHostnameDialog_ = true;
+  },
+
+  /**
    * @return {boolean}
    * @private
    */
@@ -187,4 +199,11 @@
     cr.ui.focusWithoutInk(assert(this.$$('cr-button')));
     this.updateChannelInfo_();
   },
+
+  /** @private */
+  onEditHostnameDialogClosed_() {
+    this.showEditHostnameDialog_ = false;
+    cr.ui.focusWithoutInk(assert(this.$$('cr-button')));
+    // TODO(jhawkins): Verify hostname property updated at this point.
+  },
 });
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/edit_hostname_dialog.html b/chrome/browser/resources/settings/chromeos/os_about_page/edit_hostname_dialog.html
new file mode 100644
index 0000000..8a64870
--- /dev/null
+++ b/chrome/browser/resources/settings/chromeos/os_about_page/edit_hostname_dialog.html
@@ -0,0 +1,50 @@
+<link rel="import" href="chrome://resources/html/polymer.html">
+
+<link rel="import" href="chrome://resources/cr_elements/cr_button/cr_button.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_radio_group/cr_radio_group.html">
+<link rel="import" href="chrome://resources/html/assert.html">
+<link rel="import" href="chrome://resources/html/load_time_data.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-selector/iron-selector.html">
+<link rel="import" href="../../about_page/about_page_browser_proxy.html">
+<link rel="import" href="../../settings_shared_css.html">
+
+<dom-module id="edit-hostname-dialog">
+  <template>
+    <style include="settings-shared">
+      cr-input {
+        --cr-input-error-display: none;
+      }
+
+      #input-subtext {
+        display: flex;
+      }
+
+      #input-subtext span:last-child {
+        margin-inline-start: auto;
+      }
+    </style>
+    <cr-dialog id="dialog" show-on-attach>
+      <div slot="title">$i18n{aboutEditDeviceName}</div>
+      <div slot="body">
+        <div>$i18n{aboutDeviceNameInfo}</div>
+        <cr-input></cr-input>
+        <div id="input-subtext">
+          <span>$i18n{aboutDeviceNameConstraints}</span>
+          <span>1/15</span>
+        </div>
+      </div>
+      <div slot="button-container">
+        <cr-button class="cancel-button" on-click="onCancelTap_">
+          $i18n{cancel}
+        </cr-button>
+        <cr-button class="action-button" on-click="onDoneTap_">
+          $i18n{done}
+        </cr-button>
+      </div>
+    </cr-dialog>
+  </template>
+  <script src="edit_hostname_dialog.js"></script>
+</dom-module>
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/edit_hostname_dialog.js b/chrome/browser/resources/settings/chromeos/os_about_page/edit_hostname_dialog.js
new file mode 100644
index 0000000..fa76e09
--- /dev/null
+++ b/chrome/browser/resources/settings/chromeos/os_about_page/edit_hostname_dialog.js
@@ -0,0 +1,21 @@
+// Copyright 2020 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 'edit-hostname-dialog' is a component allowing the
+ * user to edit the device hostname.
+ */
+Polymer({
+  is: 'edit-hostname-dialog',
+
+  /** @private */
+  onCancelTap_() {
+    this.$.dialog.close();
+  },
+
+  /** @private */
+  onDoneTap_() {
+    this.$.dialog.close();
+  },
+});
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_resources_v3.grdp b/chrome/browser/resources/settings/chromeos/os_settings_resources_v3.grdp
index 9080e5e7..5211c1a 100644
--- a/chrome/browser/resources/settings/chromeos/os_settings_resources_v3.grdp
+++ b/chrome/browser/resources/settings/chromeos/os_settings_resources_v3.grdp
@@ -521,23 +521,28 @@
            use_base_dir="false"
            compress="false"
            type="BINDATA" />
-  <include name="IDR_OS_SETTINGS_OS_PRINTING_PAGE_OS_ABOUT_PAGE_M_JS"
+  <include name="IDR_OS_SETTINGS_OS_ABOUT_PAGE_OS_ABOUT_PAGE_M_JS"
            file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.m.js"
            use_base_dir="false"
            compress="false"
            preprocess="true"
            type="BINDATA" />
-  <include name="IDR_OS_SETTINGS_OS_PRINTING_PAGE_CHANNEL_SWITCHER_DIALOG_M_JS"
+  <include name="IDR_OS_SETTINGS_OS_ABOUT_PAGE_CHANNEL_SWITCHER_DIALOG_M_JS"
            file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_about_page/channel_switcher_dialog.m.js"
            use_base_dir="false"
            compress="false"
            type="BINDATA" />
-  <include name="IDR_OS_SETTINGS_OS_PRINTING_PAGE_DETAILED_BUILD_INFO_M_JS"
+  <include name="IDR_OS_SETTINGS_OS_ABOUT_PAGE_DETAILED_BUILD_INFO_M_JS"
            file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_about_page/detailed_build_info.m.js"
            use_base_dir="false"
            compress="false"
            type="BINDATA" />
-  <include name="IDR_OS_SETTINGS_OS_PRINTING_PAGE_UPDATE_WARNING_DIALOG_M_JS"
+  <include name="IDR_OS_SETTINGS_OS_ABOUT_PAGE_EDIT_HOSTNAME_DIALOG_M_JS"
+           file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_about_page/edit_hostname_dialog.m.js"
+           use_base_dir="false"
+           compress="false"
+           type="BINDATA" />
+  <include name="IDR_OS_SETTINGS_OS_ABOUT_PAGE_UPDATE_WARNING_DIALOG_M_JS"
            file="${root_gen_dir}/chrome/browser/resources/settings/chromeos/os_about_page/update_warning_dialog.m.js"
            use_base_dir="false"
            compress="false"
diff --git a/chrome/browser/resources/settings/os_settings_resources.grd b/chrome/browser/resources/settings/os_settings_resources.grd
index 62921a83..1c3b329 100644
--- a/chrome/browser/resources/settings/os_settings_resources.grd
+++ b/chrome/browser/resources/settings/os_settings_resources.grd
@@ -372,6 +372,12 @@
       <structure name="IDR_OS_SETTINGS_DETAILED_BUILD_INFO_HTML"
                  file="chromeos/os_about_page/detailed_build_info.html"
                  compress="false" type="chrome_html" />
+      <structure name="IDR_OS_SETTINGS_EDIT_HOSTNAME_DIALOG_HTML"
+                 file="chromeos/os_about_page/edit_hostname_dialog.html"
+                 compress="false" type="chrome_html" />
+      <structure name="IDR_OS_SETTINGS_EDIT_HOSTNAME_DIALOG_JS"
+                 file="chromeos/os_about_page/edit_hostname_dialog.js"
+                 compress="false" type="chrome_html" />
       <structure name="IDR_OS_SETTINGS_UPDATE_WARNING_DIALOG_HTML"
                  file="chromeos/os_about_page/update_warning_dialog.html"
                  compress="false" type="chrome_html" />
diff --git a/chrome/browser/ui/app_list/app_list_client_impl_browsertest.cc b/chrome/browser/ui/app_list/app_list_client_impl_browsertest.cc
index 7f66935..e0ccb47c 100644
--- a/chrome/browser/ui/app_list/app_list_client_impl_browsertest.cc
+++ b/chrome/browser/ui/app_list/app_list_client_impl_browsertest.cc
@@ -17,7 +17,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/bind_test_util.h"
 #include "base/test/metrics/histogram_tester.h"
-#include "base/test/scoped_feature_list.h"
 #include "build/branding_buildflags.h"
 #include "build/build_config.h"
 #include "chrome/browser/apps/app_service/app_launch_params.h"
diff --git a/chrome/browser/ui/global_media_controls/presentation_request_notification_item.h b/chrome/browser/ui/global_media_controls/presentation_request_notification_item.h
index ca6dfeb..40299e1 100644
--- a/chrome/browser/ui/global_media_controls/presentation_request_notification_item.h
+++ b/chrome/browser/ui/global_media_controls/presentation_request_notification_item.h
@@ -19,7 +19,7 @@
 class StartPresentationContext;
 }  // namespace media_router
 
-class PresentationRequestNotificationItem
+class PresentationRequestNotificationItem final
     : public media_message_center::MediaNotificationItem {
  public:
   PresentationRequestNotificationItem(
diff --git a/chrome/browser/ui/global_media_controls/presentation_request_notification_provider.h b/chrome/browser/ui/global_media_controls/presentation_request_notification_provider.h
index 8fe8e045..22b6821 100644
--- a/chrome/browser/ui/global_media_controls/presentation_request_notification_provider.h
+++ b/chrome/browser/ui/global_media_controls/presentation_request_notification_provider.h
@@ -38,7 +38,7 @@
 // Once a Cast/Presentation session has been created, this class is no longer
 // involved; at that point CastMediaNotificationProvider become responsible for
 // managing the notification for an active session.
-class PresentationRequestNotificationProvider
+class PresentationRequestNotificationProvider final
     : public media_router::WebContentsPresentationManager::Observer,
       public MediaNotificationServiceObserver {
  public:
diff --git a/chrome/browser/ui/popup_browsertest.cc b/chrome/browser/ui/popup_browsertest.cc
index fdf4395..754f866e 100644
--- a/chrome/browser/ui/popup_browsertest.cc
+++ b/chrome/browser/ui/popup_browsertest.cc
@@ -63,7 +63,7 @@
 INSTANTIATE_TEST_SUITE_P(All, PopupBrowserTest, ::testing::Bool());
 
 // A helper class to wait for widget bounds changes beyond given thresholds.
-class WidgetBoundsChangeWaiter : public views::WidgetObserver {
+class WidgetBoundsChangeWaiter final : public views::WidgetObserver {
  public:
   WidgetBoundsChangeWaiter(views::Widget* widget, int move_by, int resize_by)
       : widget_(widget),
diff --git a/chrome/browser/ui/views/frame/tab_strip_region_view.cc b/chrome/browser/ui/views/frame/tab_strip_region_view.cc
index 448ecd06..ff1c6bc 100644
--- a/chrome/browser/ui/views/frame/tab_strip_region_view.cc
+++ b/chrome/browser/ui/views/frame/tab_strip_region_view.cc
@@ -67,13 +67,14 @@
         views::FlexSpecification(base::BindRepeating(
             &TabScrollContainerFlexRule, base::Unretained(tab_strip_))));
 
-    auto left_scroll = std::make_unique<views::ImageButton>(base::BindRepeating(
-        &TabStripRegionView::ScrollLeft, base::Unretained(this)));
-    auto right_scroll =
-        std::make_unique<views::ImageButton>(base::BindRepeating(
-            &TabStripRegionView::ScrollRight, base::Unretained(this)));
-    left_scroll_ = AddChildView(std::move(left_scroll));
-    right_scroll_ = AddChildView(std::move(right_scroll));
+    auto leading_scroll_button = std::make_unique<views::ImageButton>(
+        base::BindRepeating(&TabStripRegionView::ScrollTowardsLeadingTab,
+                            base::Unretained(this)));
+    auto trailing_scroll_button = std::make_unique<views::ImageButton>(
+        base::BindRepeating(&TabStripRegionView::ScrollTowardsTrailingTab,
+                            base::Unretained(this)));
+    leading_scroll_button_ = AddChildView(std::move(leading_scroll_button));
+    trailing_scroll_button_ = AddChildView(std::move(trailing_scroll_button));
   } else {
     tab_strip_container_ = AddChildView(std::move(tab_strip));
 
@@ -157,10 +158,12 @@
         TabActive::kInactive, BrowserFrameActiveState::kUseCurrent);
     SkColor foreground_color = tab_strip_->GetTabForegroundColor(
         TabActive::kInactive, background_color);
-    views::SetImageFromVectorIconWithColor(
-        left_scroll_, kScrollingTabstripLeftIcon, foreground_color);
-    views::SetImageFromVectorIconWithColor(
-        right_scroll_, kScrollingTabstripRightIcon, foreground_color);
+    views::SetImageFromVectorIconWithColor(leading_scroll_button_,
+                                           kScrollingTabstripLeadingIcon,
+                                           foreground_color);
+    views::SetImageFromVectorIconWithColor(trailing_scroll_button_,
+                                           kScrollingTabstripTrailingIcon,
+                                           foreground_color);
   }
   tab_strip_->FrameColorsChanged();
   SchedulePaint();
@@ -222,7 +225,7 @@
   return size().width() - reserved_width;
 }
 
-void TabStripRegionView::ScrollLeft() {
+void TabStripRegionView::ScrollTowardsLeadingTab() {
   views::ScrollView* scroll_view_container =
       static_cast<views::ScrollView*>(tab_strip_container_);
   gfx::Rect visible_content = scroll_view_container->GetVisibleRect();
@@ -232,7 +235,7 @@
   scroll_view_container->contents()->ScrollRectToVisible(scroll);
 }
 
-void TabStripRegionView::ScrollRight() {
+void TabStripRegionView::ScrollTowardsTrailingTab() {
   views::ScrollView* scroll_view_container =
       static_cast<views::ScrollView*>(tab_strip_container_);
   gfx::Rect visible_content = scroll_view_container->GetVisibleRect();
diff --git a/chrome/browser/ui/views/frame/tab_strip_region_view.h b/chrome/browser/ui/views/frame/tab_strip_region_view.h
index d44f52d..b14181f 100644
--- a/chrome/browser/ui/views/frame/tab_strip_region_view.h
+++ b/chrome/browser/ui/views/frame/tab_strip_region_view.h
@@ -52,14 +52,17 @@
 
   int CalculateTabStripAvailableWidth();
 
-  void ScrollLeft();
-  void ScrollRight();
+  // Scrolls the tabstrip towards the first tab in the tabstrip.
+  void ScrollTowardsLeadingTab();
+
+  // Scrolls the tabstrip towards the last tab in the tabstrip.
+  void ScrollTowardsTrailingTab();
 
   views::View* tab_strip_container_;
   TabStrip* tab_strip_;
   TabSearchButton* tab_search_button_ = nullptr;
-  views::ImageButton* left_scroll_;
-  views::ImageButton* right_scroll_;
+  views::ImageButton* leading_scroll_button_;
+  views::ImageButton* trailing_scroll_button_;
 };
 
 #endif  // CHROME_BROWSER_UI_VIEWS_FRAME_TAB_STRIP_REGION_VIEW_H_
diff --git a/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.cc b/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.cc
index 0c44963..c5bf6d8 100644
--- a/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.cc
+++ b/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.cc
@@ -100,7 +100,14 @@
       ContentSettingsType::PLUGINS) {
     auto* learn_more_button =
         SetExtraView(views::CreateVectorImageButtonWithNativeTheme(
-            this, vector_icons::kHelpOutlineIcon));
+            base::BindRepeating(
+                [](Browser* browser) {
+                  chrome::AddSelectedTabWithURL(
+                      browser, GURL(chrome::kFlashDeprecationLearnMoreURL),
+                      ui::PAGE_TRANSITION_LINK);
+                },
+                base::Unretained(browser)),
+            vector_icons::kHelpOutlineIcon));
     learn_more_button->SetFocusForPlatform();
     learn_more_button->SetTooltipText(
         l10n_util::GetStringUTF16(IDS_LEARN_MORE));
@@ -247,14 +254,6 @@
       visible_requests_[1]->GetMessageTextFragment());
 }
 
-void PermissionPromptBubbleView::ButtonPressed(views::Button* sender,
-                                               const ui::Event& event) {
-  DCHECK_EQ(sender, GetExtraView());
-  chrome::AddSelectedTabWithURL(browser_,
-                                GURL(chrome::kFlashDeprecationLearnMoreURL),
-                                ui::PAGE_TRANSITION_LINK);
-}
-
 PermissionPromptBubbleView::DisplayNameOrOrigin
 PermissionPromptBubbleView::GetDisplayNameOrOrigin() const {
   DCHECK(!visible_requests_.empty());
diff --git a/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.h b/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.h
index 62e43c1..0ee2d45f 100644
--- a/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.h
+++ b/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.h
@@ -9,14 +9,12 @@
 #include "base/strings/string16.h"
 #include "components/permissions/permission_prompt.h"
 #include "ui/views/bubble/bubble_dialog_delegate_view.h"
-#include "ui/views/controls/button/button.h"
 
 class Browser;
 
 // Bubble that prompts the user to grant or deny a permission request from a
 // website.
-class PermissionPromptBubbleView : public views::ButtonListener,
-                                   public views::BubbleDialogDelegateView {
+class PermissionPromptBubbleView : public views::BubbleDialogDelegateView {
  public:
   PermissionPromptBubbleView(Browser* browser,
                              permissions::PermissionPrompt::Delegate* delegate,
@@ -35,9 +33,6 @@
   base::string16 GetAccessibleWindowTitle() const override;
   base::string16 GetWindowTitle() const override;
 
-  // Button Listener
-  void ButtonPressed(views::Button* sender, const ui::Event& event) override;
-
   void AcceptPermission();
   void DenyPermission();
   void ClosingPermission();
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view.cc b/chrome/browser/ui/views/profiles/profile_menu_view.cc
index 4f52a2f..3479263 100644
--- a/chrome/browser/ui/views/profiles/profile_menu_view.cc
+++ b/chrome/browser/ui/views/profiles/profile_menu_view.cc
@@ -53,7 +53,6 @@
 #include "components/signin/public/identity_manager/consent_level.h"
 #include "components/signin/public/identity_manager/primary_account_mutator.h"
 #include "components/strings/grit/components_strings.h"
-#include "components/sync/driver/sync_service_utils.h"
 #include "components/vector_icons/vector_icons.h"
 #include "net/base/url_util.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -318,10 +317,6 @@
       chrome::ShowSettingsSubPage(browser(), chrome::kSignOutSubPage);
       break;
     case sync_ui_util::UNRECOVERABLE_ERROR:
-      if (ProfileSyncServiceFactory::GetForProfile(browser()->profile())) {
-        syncer::RecordSyncEvent(syncer::STOP_FROM_OPTIONS);
-      }
-
       // GetPrimaryAccountMutator() might return nullptr on some platforms.
       if (auto* account_mutator =
               IdentityManagerFactory::GetForProfile(browser()->profile())
diff --git a/chrome/browser/ui/views/status_icons/status_icon_button_linux.cc b/chrome/browser/ui/views/status_icons/status_icon_button_linux.cc
index f51aa27..1131101e 100644
--- a/chrome/browser/ui/views/status_icons/status_icon_button_linux.cc
+++ b/chrome/browser/ui/views/status_icons/status_icon_button_linux.cc
@@ -31,7 +31,10 @@
 
 }  // namespace
 
-StatusIconButtonLinux::StatusIconButtonLinux() : Button(this) {}
+StatusIconButtonLinux::StatusIconButtonLinux()
+    : Button(base::BindRepeating(
+          [](StatusIconButtonLinux* button) { button->delegate_->OnClick(); },
+          base::Unretained(this))) {}
 
 StatusIconButtonLinux::~StatusIconButtonLinux() = default;
 
@@ -103,11 +106,6 @@
                           views::MenuAnchorPosition::kTopLeft, source_type);
 }
 
-void StatusIconButtonLinux::ButtonPressed(Button* sender,
-                                          const ui::Event& event) {
-  delegate_->OnClick();
-}
-
 void StatusIconButtonLinux::PaintButtonContents(gfx::Canvas* canvas) {
   gfx::ScopedCanvas scoped_canvas(canvas);
   canvas->UndoDeviceScaleFactor();
@@ -132,4 +130,4 @@
   flags.setFilterQuality(kHigh_SkFilterQuality);
   canvas->DrawImageInt(image, 0, 0, image.width(), image.height(), 0, 0,
                        image.width(), image.height(), true, flags);
-}
\ No newline at end of file
+}
diff --git a/chrome/browser/ui/views/status_icons/status_icon_button_linux.h b/chrome/browser/ui/views/status_icons/status_icon_button_linux.h
index 30e2bdb..e9cf1ce 100644
--- a/chrome/browser/ui/views/status_icons/status_icon_button_linux.h
+++ b/chrome/browser/ui/views/status_icons/status_icon_button_linux.h
@@ -23,8 +23,7 @@
 // OnImplInitializationFailed.
 class StatusIconButtonLinux : public views::StatusIconLinux,
                               public views::Button,
-                              public views::ContextMenuController,
-                              public views::ButtonListener {
+                              public views::ContextMenuController {
  public:
   StatusIconButtonLinux();
   ~StatusIconButtonLinux() override;
@@ -40,9 +39,6 @@
                                   const gfx::Point& point,
                                   ui::MenuSourceType source_type) override;
 
-  // views::ButtonListener:
-  void ButtonPressed(Button* sender, const ui::Event& event) override;
-
   // views::Button:
   void PaintButtonContents(gfx::Canvas* canvas) override;
 
diff --git a/chrome/browser/ui/webui/settings/chromeos/about_section.cc b/chrome/browser/ui/webui/settings/chromeos/about_section.cc
index 8738c88..bb9eb38 100644
--- a/chrome/browser/ui/webui/settings/chromeos/about_section.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/about_section.cc
@@ -219,6 +219,12 @@
     {"aboutChannelDialogDev", IDS_SETTINGS_ABOUT_PAGE_DIALOG_CHANNEL_DEV},
     {"aboutChannelDialogStable", IDS_SETTINGS_ABOUT_PAGE_DIALOG_CHANNEL_STABLE},
 
+    // About page, edit device name dialog.
+    {"aboutEditDeviceName", IDS_SETTINGS_ABOUT_PAGE_EDIT_DEVICE_NAME},
+    {"aboutDeviceNameInfo", IDS_SETTINGS_ABOUT_PAGE_DEVICE_NAME_INFO},
+    {"aboutDeviceNameConstraints",
+     IDS_SETTINGS_ABOUT_PAGE_DEVICE_NAME_CONSTRAINTS},
+
     // About page, update warning dialog.
     {"aboutUpdateWarningMessage",
      IDS_SETTINGS_ABOUT_PAGE_UPDATE_WARNING_MESSAGE},
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.cc b/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.cc
index 0c08f1e..8ab9ea90 100644
--- a/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.cc
@@ -11,7 +11,7 @@
 #include "chrome/browser/ui/webui/settings/chromeos/search/search_handler.h"
 #include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h"
 #include "chrome/browser/ui/webui/settings/chromeos/settings_user_action_tracker.h"
-#include "chromeos/components/local_search_service/local_search_service.h"
+#include "chromeos/components/local_search_service/local_search_service_sync.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "content/public/browser/web_ui_data_source.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -21,7 +21,7 @@
 
 OsSettingsManager::OsSettingsManager(
     Profile* profile,
-    local_search_service::LocalSearchService* local_search_service,
+    local_search_service::LocalSearchServiceSync* local_search_service,
     multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client,
     phonehub::PhoneHubManager* phone_hub_manager,
     syncer::SyncService* sync_service,
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.h b/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.h
index cea0a261..531ac37 100644
--- a/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.h
+++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_manager.h
@@ -37,7 +37,7 @@
 }  // namespace android_sms
 
 namespace local_search_service {
-class LocalSearchService;
+class LocalSearchServiceSync;
 }  // namespace local_search_service
 
 namespace multidevice_setup {
@@ -63,7 +63,8 @@
 // Main responsibilities:
 //
 // (1) Support search queries for settings content. OsSettingsManager is
-//     responsible for updating the kCroSettings index of the LocalSearchService
+//     responsible for updating the kCroSettings index of the
+//     LocalSearchServiceSync
 //     with search tags corresponding to all settings which are available.
 //
 //     The availability of settings depends on the user's account (e.g.,
@@ -85,7 +86,7 @@
  public:
   OsSettingsManager(
       Profile* profile,
-      local_search_service::LocalSearchService* local_search_service,
+      local_search_service::LocalSearchServiceSync* local_search_service,
       multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client,
       phonehub::PhoneHubManager* phone_hub_manager,
       syncer::SyncService* sync_service,
diff --git a/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_factory.cc b/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_factory.cc
index 11ad06e..3c390d1 100644
--- a/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_factory.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/os_settings_manager_factory.cc
@@ -17,7 +17,7 @@
 #include "chrome/browser/sync/profile_sync_service_factory.h"
 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.h"
 #include "chrome/browser/ui/webui/settings/chromeos/os_settings_manager.h"
-#include "chromeos/components/local_search_service/local_search_service_factory.h"
+#include "chromeos/components/local_search_service/local_search_service_sync_factory.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 
 namespace chromeos {
@@ -39,7 +39,7 @@
     : BrowserContextKeyedServiceFactory(
           "OsSettingsManager",
           BrowserContextDependencyManager::GetInstance()) {
-  DependsOn(local_search_service::LocalSearchServiceFactory::GetInstance());
+  DependsOn(local_search_service::LocalSearchServiceSyncFactory::GetInstance());
   DependsOn(multidevice_setup::MultiDeviceSetupClientFactory::GetInstance());
   DependsOn(phonehub::PhoneHubManagerFactory::GetInstance());
   DependsOn(ProfileSyncServiceFactory::GetInstance());
@@ -68,7 +68,7 @@
 
   return new OsSettingsManager(
       profile,
-      local_search_service::LocalSearchServiceFactory::GetForBrowserContext(
+      local_search_service::LocalSearchServiceSyncFactory::GetForBrowserContext(
           context),
       multidevice_setup::MultiDeviceSetupClientFactory::GetForProfile(profile),
       phonehub::PhoneHubManagerFactory::GetForProfile(profile),
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc b/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc
index 1dac5a4..efb3695 100644
--- a/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/search/search_handler.cc
@@ -13,7 +13,7 @@
 #include "chrome/browser/ui/webui/settings/chromeos/search/search_concept.h"
 #include "chrome/browser/ui/webui/settings/chromeos/search/search_result_icon.mojom.h"
 #include "chrome/grit/generated_resources.h"
-#include "chromeos/components/local_search_service/local_search_service.h"
+#include "chromeos/components/local_search_service/local_search_service_sync.h"
 #include "ui/base/l10n/l10n_util.h"
 
 namespace chromeos {
@@ -44,11 +44,11 @@
     SearchTagRegistry* search_tag_registry,
     OsSettingsSections* sections,
     Hierarchy* hierarchy,
-    local_search_service::LocalSearchService* local_search_service)
+    local_search_service::LocalSearchServiceSync* local_search_service)
     : search_tag_registry_(search_tag_registry),
       sections_(sections),
       hierarchy_(hierarchy),
-      index_(local_search_service->GetIndex(
+      index_(local_search_service->GetIndexSync(
           local_search_service::IndexId::kCrosSettings,
           local_search_service::Backend::kLinearMap,
           g_browser_process ? g_browser_process->local_state() : nullptr)) {
@@ -76,11 +76,11 @@
   uint32_t max_local_search_service_results = 5 * max_num_results;
 
   std::vector<local_search_service::Result> local_search_service_results;
-  local_search_service::ResponseStatus response_status = index_->Find(
+  local_search_service::ResponseStatus response_status = index_->FindSync(
       query, max_local_search_service_results, &local_search_service_results);
 
   if (response_status != local_search_service::ResponseStatus::kSuccess) {
-    LOG(ERROR) << "Cannot search; LocalSearchService returned "
+    LOG(ERROR) << "Cannot search; LocalSearchServiceSync returned "
                << static_cast<int>(response_status)
                << ". Returning empty results array.";
     return {};
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/search_handler.h b/chrome/browser/ui/webui/settings/chromeos/search/search_handler.h
index 4f219a5f..95a50eae 100644
--- a/chrome/browser/ui/webui/settings/chromeos/search/search_handler.h
+++ b/chrome/browser/ui/webui/settings/chromeos/search/search_handler.h
@@ -11,7 +11,7 @@
 #include "base/optional.h"
 #include "chrome/browser/ui/webui/settings/chromeos/search/search.mojom.h"
 #include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h"
-#include "chromeos/components/local_search_service/index.h"
+#include "chromeos/components/local_search_service/index_sync.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/receiver_set.h"
@@ -21,7 +21,7 @@
 namespace chromeos {
 
 namespace local_search_service {
-class LocalSearchService;
+class LocalSearchServiceSync;
 }  // namespace local_search_service
 
 namespace settings {
@@ -33,17 +33,18 @@
 // Handles search queries for Chrome OS settings. Search() is expected to be
 // invoked by the settings UI as well as the the Launcher search UI. Search
 // results are obtained by matching the provided query against search tags
-// indexed in the LocalSearchService and cross-referencing results with
+// indexed in the LocalSearchServiceSync and cross-referencing results with
 // SearchTagRegistry.
 //
 // Searches which do not provide any matches result in an empty results array.
 class SearchHandler : public mojom::SearchHandler,
                       public SearchTagRegistry::Observer {
  public:
-  SearchHandler(SearchTagRegistry* search_tag_registry,
-                OsSettingsSections* sections,
-                Hierarchy* hierarchy,
-                local_search_service::LocalSearchService* local_search_service);
+  SearchHandler(
+      SearchTagRegistry* search_tag_registry,
+      OsSettingsSections* sections,
+      Hierarchy* hierarchy,
+      local_search_service::LocalSearchServiceSync* local_search_service);
   ~SearchHandler() override;
 
   SearchHandler(const SearchHandler& other) = delete;
@@ -107,7 +108,7 @@
   SearchTagRegistry* search_tag_registry_;
   OsSettingsSections* sections_;
   Hierarchy* hierarchy_;
-  local_search_service::Index* index_;
+  local_search_service::IndexSync* index_;
 
   // Note: Expected to have multiple clients, so ReceiverSet/RemoteSet are used.
   mojo::ReceiverSet<mojom::SearchHandler> receivers_;
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc b/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc
index ae75a5a..d1bf9da8c 100644
--- a/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/search/search_handler_unittest.cc
@@ -13,7 +13,7 @@
 #include "chrome/browser/ui/webui/settings/chromeos/search/search.mojom-test-utils.h"
 #include "chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h"
 #include "chrome/grit/generated_resources.h"
-#include "chromeos/components/local_search_service/local_search_service.h"
+#include "chromeos/components/local_search_service/local_search_service_sync.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -129,7 +129,7 @@
   }
 
   base::test::TaskEnvironment task_environment_;
-  local_search_service::LocalSearchService local_search_service_;
+  local_search_service::LocalSearchServiceSync local_search_service_;
   SearchTagRegistry search_tag_registry_;
   FakeOsSettingsSections fake_sections_;
   FakeHierarchy fake_hierarchy_;
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.cc b/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.cc
index 035f76f..5f9e94c2 100644
--- a/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.cc
@@ -11,7 +11,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/ui/webui/settings/chromeos/search/search_concept.h"
-#include "chromeos/components/local_search_service/local_search_service.h"
+#include "chromeos/components/local_search_service/local_search_service_sync.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -53,7 +53,7 @@
     bool is_pending_add = map_entry.second.second;
 
     // If tag metadata is present for this tag, it has already been added and is
-    // present in LocalSearchService.
+    // present in LocalSearchServiceSync.
     bool is_concept_already_added =
         registry_->GetTagMetadata(result_id) != nullptr;
 
@@ -99,8 +99,8 @@
 }
 
 SearchTagRegistry::SearchTagRegistry(
-    local_search_service::LocalSearchService* local_search_service)
-    : index_(local_search_service->GetIndex(
+    local_search_service::LocalSearchServiceSync* local_search_service)
+    : index_(local_search_service->GetIndexSync(
           local_search_service::IndexId::kCrosSettings,
           local_search_service::Backend::kLinearMap,
           g_browser_process ? g_browser_process->local_state() : nullptr)) {}
@@ -121,7 +121,7 @@
 
 void SearchTagRegistry::AddSearchTags(
     const std::vector<const SearchConcept*>& search_tags) {
-  index_->AddOrUpdate(ConceptVectorToDataVector(search_tags));
+  index_->AddOrUpdateSync(ConceptVectorToDataVector(search_tags));
 
   // Add each concept to the map. Note that it is safe to take the address of
   // each concept because all concepts are allocated via static
@@ -141,7 +141,7 @@
     data_ids.push_back(std::move(result_id));
   }
 
-  index_->Delete(data_ids);
+  index_->DeleteSync(data_ids);
 
   NotifyRegistryUpdated();
 }
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h b/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h
index 1524800..645575e 100644
--- a/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h
+++ b/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry.h
@@ -13,13 +13,13 @@
 #include "base/observer_list.h"
 #include "base/observer_list_types.h"
 #include "chrome/browser/ui/webui/settings/chromeos/os_settings_section.h"
-#include "chromeos/components/local_search_service/index.h"
+#include "chromeos/components/local_search_service/index_sync.h"
 
 namespace chromeos {
 
 namespace local_search_service {
-class Index;
-class LocalSearchService;
+class IndexSync;
+class LocalSearchServiceSync;
 }  // namespace local_search_service
 
 namespace settings {
@@ -27,7 +27,7 @@
 struct SearchConcept;
 
 // Processes all registered search tags by adding/removing them from
-// LocalSearchService and providing metadata via GetTagMetadata().
+// LocalSearchServiceSync and providing metadata via GetTagMetadata().
 class SearchTagRegistry {
  public:
   class Observer : public base::CheckedObserver {
@@ -64,7 +64,7 @@
   };
 
   SearchTagRegistry(
-      local_search_service::LocalSearchService* local_search_service);
+      local_search_service::LocalSearchServiceSync* local_search_service);
   SearchTagRegistry(const SearchTagRegistry& other) = delete;
   SearchTagRegistry& operator=(const SearchTagRegistry& other) = delete;
   virtual ~SearchTagRegistry();
@@ -79,8 +79,8 @@
   ScopedTagUpdater StartUpdate();
 
   // Returns the tag metadata associated with |result_id|, which is the ID
-  // returned by the LocalSearchService. If no metadata is available, null is
-  // returned.
+  // returned by the LocalSearchServiceSync. If no metadata is available, null
+  // is returned.
   const SearchConcept* GetTagMetadata(const std::string& result_id) const;
  private:
   FRIEND_TEST_ALL_PREFIXES(SearchTagRegistryTest, AddAndRemove);
@@ -94,11 +94,11 @@
       const std::vector<const SearchConcept*>& search_tags);
   void NotifyRegistryUpdated();
 
-  // Index used by the LocalSearchService for string matching.
-  local_search_service::Index* index_;
+  // Index used by the LocalSearchServiceSync for string matching.
+  local_search_service::IndexSync* index_;
 
   // In-memory cache of all results which have been added to the
-  // LocalSearchService. Contents are kept in sync with |index_|.
+  // LocalSearchServiceSync. Contents are kept in sync with |index_|.
   std::unordered_map<std::string, const SearchConcept*>
       result_id_to_metadata_list_map_;
 
diff --git a/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry_unittest.cc b/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry_unittest.cc
index 67ab6f4..7b68386 100644
--- a/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry_unittest.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/search/search_tag_registry_unittest.cc
@@ -9,8 +9,8 @@
 #include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h"
 #include "chrome/browser/ui/webui/settings/chromeos/search/search_concept.h"
 #include "chrome/grit/generated_resources.h"
-#include "chromeos/components/local_search_service/index.h"
-#include "chromeos/components/local_search_service/local_search_service.h"
+#include "chromeos/components/local_search_service/index_sync.h"
+#include "chromeos/components/local_search_service/local_search_service_sync.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace chromeos {
@@ -69,17 +69,17 @@
   // testing::Test:
   void SetUp() override {
     search_tag_registry_.AddObserver(&observer_);
-    index_ = local_search_service_.GetIndex(
+    index_ = local_search_service_.GetIndexSync(
         local_search_service::IndexId::kCrosSettings,
         local_search_service::Backend::kLinearMap, nullptr /* local_state */);
   }
 
   void TearDown() override { search_tag_registry_.RemoveObserver(&observer_); }
 
-  local_search_service::LocalSearchService local_search_service_;
+  local_search_service::LocalSearchServiceSync local_search_service_;
   SearchTagRegistry search_tag_registry_;
   FakeObserver observer_;
-  local_search_service::Index* index_;
+  local_search_service::IndexSync* index_;
 };
 
 TEST_F(SearchTagRegistryTest, AddAndRemove) {
@@ -91,11 +91,11 @@
 
     // Nothing should have happened yet, since |updater| has not gone out of
     // scope.
-    EXPECT_EQ(0u, index_->GetSize());
+    EXPECT_EQ(0u, index_->GetSizeSync());
     EXPECT_EQ(0u, observer_.num_calls());
   }
   // Now that it went out of scope, the update should have occurred.
-  EXPECT_EQ(3u, index_->GetSize());
+  EXPECT_EQ(3u, index_->GetSizeSync());
   EXPECT_EQ(1u, observer_.num_calls());
 
   std::string first_tag_id =
@@ -115,11 +115,11 @@
 
     // Tags should not have been removed yet, since |updater| has not gone out
     // of scope.
-    EXPECT_EQ(3u, index_->GetSize());
+    EXPECT_EQ(3u, index_->GetSizeSync());
     EXPECT_EQ(1u, observer_.num_calls());
   }
   // Now that it went out of scope, the update should have occurred.
-  EXPECT_EQ(0u, index_->GetSize());
+  EXPECT_EQ(0u, index_->GetSizeSync());
   EXPECT_EQ(2u, observer_.num_calls());
 
   // The tag should no longer be accessible via GetTagMetadata().
diff --git a/chrome/browser/ui/webui/settings/people_handler.cc b/chrome/browser/ui/webui/settings/people_handler.cc
index 702dce6..753c611 100644
--- a/chrome/browser/ui/webui/settings/people_handler.cc
+++ b/chrome/browser/ui/webui/settings/people_handler.cc
@@ -49,7 +49,6 @@
 #include "components/strings/grit/components_strings.h"
 #include "components/sync/base/passphrase_enums.h"
 #include "components/sync/base/user_selectable_type.h"
-#include "components/sync/driver/sync_service_utils.h"
 #include "components/sync/driver/sync_user_settings.h"
 #include "components/unified_consent/unified_consent_metrics.h"
 #include "content/public/browser/render_view_host.h"
@@ -665,9 +664,6 @@
   DCHECK(identity_manager->HasPrimaryAccount(ConsentLevel::kSync));
   DCHECK(signin_util::IsUserSignoutAllowedForProfile(profile_));
 
-  if (GetSyncService())
-    syncer::RecordSyncEvent(syncer::STOP_FROM_OPTIONS);
-
   identity_manager->GetPrimaryAccountMutator()->RevokeSyncConsent();
 }
 #endif  // defined(OS_CHROMEOS)
@@ -695,8 +691,6 @@
   } else {
     auto* identity_manager = IdentityManagerFactory::GetForProfile(profile_);
     if (identity_manager->HasPrimaryAccount()) {
-      if (GetSyncService())
-        syncer::RecordSyncEvent(syncer::STOP_FROM_OPTIONS);
 
       signin_metrics::SignoutDelete delete_metric =
           delete_profile ? signin_metrics::SignoutDelete::DELETED
@@ -784,8 +778,6 @@
           sync_service->GetAuthError().state() ==
               GoogleServiceAuthError::NONE))) {
       if (configuring_sync_) {
-        syncer::RecordSyncEvent(syncer::CANCEL_DURING_CONFIGURE);
-
         // If the user clicked "Cancel" while setting up sync, disable sync
         // because we don't want the sync engine to remain in the
         // first-setup-incomplete state.
diff --git a/chrome/browser/video_tutorials/BUILD.gn b/chrome/browser/video_tutorials/BUILD.gn
index ec119a4f9..91f5faa 100644
--- a/chrome/browser/video_tutorials/BUILD.gn
+++ b/chrome/browser/video_tutorials/BUILD.gn
@@ -61,6 +61,7 @@
   android_library("java") {
     sources = [
       "android/java/src/org/chromium/chrome/browser/video_tutorials/Language.java",
+      "android/java/src/org/chromium/chrome/browser/video_tutorials/LanguageInfoProvider.java",
       "android/java/src/org/chromium/chrome/browser/video_tutorials/Tutorial.java",
       "android/java/src/org/chromium/chrome/browser/video_tutorials/VideoTutorialService.java",
       "android/java/src/org/chromium/chrome/browser/video_tutorials/iph/VideoIPHCoordinator.java",
diff --git a/chrome/browser/video_tutorials/android/java/src/org/chromium/chrome/browser/video_tutorials/LanguageInfoProvider.java b/chrome/browser/video_tutorials/android/java/src/org/chromium/chrome/browser/video_tutorials/LanguageInfoProvider.java
new file mode 100644
index 0000000..bff553a
--- /dev/null
+++ b/chrome/browser/video_tutorials/android/java/src/org/chromium/chrome/browser/video_tutorials/LanguageInfoProvider.java
@@ -0,0 +1,16 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.video_tutorials;
+
+/**
+ * Interface for obtaining the language information for a given locale in order to display on the
+ * UI.
+ */
+public interface LanguageInfoProvider {
+    /**
+x     * @return The language info for a given {@code locale}.
+     */
+    Language getLanguageInfo(String locale);
+}
diff --git a/chrome/browser/video_tutorials/android/java/src/org/chromium/chrome/browser/video_tutorials/VideoTutorialService.java b/chrome/browser/video_tutorials/android/java/src/org/chromium/chrome/browser/video_tutorials/VideoTutorialService.java
index 4b1ba82..c781706 100644
--- a/chrome/browser/video_tutorials/android/java/src/org/chromium/chrome/browser/video_tutorials/VideoTutorialService.java
+++ b/chrome/browser/video_tutorials/android/java/src/org/chromium/chrome/browser/video_tutorials/VideoTutorialService.java
@@ -26,7 +26,7 @@
     /**
      * Called to get the list of supported languages.
      */
-    List<Language> getSupportedLanguages();
+    List<String> getSupportedLanguages();
 
     /**
      * @return The user's language of choice for watching the video tutorials.
diff --git a/chrome/browser/video_tutorials/android/java/src/org/chromium/chrome/browser/video_tutorials/test/TestVideoTutorialService.java b/chrome/browser/video_tutorials/android/java/src/org/chromium/chrome/browser/video_tutorials/test/TestVideoTutorialService.java
index 82599bd..4d999fd 100644
--- a/chrome/browser/video_tutorials/android/java/src/org/chromium/chrome/browser/video_tutorials/test/TestVideoTutorialService.java
+++ b/chrome/browser/video_tutorials/android/java/src/org/chromium/chrome/browser/video_tutorials/test/TestVideoTutorialService.java
@@ -15,12 +15,12 @@
 
 /** A video tutorial service implementation for tests. */
 public class TestVideoTutorialService implements VideoTutorialService {
-    public static final Language HINDI = new Language("hi", "Hindi", "Hindi Native");
-    public static final Language TAMIL = new Language("ta", "Tamil", "Tamil Native");
-    public static final Language ENGLISH = new Language("en", "English", "English Native");
+    public static final Language HINDI = new Language("hi", "hindi", "हिंदी");
+    public static final Language TAMIL = new Language("ta", "Tamil", "தமிழ்");
+    public static final Language ENGLISH = new Language("en", "English", "English");
 
     private final List<Tutorial> mTutorials = new ArrayList<>();
-    private final List<Language> mLanguages = new ArrayList<>();
+    private final List<String> mLanguages = new ArrayList<>();
     private String mPreferredLocale;
 
     public TestVideoTutorialService() {
@@ -42,7 +42,7 @@
     }
 
     @Override
-    public List<Language> getSupportedLanguages() {
+    public List<String> getSupportedLanguages() {
         return mLanguages;
     }
 
@@ -56,7 +56,7 @@
         mPreferredLocale = locale;
     }
 
-    public List<Language> getTestLanguages() {
+    public List<String> getTestLanguages() {
         return mLanguages;
     }
 
@@ -84,8 +84,8 @@
     }
 
     private void initializeLanguages() {
-        mLanguages.add(HINDI);
-        mLanguages.add(TAMIL);
-        mLanguages.add(ENGLISH);
+        mLanguages.add("hi");
+        mLanguages.add("ta");
+        mLanguages.add("en");
     }
 }
diff --git a/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/VideoTutorialServiceFactory.java b/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/VideoTutorialServiceFactory.java
index 14bff1d..bf13635 100644
--- a/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/VideoTutorialServiceFactory.java
+++ b/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/VideoTutorialServiceFactory.java
@@ -54,9 +54,10 @@
     public static VideoPlayerCoordinator createVideoPlayerCoordinator(Context context,
             VideoTutorialService videoTutorialService,
             Supplier<Pair<WebContents, ContentView>> webContentsFactory,
-            Callback<Tutorial> tryNowCallback, Runnable closeCallback) {
-        return new VideoPlayerCoordinatorImpl(
-                context, videoTutorialService, webContentsFactory, tryNowCallback, closeCallback);
+            LanguageInfoProvider languageInfoProvider, Callback<Tutorial> tryNowCallback,
+            Runnable closeCallback) {
+        return new VideoPlayerCoordinatorImpl(context, videoTutorialService, webContentsFactory,
+                languageInfoProvider, tryNowCallback, closeCallback);
     }
 
     /** See {@link TutorialListCoordinator}.*/
diff --git a/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/bridges/VideoTutorialServiceBridge.java b/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/bridges/VideoTutorialServiceBridge.java
index 56c09c9..8a476bd5 100644
--- a/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/bridges/VideoTutorialServiceBridge.java
+++ b/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/bridges/VideoTutorialServiceBridge.java
@@ -46,10 +46,12 @@
     }
 
     @Override
-    public List<Language> getSupportedLanguages() {
-        if (mNativeVideoTutorialServiceBridge == 0) return null;
-        return VideoTutorialServiceBridgeJni.get().getSupportedLanguages(
-                mNativeVideoTutorialServiceBridge, this);
+    public List<String> getSupportedLanguages() {
+        return null;
+        // TODO(shaktisahu): Fix the native to return a list of locales instead of languages.
+        // if (mNativeVideoTutorialServiceBridge == 0) return null;
+        // return VideoTutorialServiceBridgeJni.get().getSupportedLanguages(
+        //         mNativeVideoTutorialServiceBridge, this);
     }
 
     @Override
diff --git a/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/languages/LanguagePickerCoordinator.java b/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/languages/LanguagePickerCoordinator.java
index e8f0bd6..5f2aad2f 100644
--- a/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/languages/LanguagePickerCoordinator.java
+++ b/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/languages/LanguagePickerCoordinator.java
@@ -7,6 +7,7 @@
 import android.content.Context;
 import android.view.View;
 
+import org.chromium.chrome.browser.video_tutorials.LanguageInfoProvider;
 import org.chromium.chrome.browser.video_tutorials.VideoTutorialService;
 import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
 import org.chromium.ui.modelutil.PropertyModel;
@@ -27,13 +28,15 @@
      * @param view The view representing this language picker.
      * @param videoTutorialService The video tutorial service backend.
      */
-    public LanguagePickerCoordinator(View view, VideoTutorialService videoTutorialService) {
+    public LanguagePickerCoordinator(View view, VideoTutorialService videoTutorialService,
+            LanguageInfoProvider languageInfoProvider) {
         mContext = view.getContext();
         mVideoTutorialService = videoTutorialService;
         mModel = new PropertyModel(LanguagePickerProperties.ALL_KEYS);
         mListModel = new ModelList();
         mView = new LanguagePickerView(view, mModel, mListModel);
-        mMediator = new LanguagePickerMediator(mContext, mModel, mListModel, videoTutorialService);
+        mMediator = new LanguagePickerMediator(
+                mContext, mModel, mListModel, videoTutorialService, languageInfoProvider);
     }
 
     /**
diff --git a/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/languages/LanguagePickerMediator.java b/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/languages/LanguagePickerMediator.java
index f49cbc6..34a55c38 100644
--- a/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/languages/LanguagePickerMediator.java
+++ b/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/languages/LanguagePickerMediator.java
@@ -8,6 +8,7 @@
 import android.text.TextUtils;
 
 import org.chromium.chrome.browser.video_tutorials.Language;
+import org.chromium.chrome.browser.video_tutorials.LanguageInfoProvider;
 import org.chromium.chrome.browser.video_tutorials.VideoTutorialService;
 import org.chromium.ui.modelutil.MVCListAdapter.ListItem;
 import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
@@ -22,6 +23,7 @@
 public class LanguagePickerMediator {
     private final Context mContext;
     private final VideoTutorialService mVideoTutorialService;
+    private final LanguageInfoProvider mLanguageInfoProvider;
     private final PropertyModel mModel;
     private final ModelList mListModel;
 
@@ -30,9 +32,10 @@
      * @param videoTutorialService The video tutorial service backend.
      */
     public LanguagePickerMediator(Context context, PropertyModel model, ModelList listModel,
-            VideoTutorialService videoTutorialService) {
+            VideoTutorialService videoTutorialService, LanguageInfoProvider languageInfoProvider) {
         mContext = context;
         mVideoTutorialService = videoTutorialService;
+        mLanguageInfoProvider = languageInfoProvider;
         mModel = model;
         mListModel = listModel;
     }
@@ -51,11 +54,14 @@
         populateList(mVideoTutorialService.getSupportedLanguages());
     }
 
-    private void populateList(List<Language> supportedLanguages) {
+    private void populateList(List<String> supportedLanguages) {
         List<ListItem> listItems = new ArrayList<>();
-        for (Language locale : supportedLanguages) {
+        for (String locale : supportedLanguages) {
+            Language language = mLanguageInfoProvider.getLanguageInfo(locale);
+            if (language == null) continue;
+
             ListItem listItem = new ListItem(
-                    LanguageItemProperties.ITEM_VIEW_TYPE, buildListItemModelFromLocale(locale));
+                    LanguageItemProperties.ITEM_VIEW_TYPE, buildListItemModelFromLocale(language));
             listItems.add(listItem);
         }
         mListModel.set(listItems);
diff --git a/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/languages/LanguagePickerMediatorUnitTest.java b/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/languages/LanguagePickerMediatorUnitTest.java
index 6774346..d130a775 100644
--- a/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/languages/LanguagePickerMediatorUnitTest.java
+++ b/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/languages/LanguagePickerMediatorUnitTest.java
@@ -14,10 +14,12 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
 import org.chromium.base.metrics.test.ShadowRecordHistogram;
 import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.chrome.browser.video_tutorials.LanguageInfoProvider;
 import org.chromium.chrome.browser.video_tutorials.test.TestVideoTutorialService;
 import org.chromium.ui.modelutil.MVCListAdapter.ListItem;
 import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
@@ -37,7 +39,9 @@
     private ModelList mListModel;
     private LanguagePickerMediator mMediator;
     @Mock
-    PropertyObservable.PropertyObserver<PropertyKey> mPropertyObserver;
+    private PropertyObservable.PropertyObserver<PropertyKey> mPropertyObserver;
+    @Mock
+    private LanguageInfoProvider mLanguageProvider;
 
     @Before
     public void setUp() {
@@ -49,8 +53,8 @@
 
         mListModel = new ModelList();
         mTestVideoTutorialService = new TestVideoTutorialService();
-        mMediator =
-                new LanguagePickerMediator(mContext, mModel, mListModel, mTestVideoTutorialService);
+        mMediator = new LanguagePickerMediator(
+                mContext, mModel, mListModel, mTestVideoTutorialService, mLanguageProvider);
     }
 
     @Test
@@ -64,6 +68,13 @@
 
     @Test
     public void loadsLanguagesInTheList() {
+        Mockito.when(mLanguageProvider.getLanguageInfo("hi"))
+                .thenReturn(TestVideoTutorialService.HINDI);
+        Mockito.when(mLanguageProvider.getLanguageInfo("ta"))
+                .thenReturn(TestVideoTutorialService.TAMIL);
+        Mockito.when(mLanguageProvider.getLanguageInfo("en"))
+                .thenReturn(TestVideoTutorialService.ENGLISH);
+
         mMediator.showLanguagePicker(() -> {}, () -> {});
 
         assertThat(mListModel.size(), equalTo(mTestVideoTutorialService.getTestLanguages().size()));
diff --git a/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/languages/LanguagePickerTest.java b/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/languages/LanguagePickerTest.java
index 3c84b508..f588579 100644
--- a/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/languages/LanguagePickerTest.java
+++ b/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/languages/LanguagePickerTest.java
@@ -26,6 +26,7 @@
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
+import org.chromium.chrome.browser.video_tutorials.LanguageInfoProvider;
 import org.chromium.chrome.browser.video_tutorials.R;
 import org.chromium.chrome.browser.video_tutorials.VideoTutorialService;
 import org.chromium.chrome.browser.video_tutorials.test.TestVideoTutorialService;
@@ -46,6 +47,8 @@
     private View mContentView;
     private VideoTutorialService mVideoTutorialService;
     private LanguagePickerCoordinator mCoordinator;
+    @Mock
+    private LanguageInfoProvider mLanguageProvider;
 
     @Mock
     private Runnable mWatchCallback;
@@ -63,7 +66,10 @@
             mContentView =
                     LayoutInflater.from(mActivity).inflate(R.layout.language_picker, null, false);
             parentView.addView(mContentView);
-            mCoordinator = new LanguagePickerCoordinator(mContentView, mVideoTutorialService);
+            Mockito.when(mLanguageProvider.getLanguageInfo("hi"))
+                    .thenReturn(TestVideoTutorialService.HINDI);
+            mCoordinator = new LanguagePickerCoordinator(
+                    mContentView, mVideoTutorialService, mLanguageProvider);
             mCoordinator.showLanguagePicker(mWatchCallback, mCloseCallback);
         });
     }
diff --git a/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/player/VideoPlayerCoordinatorImpl.java b/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/player/VideoPlayerCoordinatorImpl.java
index 29d0414f..7a99b786 100644
--- a/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/player/VideoPlayerCoordinatorImpl.java
+++ b/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/player/VideoPlayerCoordinatorImpl.java
@@ -10,6 +10,7 @@
 
 import org.chromium.base.Callback;
 import org.chromium.base.supplier.Supplier;
+import org.chromium.chrome.browser.video_tutorials.LanguageInfoProvider;
 import org.chromium.chrome.browser.video_tutorials.PlaybackStateObserver;
 import org.chromium.chrome.browser.video_tutorials.R;
 import org.chromium.chrome.browser.video_tutorials.Tutorial;
@@ -48,17 +49,19 @@
      */
     public VideoPlayerCoordinatorImpl(Context context, VideoTutorialService videoTutorialService,
             Supplier<Pair<WebContents, ContentView>> webContentsFactory,
-            Callback<Tutorial> tryNowCallback, Runnable closeCallback) {
+            LanguageInfoProvider languageInfoProvider, Callback<Tutorial> tryNowCallback,
+            Runnable closeCallback) {
         mContext = context;
         mVideoTutorialService = videoTutorialService;
         mModel = new PropertyModel(VideoPlayerProperties.ALL_KEYS);
 
         ThinWebView thinWebView = createThinWebView(webContentsFactory);
         mView = new VideoPlayerView(context, mModel, thinWebView);
-        mLanguagePicker = new LanguagePickerCoordinator(
-                mView.getView().findViewById(R.id.language_picker), mVideoTutorialService);
+        mLanguagePicker =
+                new LanguagePickerCoordinator(mView.getView().findViewById(R.id.language_picker),
+                        mVideoTutorialService, languageInfoProvider);
         mMediator = new VideoPlayerMediator(mContext, mModel, videoTutorialService, mLanguagePicker,
-                mWebContents, tryNowCallback, closeCallback);
+                languageInfoProvider, mWebContents, tryNowCallback, closeCallback);
         PropertyModelChangeProcessor.create(mModel, mView, new VideoPlayerViewBinder());
     }
 
diff --git a/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/player/VideoPlayerMediator.java b/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/player/VideoPlayerMediator.java
index 47e700b2..ec2cf99 100644
--- a/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/player/VideoPlayerMediator.java
+++ b/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/player/VideoPlayerMediator.java
@@ -5,10 +5,10 @@
 package org.chromium.chrome.browser.video_tutorials.player;
 
 import android.content.Context;
-import android.text.TextUtils;
 
 import org.chromium.base.Callback;
 import org.chromium.chrome.browser.video_tutorials.Language;
+import org.chromium.chrome.browser.video_tutorials.LanguageInfoProvider;
 import org.chromium.chrome.browser.video_tutorials.PlaybackStateObserver;
 import org.chromium.chrome.browser.video_tutorials.R;
 import org.chromium.chrome.browser.video_tutorials.Tutorial;
@@ -35,16 +35,19 @@
     private Tutorial mTutorial;
     private final Callback<Tutorial> mTryNowCallback;
     private final Runnable mCloseCallback;
+    private final LanguageInfoProvider mLanguageInfoProvider;
     private long mVideoStartTime;
 
     /** Constructor. */
     public VideoPlayerMediator(Context context, PropertyModel model,
             VideoTutorialService videoTutorialService, LanguagePickerCoordinator languagePicker,
-            WebContents webContents, Callback<Tutorial> tryNowCallback, Runnable closeCallback) {
+            LanguageInfoProvider languageInfoProvider, WebContents webContents,
+            Callback<Tutorial> tryNowCallback, Runnable closeCallback) {
         mContext = context;
         mModel = model;
         mVideoTutorialService = videoTutorialService;
         mLanguagePicker = languagePicker;
+        mLanguageInfoProvider = languageInfoProvider;
         mWebContents = webContents;
         mTryNowCallback = tryNowCallback;
         mCloseCallback = closeCallback;
@@ -129,14 +132,13 @@
     }
 
     private void updateChangeLanguageButtonText() {
-        String locale = mVideoTutorialService.getPreferredLocale();
-        for (Language language : mVideoTutorialService.getSupportedLanguages()) {
-            if (TextUtils.equals(language.locale, locale)) {
-                String buttonText = mContext.getResources().getString(
-                        R.string.video_tutorials_change_language, language.nativeName);
-                mModel.set(VideoPlayerProperties.CHANGE_LANGUAGE_BUTTON_TEXT, buttonText);
-            }
-        }
+        String preferredLocale = mVideoTutorialService.getPreferredLocale();
+        Language language = mLanguageInfoProvider.getLanguageInfo(preferredLocale);
+        if (language == null) return;
+
+        String buttonText = mContext.getResources().getString(
+                R.string.video_tutorials_change_language, language.nativeName);
+        mModel.set(VideoPlayerProperties.CHANGE_LANGUAGE_BUTTON_TEXT, buttonText);
     }
 
     private void onLanguageSelected() {
diff --git a/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/player/VideoPlayerMediatorUnitTest.java b/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/player/VideoPlayerMediatorUnitTest.java
index 8b77854..9d5ea7e 100644
--- a/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/player/VideoPlayerMediatorUnitTest.java
+++ b/chrome/browser/video_tutorials/internal/android/java/src/org/chromium/chrome/browser/video_tutorials/player/VideoPlayerMediatorUnitTest.java
@@ -23,6 +23,7 @@
 import org.chromium.base.Callback;
 import org.chromium.base.metrics.test.ShadowRecordHistogram;
 import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.chrome.browser.video_tutorials.LanguageInfoProvider;
 import org.chromium.chrome.browser.video_tutorials.Tutorial;
 import org.chromium.chrome.browser.video_tutorials.VideoTutorialUtils;
 import org.chromium.chrome.browser.video_tutorials.languages.LanguagePickerCoordinator;
@@ -60,6 +61,8 @@
     PropertyObservable.PropertyObserver<PropertyKey> mPropertyObserver;
     @Mock
     Callback<Tutorial> mTryNowCallback;
+    @Mock
+    private LanguageInfoProvider mLanguageProvider;
 
     @Before
     public void setUp() {
@@ -73,7 +76,7 @@
 
         mTestVideoTutorialService = new TestVideoTutorialService();
         mMediator = new VideoPlayerMediator(mContext, mModel, mTestVideoTutorialService,
-                mLanguagePicker, mWebContents, mTryNowCallback, mCloseCallback);
+                mLanguagePicker, mLanguageProvider, mWebContents, mTryNowCallback, mCloseCallback);
     }
 
     @Test
@@ -91,7 +94,7 @@
 
     @Test
     public void languagePickerNotShownIfPreferredLocaleSetAlready() {
-        mTestVideoTutorialService.setPreferredLocale(TestVideoTutorialService.ENGLISH.locale);
+        mTestVideoTutorialService.setPreferredLocale("en");
         Tutorial tutorial = mTestVideoTutorialService.getTestTutorials().get(0);
         mMediator.playVideoTutorial(tutorial);
 
diff --git a/chrome/browser/web_applications/system_web_app_manager_browsertest.h b/chrome/browser/web_applications/system_web_app_manager_browsertest.h
index 4566248..acb8ae8 100644
--- a/chrome/browser/web_applications/system_web_app_manager_browsertest.h
+++ b/chrome/browser/web_applications/system_web_app_manager_browsertest.h
@@ -7,7 +7,6 @@
 
 #include <memory>
 
-#include "base/test/scoped_feature_list.h"
 #include "chrome/browser/web_applications/test/profile_test_helper.h"
 #include "chrome/browser/web_applications/test/test_system_web_app_installation.h"
 #include "chrome/browser/web_applications/test/test_web_app_provider.h"
diff --git a/chrome/browser/web_applications/system_web_app_manager_unittest.cc b/chrome/browser/web_applications/system_web_app_manager_unittest.cc
index d8d063e..3c3b7e7 100644
--- a/chrome/browser/web_applications/system_web_app_manager_unittest.cc
+++ b/chrome/browser/web_applications/system_web_app_manager_unittest.cc
@@ -37,6 +37,7 @@
 #include "chrome/browser/web_applications/web_app.h"
 #include "chrome/browser/web_applications/web_app_icon_manager.h"
 #include "chrome/browser/web_applications/web_app_install_finalizer.h"
+#include "chrome/browser/web_applications/web_app_install_manager.h"
 #include "chrome/browser/web_applications/web_app_sync_bridge.h"
 #include "chrome/common/chrome_features.h"
 #include "content/public/test/test_utils.h"
diff --git a/chrome/browser/web_applications/test/web_app_test.h b/chrome/browser/web_applications/test/web_app_test.h
index 01d9ca8..32626d0 100644
--- a/chrome/browser/web_applications/test/web_app_test.h
+++ b/chrome/browser/web_applications/test/web_app_test.h
@@ -7,10 +7,9 @@
 
 #include <memory>
 
+#include "chrome/browser/web_applications/components/install_manager.h"
 #include "chrome/browser/web_applications/components/web_app_install_utils.h"
-#include "chrome/browser/web_applications/web_app_install_manager.h"
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
-#include "testing/gtest/include/gtest/gtest.h"
 
 struct WebApplicationInfo;
 
diff --git a/chrome/browser/web_applications/web_app_migration_user_display_mode_clean_up.h b/chrome/browser/web_applications/web_app_migration_user_display_mode_clean_up.h
index 569b6fa..dd19faaa 100644
--- a/chrome/browser/web_applications/web_app_migration_user_display_mode_clean_up.h
+++ b/chrome/browser/web_applications/web_app_migration_user_display_mode_clean_up.h
@@ -51,7 +51,7 @@
 // user_display_mode for their web apps to kBrowser after migration. This clean
 // up CL will erroneously undo such a change. To mitigate this we only run the
 // clean up once per migrated device.
-class WebAppMigrationUserDisplayModeCleanUp
+class WebAppMigrationUserDisplayModeCleanUp final
     : public syncer::SyncServiceObserver {
  public:
   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index cfbd4c7..e1a8f3a 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-master-1602698313-2c5e1ad3bbb75ee9feac0a345669fda97d41b13c.profdata
+chrome-linux-master-1602719900-429a2df71c95e6dc087ec01302b187e7e9fb6918.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 63dea5e..ec7d8ad2 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-master-1602698313-cdff293844f2ff9d3e5ecfb456ef681f49f814ed.profdata
+chrome-mac-master-1602719900-0adf1708ffdf07a3257db3881b100b59132f390a.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 1b355e9..168dcf8 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-master-1602633476-69602bad93ac5850796e454db1a842456d0dd6b1.profdata
+chrome-win32-master-1602676072-6b1951d9f0e9d329ad053bceb12040099bb1e856.profdata
diff --git a/chrome/test/data/webui/settings/chromeos/ambient_mode_page_test.js b/chrome/test/data/webui/settings/chromeos/ambient_mode_page_test.js
index 34cb64a..7a25931 100644
--- a/chrome/test/data/webui/settings/chromeos/ambient_mode_page_test.js
+++ b/chrome/test/data/webui/settings/chromeos/ambient_mode_page_test.js
@@ -83,7 +83,7 @@
     settings.Router.getInstance().resetRouteForTesting();
   });
 
-  test('toggleAmbientMode', function() {
+  test('toggleAmbientMode', () => {
     const button = ambientModePage.$$('#ambientModeEnable');
     assertTrue(!!button);
     assertFalse(button.disabled);
@@ -110,12 +110,77 @@
     assertEquals(enabled, enabled_toggled_twice);
   });
 
+  test('hasNoTopicSourceItemsWhenLoading', () => {
+    const spinner = ambientModePage.$$('paper-spinner-lite');
+    assertTrue(!!spinner);
+    assertTrue(spinner.active);
+    assertFalse(spinner.hidden);
+
+    const topicSourceListDiv = ambientModePage.$$('#topicSourceListDiv');
+    assertFalse(!!topicSourceListDiv);
+  });
+
+  test('hasTopicSourceItemsAfterLoad', function() {
+    const spinner = ambientModePage.$$('paper-spinner-lite');
+    assertTrue(!!spinner);
+    assertTrue(spinner.active);
+    assertFalse(spinner.hidden);
+
+    const topicSourceListDiv = ambientModePage.$$('#topicSourceListDiv');
+    assertFalse(!!topicSourceListDiv);
+
+    // Select the google photos topic source.
+    cr.webUIListenerCallback('topic-source-changed', {
+      'topicSource': AmbientModeTopicSource.GOOGLE_PHOTOS,
+      'hasAlbums': true
+    });
+    // Select celsius as the initial temperature unit.
+    cr.webUIListenerCallback(
+        'temperature-unit-changed', AmbientModeTemperatureUnit.CELSIUS);
+    Polymer.dom.flush();
+
+    // Spinner is not active and not visible.
+    assertFalse(spinner.active);
+    assertTrue(spinner.hidden);
+
+    const topicSourceList = ambientModePage.$$('topic-source-list');
+    const ironList = topicSourceList.$$('iron-list');
+    const topicSourceItems = ironList.querySelectorAll('topic-source-item');
+
+    // Only have two topics source items: GOOGLE_PHOTOS and ART_GALLERY.
+    assertEquals(2, topicSourceItems.length);
+  });
+
+  test('topicSourceItemHasCorrectRowHeight', function() {
+    // Select the google photos topic source.
+    cr.webUIListenerCallback('topic-source-changed', {
+      'topicSource': AmbientModeTopicSource.GOOGLE_PHOTOS,
+      'hasAlbums': true
+    });
+    // Select celsius as the initial temperature unit.
+    cr.webUIListenerCallback(
+        'temperature-unit-changed', AmbientModeTemperatureUnit.CELSIUS);
+    Polymer.dom.flush();
+
+    const topicSourceList = ambientModePage.$$('topic-source-list');
+    const ironList = topicSourceList.$$('iron-list');
+    const topicSourceItems = ironList.querySelectorAll('topic-source-item');
+
+    topicSourceItems.forEach((row) => {
+      assertEquals(64, row.offsetHeight);
+    });
+  });
+
   test('doubleClickTopicSource', () => {
     // Select the google photos topic source.
     cr.webUIListenerCallback('topic-source-changed', {
       'topicSource': AmbientModeTopicSource.GOOGLE_PHOTOS,
       'hasAlbums': true
     });
+    // Select celsius as the initial temperature unit.
+    cr.webUIListenerCallback(
+        'temperature-unit-changed', AmbientModeTemperatureUnit.CELSIUS);
+    Polymer.dom.flush();
 
     const topicSourceList = ambientModePage.$$('topic-source-list');
     const ironList = topicSourceList.$$('iron-list');
@@ -140,23 +205,6 @@
     assertEquals('topicSource=0', router.getQueryParameters().toString());
   });
 
-  test('hasTopicSourceItems', function() {
-    const topicSourceListElement = ambientModePage.$$('topic-source-list');
-    const ironList = topicSourceListElement.$$('iron-list');
-    const topicSourceItems = ironList.querySelectorAll('topic-source-item');
-    assertEquals(2, topicSourceItems.length);
-  });
-
-  test('topicSourceItemHasCorrectRowHeight', function() {
-    const topicSourceListElement = ambientModePage.$$('topic-source-list');
-    const ironList = topicSourceListElement.$$('iron-list');
-    const topicSourceItems = ironList.querySelectorAll('topic-source-item');
-
-    topicSourceItems.forEach((row) => {
-      assertEquals(64, row.offsetHeight);
-    });
-  });
-
   test('Deep link to topic sources', async () => {
     loadTimeData.overrideValues({isDeepLinkingEnabled: true});
     assertTrue(loadTimeData.getBoolean('isDeepLinkingEnabled'));
@@ -166,6 +214,16 @@
     settings.Router.getInstance().navigateTo(
         settings.routes.AMBIENT_MODE, params);
 
+    // Select the google photos topic source.
+    cr.webUIListenerCallback('topic-source-changed', {
+      'topicSource': AmbientModeTopicSource.GOOGLE_PHOTOS,
+      'hasAlbums': true
+    });
+    // Select celsius as the initial temperature unit.
+    cr.webUIListenerCallback(
+        'temperature-unit-changed', AmbientModeTemperatureUnit.CELSIUS);
+    Polymer.dom.flush();
+
     const deepLinkElement =
         ambientModePage.$$('topic-source-list').$$('topic-source-item');
     await test_util.waitAfterNextRender(deepLinkElement);
@@ -174,28 +232,40 @@
         'Topic sources row should be focused for settingId=502.');
   });
 
-  test('temperatureUnitRadioButtonsDisabled', () => {
-    // When |selectedTemperatureUnit_| is invalid the radio buttons should be
-    // disabled. This is the initial state.
-    const radioGroup = ambientModePage.$$('#weatherDiv cr-radio-group');
+  test('temperatureUnitRadioButtonsVisibility', () => {
+    // Select the google photos topic source.
+    cr.webUIListenerCallback('topic-source-changed', {
+      'topicSource': AmbientModeTopicSource.GOOGLE_PHOTOS,
+      'hasAlbums': true
+    });
+    Polymer.dom.flush();
 
-    assertTrue(radioGroup.disabled);
+    // When |selectedTemperatureUnit_| is invalid the radio buttons is not
+    // visible. This is the initial state.
+    let radioGroup = ambientModePage.$$('#weatherDiv cr-radio-group');
+    assertFalse(!!radioGroup);
 
     // When |selectedTemperatureUnit_| is valid the radio buttons should be
-    // enabled.
+    // visible and enabled.
     cr.webUIListenerCallback(
         'temperature-unit-changed', AmbientModeTemperatureUnit.CELSIUS);
-    assertFalse(radioGroup.disabled);
+    Polymer.dom.flush();
 
-    cr.webUIListenerCallback(
-        'temperature-unit-changed', AmbientModeTemperatureUnit.UNKNOWN);
-    assertTrue(radioGroup.disabled);
+    radioGroup = ambientModePage.$$('#weatherDiv cr-radio-group');
+    assertTrue(!!radioGroup);
+    assertFalse(radioGroup.disabled);
   });
 
   test('temperatureUnitRadioButtons', async () => {
-    // Simulate C++ setting celsius as the initial temperature unit.
+    // Select the google photos topic source.
+    cr.webUIListenerCallback('topic-source-changed', {
+      'topicSource': AmbientModeTopicSource.GOOGLE_PHOTOS,
+      'hasAlbums': true
+    });
+    // Select celsius as the initial temperature unit.
     cr.webUIListenerCallback(
         'temperature-unit-changed', AmbientModeTemperatureUnit.CELSIUS);
+    Polymer.dom.flush();
 
     const celsiusButton = ambientModePage.$$('cr-radio-button[name=celsius]');
     const fahrenheitButton =
@@ -234,9 +304,15 @@
   });
 
   test('temperatureUnitRadioButtonsDoubleClick', async () => {
-    // Simulate C++ setting celsius as the default temperature unit.
+    // Select the google photos topic source.
+    cr.webUIListenerCallback('topic-source-changed', {
+      'topicSource': AmbientModeTopicSource.GOOGLE_PHOTOS,
+      'hasAlbums': true
+    });
+    // Select celsius as the initial temperature unit.
     cr.webUIListenerCallback(
         'temperature-unit-changed', AmbientModeTemperatureUnit.CELSIUS);
+    Polymer.dom.flush();
 
     const celsiusButton = ambientModePage.$$('cr-radio-button[name=celsius]');
 
@@ -246,4 +322,44 @@
     celsiusButton.click();
     assertEquals(0, browserProxy.getCallCount('setSelectedTemperatureUnit'));
   });
+
+  test('topicSourceAndWeatherDisabledWhenToggleOff', () => {
+    // Select the google photos topic source.
+    cr.webUIListenerCallback('topic-source-changed', {
+      'topicSource': AmbientModeTopicSource.GOOGLE_PHOTOS,
+      'hasAlbums': true
+    });
+    // Select celsius as the initial temperature unit.
+    cr.webUIListenerCallback(
+        'temperature-unit-changed', AmbientModeTemperatureUnit.CELSIUS);
+    Polymer.dom.flush();
+
+    const button = ambientModePage.$$('#ambientModeEnable');
+    assertTrue(!!button);
+    assertFalse(button.disabled);
+
+    // The button's state is set by the pref value.
+    let enabled =
+        ambientModePage.getPref('settings.ambient_mode.enabled.value');
+    assertTrue(enabled);
+    assertEquals(enabled, button.checked);
+
+    // Topic source list and weather radio group are enabled.
+    const topicSourceList = ambientModePage.$$('topic-source-list');
+    assertFalse(topicSourceList.disabled);
+    const radioGroup = ambientModePage.$$('#weatherDiv cr-radio-group');
+    assertFalse(radioGroup.disabled);
+
+    // Click the button will toggle the pref value.
+    button.click();
+    Polymer.dom.flush();
+    enabled = ambientModePage.getPref('settings.ambient_mode.enabled.value');
+    assertFalse(enabled);
+    assertEquals(enabled, button.checked);
+
+    // Topic source list and weather radio group are disabled.
+    assertTrue(topicSourceList.disabled);
+    assertTrue(radioGroup.disabled);
+  });
+
 });
diff --git a/chrome/test/data/webui/settings/chromeos/ambient_mode_photos_page_test.js b/chrome/test/data/webui/settings/chromeos/ambient_mode_photos_page_test.js
index 6d7fac9..5692b5b 100644
--- a/chrome/test/data/webui/settings/chromeos/ambient_mode_photos_page_test.js
+++ b/chrome/test/data/webui/settings/chromeos/ambient_mode_photos_page_test.js
@@ -151,6 +151,24 @@
     assertEquals('album1', album1.album.title);
   });
 
+  test('spinnerVisibility', function() {
+    const albumList = ambientModePhotosPage.$$('album-list');
+    const spinner = albumList.$$('paper-spinner-lite');
+    assertTrue(!!spinner);
+    assertTrue(spinner.active);
+    assertFalse(spinner.hidden);
+
+    ambientModePhotosPage.albums = [
+      {albumId: 'id0', checked: true, title: 'album0'},
+      {albumId: 'id1', checked: false, title: 'album1'}
+    ];
+    Polymer.dom.flush();
+
+    // Spinner is not active and not visible.
+    assertFalse(spinner.active);
+    assertTrue(spinner.hidden);
+  });
+
   test('personalPhotosImageContainerHasCorrectSize', function() {
     ambientModePhotosPage.albums = [
       {albumId: 'id0', checked: true, title: 'album0'},
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
index 7ea394fb..bc0536b 100644
--- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
+++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -1723,6 +1723,7 @@
   mocha.run();
 });
 
+// TODO(crbug/1109431): Remove this test once migration is complete.
 // eslint-disable-next-line no-var
 var OSSettingsLanguagesPageTest = class extends OSSettingsBrowserTest {
   /** @override */
@@ -1732,6 +1733,11 @@
   }
 
   /** @override */
+  get featureList() {
+    return {disabled: ['chromeos::features::kLanguageSettingsUpdate']};
+  }
+
+  /** @override */
   get extraLibraries() {
     return super.extraLibraries.concat([
       BROWSER_SETTINGS_PATH + '../fake_chrome_event.js',
@@ -1772,11 +1778,6 @@
   }
 
   /** @override */
-  get featureList() {
-    return {enabled: ['chromeos::features::kLanguageSettingsUpdate']};
-  }
-
-  /** @override */
   get extraLibraries() {
     return super.extraLibraries.concat([
       BROWSER_SETTINGS_PATH + '../fake_chrome_event.js',
@@ -1848,11 +1849,6 @@
   }
 
   /** @override */
-  get featureList() {
-    return {enabled: ['chromeos::features::kLanguageSettingsUpdate']};
-  }
-
-  /** @override */
   get extraLibraries() {
     return super.extraLibraries.concat([
       BROWSER_SETTINGS_PATH + '../fake_chrome_event.js',
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
index a8c8e27..658b566 100644
--- a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
+++ b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
@@ -38,41 +38,24 @@
   }
 };
 
+// TODO(crbug/1109431): Remove this test once migration is complete.
 // eslint-disable-next-line no-var
-var OSSettingsInputPageV3Test = class extends OSSettingsV3BrowserTest {
+var OSSettingsOsLanguagesPageV3Test = class extends OSSettingsV3BrowserTest {
   /** @override */
   get browsePreload() {
-    return 'chrome://os-settings/test_loader.html?module=settings/chromeos/input_page_test.m.js';
+    return 'chrome://os-settings/test_loader.html?module=settings/chromeos/os_languages_page_tests.m.js';
   }
 
   /** @override */
   get featureList() {
     return {
-      enabled: super.featureList.enabled.concat(
-          ['chromeos::features::kLanguageSettingsUpdate'])
+      enabled: super.featureList.enabled,
+      disabled: ['chromeos::features::kLanguageSettingsUpdate']
     };
   }
 };
 
-TEST_F('OSSettingsInputPageV3Test', 'All', () => mocha.run());
-
-// eslint-disable-next-line no-var
-var OSSettingsOsLanguagesPageV2V3Test = class extends OSSettingsV3BrowserTest {
-  /** @override */
-  get browsePreload() {
-    return 'chrome://os-settings/test_loader.html?module=settings/chromeos/os_languages_page_v2_tests.m.js';
-  }
-
-  /** @override */
-  get featureList() {
-    return {
-      enabled: super.featureList.enabled.concat(
-          ['chromeos::features::kLanguageSettingsUpdate'])
-    };
-  }
-};
-
-TEST_F('OSSettingsOsLanguagesPageV2V3Test', 'All', () => mocha.run());
+TEST_F('OSSettingsOsLanguagesPageV3Test', 'All', () => mocha.run());
 
 // eslint-disable-next-line no-var
 var OSSettingsNearbyShareSubPageV3Test = class extends OSSettingsV3BrowserTest {
@@ -97,6 +80,7 @@
  ['DateTimePage', 'date_time_page_tests.m.js'],
  ['GoogleAssistantPage', 'google_assistant_page_test.m.js'],
  ['InputMethodOptionPage', 'input_method_options_page_test.m.js'],
+ ['InputPage', 'input_page_test.m.js'],
  ['InternetConfig', 'internet_config_test.m.js'],
  ['InternetDetailPage', 'internet_detail_page_tests.m.js'],
  ['InternetKnownNetworksPage', 'internet_known_networks_page_tests.m.js'],
@@ -117,7 +101,7 @@
  ['NetworkSummary', 'network_summary_test.m.js'],
  ['NetworkSummaryItem', 'network_summary_item_test.m.js'],
  ['OsEditDictionaryPage', 'os_edit_dictionary_page_test.m.js'],
- ['OsLanguagesPage', 'os_languages_page_tests.m.js'],
+ ['OsLanguagesPageV2', 'os_languages_page_v2_tests.m.js'],
  ['OsSearchPage', 'os_search_page_test.m.js'],
  ['NearbyShareReceiveDialog', 'nearby_share_receive_dialog_tests.m.js'],
  ['ParentalControlsPage', 'parental_controls_page_test.m.js'],
diff --git a/chrome/test/data/webui/settings/languages_page_metrics_test_cros.js b/chrome/test/data/webui/settings/languages_page_metrics_test_cros.js
index 547a492..de2dec4 100644
--- a/chrome/test/data/webui/settings/languages_page_metrics_test_cros.js
+++ b/chrome/test/data/webui/settings/languages_page_metrics_test_cros.js
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {LanguagesBrowserProxyImpl, LanguagesMetricsProxyImpl, LanguagesPageInteraction} from 'chrome://settings/lazy_load.js';
 import {CrSettingsPrefs} from 'chrome://settings/settings.js';
@@ -14,6 +15,7 @@
 import {TestLanguagesBrowserProxy} from './test_languages_browser_proxy.m.js';
 import {TestLanguagesMetricsProxy} from './test_languages_metrics_proxy.js';
 
+// TODO(crbug/1109431): Remove this test once migration is complete.
 suite('LanguagesPageMetricsChromeOS', function() {
   /** @type {!LanguageHelper} */
   let languageHelper;
@@ -25,6 +27,9 @@
   let languagesMetricsProxy;
 
   suiteSetup(function() {
+    loadTimeData.overrideValues({
+      isChromeOSLanguagesSettingsUpdate: false,
+    });
     CrSettingsPrefs.deferInitialization = true;
   });
 
diff --git a/chrome/test/data/webui/settings/languages_page_tests.js b/chrome/test/data/webui/settings/languages_page_tests.js
index 189a0f08..6ced8e1 100644
--- a/chrome/test/data/webui/settings/languages_page_tests.js
+++ b/chrome/test/data/webui/settings/languages_page_tests.js
@@ -47,6 +47,10 @@
   const initialLanguages = 'en-US,sw';
 
   suiteSetup(function() {
+    // TODO(crbug/1109431): Update this test once migration is completed.
+    loadTimeData.overrideValues({
+      isChromeOSLanguagesSettingsUpdate: false,
+    });
     testing.Test.disableAnimationsAndTransitions();
     PolymerTest.clearBody();
     CrSettingsPrefs.deferInitialization = true;
diff --git a/chrome/updater/win/update_service_out_of_process.cc b/chrome/updater/win/update_service_out_of_process.cc
index c744576..152ba07e 100644
--- a/chrome/updater/win/update_service_out_of_process.cc
+++ b/chrome/updater/win/update_service_out_of_process.cc
@@ -345,7 +345,7 @@
   HRESULT hr = CreateUpdater(updater);
   if (FAILED(hr)) {
     DVLOG(2) << "Failed to create the updater interface: " << std::hex << hr;
-    std::move(callback).Run(static_cast<Result>(hr));
+    std::move(callback).Run(Result::kServiceFailed);
     return;
   }
 
@@ -366,8 +366,8 @@
     // state of the update server is. The observer may or may not post any
     // callback. Disconnecting the observer resolves this ambiguity and
     // transfers the ownership of the callback back to the owner of the
-    // observer.]
-    observer->Disconnect().Run(static_cast<Result>(hr));
+    // observer.
+    observer->Disconnect().Run(Result::kServiceFailed);
     return;
   }
 }
@@ -381,7 +381,7 @@
   HRESULT hr = CreateUpdater(updater);
   if (FAILED(hr)) {
     DVLOG(2) << "Failed to create the updater interface: " << std::hex << hr;
-    std::move(callback).Run(static_cast<Result>(hr));
+    std::move(callback).Run(Result::kServiceFailed);
     return;
   }
 
@@ -392,7 +392,7 @@
     DVLOG(2) << "Failed to call IUpdater::UpdateAll: " << std::hex << hr;
 
     // See the comment in the implementation of |UpdateAllOnSTA|.
-    observer->Disconnect().Run(static_cast<Result>(hr));
+    observer->Disconnect().Run(Result::kServiceFailed);
     return;
   }
 }
diff --git a/chromeos/components/diagnostics_ui/resources/realtime_cpu_chart.js b/chromeos/components/diagnostics_ui/resources/realtime_cpu_chart.js
index 8a62ecc0..15d0d12 100644
--- a/chromeos/components/diagnostics_ui/resources/realtime_cpu_chart.js
+++ b/chromeos/components/diagnostics_ui/resources/realtime_cpu_chart.js
@@ -7,6 +7,7 @@
 
 import './d3.min.js';
 
+import {assert} from 'chrome://resources/js/assert.m.js';
 import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 /**
@@ -34,6 +35,12 @@
   /** @private {!Array<Object>} */
   data_: [],
 
+  /**
+   * Unix timestamp in milliseconds of last data update.
+   * @private {number}
+   */
+  dataLastUpdated_: 0,
+
   properties: {
     user: {
       type: Number,
@@ -52,6 +59,12 @@
     },
 
     /** @private */
+    refreshInterval_: {
+      type: Number,
+      value: 200,  // in milliseconds.
+    },
+
+    /** @private */
     width_: {
       type: Number,
       value: 350,
@@ -86,10 +99,9 @@
 
   /** @override */
   created() {
-    // TODO(joonbug): Remove this when chart is ready.
-    // Initialize entire data array with a random data for now.
+    // Initialize the data array with 0s initially.
     for (var i = 0; i < this.numDataPoints_; ++i) {
-      this.data_.push({user: 25, system: 65});
+      this.data_.push({user: 0, system: 0});
     }
   },
 
@@ -97,8 +109,6 @@
   ready() {
     this.setScaling_();
     this.initializeChart_();
-    this.drawChartLine_('user-line');
-    this.drawChartLine_('system-line');
   },
 
   /**
@@ -122,10 +132,12 @@
     this.yAxisScaleFn_ =
         d3.scaleLinear().domain([0, 100]).range([this.graphHeight_, 0]);
 
-    // Map x-values [0, numDataPoints] to [0, graphWidth] linearly.
-    // Data value of 0 will map to 0, and numDataPoints maps to graphWidth.
+    // Map x-values [0, numDataPoints - 3] to [0, graphWidth] linearly.
+    // Data value of 0 maps to 0, and (numDataPoints - 3) maps to graphWidth.
+    // numDataPoints is subtracted since 1) data array is zero based, and
+    // 2) to smooth out the curve function.
     this.xAxisScaleFn_ =
-        d3.scaleLinear().domain([0, this.numDataPoints_]).range([
+        d3.scaleLinear().domain([0, this.numDataPoints_ - 3]).range([
           0, this.graphWidth_
         ]);
   },
@@ -148,6 +160,25 @@
                 .tickSize(-this.graphWidth_)  // Extend the ticks into the
                                               // entire graph as gridlines.
         );
+
+    const plotGroup = d3.select(this.$$('#plotGroup'));
+
+    // Feed data array to the plot group.
+    plotGroup.datum(this.data_);
+
+    // Select each line and configure the transition for animation.
+    // d3.transition API @ https://github.com/d3/d3-transition#d3-transition.
+    // d3.easing API @ https://github.com/d3/d3-ease#api-reference.
+    plotGroup.select('.user-line')
+        .transition()
+        .duration(this.refreshInterval_)
+        .ease(d3.easeLinear)  // Linear transition
+        .on('start', this.drawChartLine_.bind(this, 'user-line'));
+    plotGroup.select('.system-line')
+        .transition()
+        .duration(this.refreshInterval_)
+        .ease(d3.easeLinear)  // Linear transition
+        .on('start', this.drawChartLine_.bind(this, 'system-line'));
   },
 
   /**
@@ -168,15 +199,44 @@
   },
 
   /**
+   * Takes a snapshot of current CPU readings and appends to the data array.
+   * This method is called by each line after each transition.
+   * @private
+   */
+  appendDataSnapshot_() {
+    const now = new Date().getTime();
+
+    // We only want to append the data once per refreshInterval cycle even with
+    // multiple lines. Roughly limit the call so that at least half of the
+    // refreshInterval has elapsed since the last update.
+    if (now - this.dataLastUpdated_ > this.refreshInterval_ / 2) {
+      this.dataLastUpdated_ = now;
+      this.data_.push({user: this.user, system: this.system});
+      this.data_.shift();
+    }
+  },
+
+  /**
    * @param {string} lineClass class string for <path> element.
    * @private
    */
   drawChartLine_(lineClass) {
-    const lineElement = this.$$(`path.${lineClass}`);
+    this.appendDataSnapshot_();
 
-    // Attach data array and draw the line
+    const lineElement = assert(this.$$(`path.${lineClass}`));
+
+    // Reset the animation (transform) and redraw the line with new data.
+    // this.data_ is already associated with the plotGroup, so no need to
+    // specify it directly here.
     d3.select(lineElement)
-        .datum(this.data_)
-        .attr('d', this.getLineDefinition_(lineClass));
+        .attr('d', this.getLineDefinition_(lineClass))
+        .attr('transform', null);
+
+    // Start animation of the line towards left by one tick outside the chart
+    // boundary, then repeat the process.
+    d3.active(lineElement)
+        .attr('transform', 'translate(' + this.xAxisScaleFn_(-1) + ', 0)')
+        .transition()
+        .on('start', this.drawChartLine_.bind(this, lineClass));
   },
 });
diff --git a/chromeos/components/local_search_service/BUILD.gn b/chromeos/components/local_search_service/BUILD.gn
index 438b58c..10043fbb 100644
--- a/chromeos/components/local_search_service/BUILD.gn
+++ b/chromeos/components/local_search_service/BUILD.gn
@@ -8,18 +8,18 @@
   sources = [
     "content_extraction_utils.cc",
     "content_extraction_utils.h",
-    "index.cc",
-    "index.h",
+    "index_sync.cc",
+    "index_sync.h",
     "inverted_index.cc",
     "inverted_index.h",
     "inverted_index_search.cc",
     "inverted_index_search.h",
     "linear_map_search.cc",
     "linear_map_search.h",
-    "local_search_service.cc",
-    "local_search_service.h",
-    "local_search_service_factory.cc",
-    "local_search_service_factory.h",
+    "local_search_service_sync.cc",
+    "local_search_service_sync.h",
+    "local_search_service_sync_factory.cc",
+    "local_search_service_sync_factory.h",
     "pref_names.cc",
     "pref_names.h",
     "search_metrics_reporter.cc",
@@ -93,7 +93,7 @@
     "inverted_index_unittest.cc",
     "linear_map_search_unittest.cc",
     "local_search_service_proxy_unittest.cc",
-    "local_search_service_unittest.cc",
+    "local_search_service_sync_unittest.cc",
     "search_metrics_reporter_unittest.cc",
     "search_utils_unittest.cc",
   ]
diff --git a/chromeos/components/local_search_service/index_proxy.cc b/chromeos/components/local_search_service/index_proxy.cc
index 100398d..83fd28e1 100644
--- a/chromeos/components/local_search_service/index_proxy.cc
+++ b/chromeos/components/local_search_service/index_proxy.cc
@@ -5,12 +5,12 @@
 #include "chromeos/components/local_search_service/index_proxy.h"
 
 #include "base/optional.h"
-#include "chromeos/components/local_search_service/index.h"
+#include "chromeos/components/local_search_service/index_sync.h"
 
 namespace chromeos {
 namespace local_search_service {
 
-IndexProxy::IndexProxy(Index* index) : index_(index) {
+IndexProxy::IndexProxy(IndexSync* index) : index_(index) {
   DCHECK(index_);
 }
 
@@ -22,19 +22,19 @@
 }
 
 void IndexProxy::GetSize(GetSizeCallback callback) {
-  const uint64_t num_items = index_->GetSize();
+  const uint64_t num_items = index_->GetSizeSync();
   std::move(callback).Run(num_items);
 }
 
 void IndexProxy::AddOrUpdate(const std::vector<Data>& data,
                              AddOrUpdateCallback callback) {
-  index_->AddOrUpdate(data);
+  index_->AddOrUpdateSync(data);
   std::move(callback).Run();
 }
 
 void IndexProxy::Delete(const std::vector<std::string>& ids,
                         DeleteCallback callback) {
-  const uint64_t num_deleted = index_->Delete(ids);
+  const uint64_t num_deleted = index_->DeleteSync(ids);
   std::move(callback).Run(num_deleted);
 }
 
@@ -42,7 +42,7 @@
                       uint32_t max_results,
                       FindCallback callback) {
   std::vector<Result> results;
-  ResponseStatus status = index_->Find(query, max_results, &results);
+  ResponseStatus status = index_->FindSync(query, max_results, &results);
   if (status != ResponseStatus::kSuccess) {
     std::move(callback).Run(status, base::nullopt);
   } else {
@@ -51,7 +51,7 @@
 }
 
 void IndexProxy::ClearIndex(ClearIndexCallback callback) {
-  index_->ClearIndex();
+  index_->ClearIndexSync();
   std::move(callback).Run();
 }
 
diff --git a/chromeos/components/local_search_service/index_proxy.h b/chromeos/components/local_search_service/index_proxy.h
index 8e58dd33..77e9369 100644
--- a/chromeos/components/local_search_service/index_proxy.h
+++ b/chromeos/components/local_search_service/index_proxy.h
@@ -15,11 +15,11 @@
 namespace chromeos {
 namespace local_search_service {
 
-class Index;
+class IndexSync;
 
 class IndexProxy : public mojom::IndexProxy {
  public:
-  explicit IndexProxy(Index* index);
+  explicit IndexProxy(IndexSync* index);
   ~IndexProxy() override;
 
   void BindReceiver(mojo::PendingReceiver<mojom::IndexProxy> receiver);
@@ -36,7 +36,7 @@
   void ClearIndex(ClearIndexCallback callback) override;
 
  private:
-  Index* const index_;
+  IndexSync* const index_;
   mojo::ReceiverSet<mojom::IndexProxy> receivers_;
 };
 
diff --git a/chromeos/components/local_search_service/index.cc b/chromeos/components/local_search_service/index_sync.cc
similarity index 73%
rename from chromeos/components/local_search_service/index.cc
rename to chromeos/components/local_search_service/index_sync.cc
index f499337..e6d0614b 100644
--- a/chromeos/components/local_search_service/index.cc
+++ b/chromeos/components/local_search_service/index_sync.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/components/local_search_service/index.h"
+#include "chromeos/components/local_search_service/index_sync.h"
 
 #include <utility>
 
@@ -20,7 +20,7 @@
 }
 
 std::string IndexIdBasedHistogramPrefix(IndexId index_id) {
-  const std::string prefix = "LocalSearchService.";
+  const std::string prefix = "LocalSearchServiceSync.";
   switch (index_id) {
     case IndexId::kCrosSettings:
       return prefix + "CrosSettings";
@@ -30,7 +30,9 @@
 }
 
 }  // namespace
-Index::Index(IndexId index_id, Backend backend, PrefService* local_state) {
+IndexSync::IndexSync(IndexId index_id,
+                     Backend backend,
+                     PrefService* local_state) {
   histogram_prefix_ = IndexIdBasedHistogramPrefix(index_id);
   DCHECK(!histogram_prefix_.empty());
   LogIndexIdAndBackendType(histogram_prefix_, backend);
@@ -45,11 +47,11 @@
   reporter_->SetIndexId(index_id);
 }
 
-Index::~Index() = default;
+IndexSync::~IndexSync() = default;
 
-void Index::MaybeLogSearchResultsStats(ResponseStatus status,
-                                       size_t num_results,
-                                       base::TimeDelta latency) {
+void IndexSync::MaybeLogSearchResultsStats(ResponseStatus status,
+                                           size_t num_results,
+                                           base::TimeDelta latency) {
   if (reporter_)
     reporter_->OnSearchPerformed();
 
@@ -62,19 +64,19 @@
   }
 }
 
-void Index::MaybeLogIndexSize() {
-  const uint64_t index_size = GetSize();
+void IndexSync::MaybeLogIndexSize() {
+  const uint64_t index_size = GetSizeSync();
   if (index_size != 0u) {
     base::UmaHistogramCounts10000(histogram_prefix_ + ".NumberDocuments",
                                   index_size);
   }
 }
 
-void Index::SetSearchParams(const SearchParams& search_params) {
+void IndexSync::SetSearchParams(const SearchParams& search_params) {
   search_params_ = search_params;
 }
 
-SearchParams Index::GetSearchParamsForTesting() {
+SearchParams IndexSync::GetSearchParamsForTesting() {
   return search_params_;
 }
 
diff --git a/chromeos/components/local_search_service/index.h b/chromeos/components/local_search_service/index_sync.h
similarity index 70%
rename from chromeos/components/local_search_service/index.h
rename to chromeos/components/local_search_service/index_sync.h
index 40961e9..24b4dc1c 100644
--- a/chromeos/components/local_search_service/index.h
+++ b/chromeos/components/local_search_service/index_sync.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_INDEX_H_
-#define CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_INDEX_H_
+#ifndef CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_INDEX_SYNC_H_
+#define CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_INDEX_SYNC_H_
 
 #include <map>
 #include <memory>
@@ -23,39 +23,39 @@
 namespace chromeos {
 namespace local_search_service {
 
-// A local search service Index.
+// A local search service IndexSync.
 // It is the client-facing API for search and indexing. It can be implemented
 // with different backends that provide actual data storage/indexing/search
 // functions.
-class Index {
+class IndexSync {
  public:
-  Index(IndexId index_id, Backend backend, PrefService* local_state);
-  virtual ~Index();
+  IndexSync(IndexId index_id, Backend backend, PrefService* local_state);
+  virtual ~IndexSync();
 
-  Index(const Index&) = delete;
-  Index& operator=(const Index&) = delete;
+  IndexSync(const IndexSync&) = delete;
+  IndexSync& operator=(const IndexSync&) = delete;
 
   // Returns number of data items.
-  virtual uint64_t GetSize() = 0;
+  virtual uint64_t GetSizeSync() = 0;
 
   // Adds or updates data.
   // IDs of data should not be empty.
-  virtual void AddOrUpdate(const std::vector<Data>& data) = 0;
+  virtual void AddOrUpdateSync(const std::vector<Data>& data) = 0;
 
   // Deletes data with |ids| and returns number of items deleted.
   // If an id doesn't exist in the Index, no operation will be done.
   // IDs should not be empty.
-  virtual uint32_t Delete(const std::vector<std::string>& ids) = 0;
+  virtual uint32_t DeleteSync(const std::vector<std::string>& ids) = 0;
 
   // Clears all data in the index.
-  virtual void ClearIndex() = 0;
+  virtual void ClearIndexSync() = 0;
 
   // Returns matching results for a given query.
   // Zero |max_results| means no max.
   // Search behaviour depends on the implementation.
-  virtual ResponseStatus Find(const base::string16& query,
-                              uint32_t max_results,
-                              std::vector<Result>* results) = 0;
+  virtual ResponseStatus FindSync(const base::string16& query,
+                                  uint32_t max_results,
+                                  std::vector<Result>* results) = 0;
 
   // Logs daily search metrics if |reporter_| is non-null. Also logs other
   // UMA metrics (number results and search latency).
@@ -79,10 +79,10 @@
  private:
   std::string histogram_prefix_;
   std::unique_ptr<SearchMetricsReporter> reporter_;
-  base::WeakPtrFactory<Index> weak_ptr_factory_{this};
+  base::WeakPtrFactory<IndexSync> weak_ptr_factory_{this};
 };
 
 }  // namespace local_search_service
 }  // namespace chromeos
 
-#endif  // CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_INDEX_H_
+#endif  // CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_INDEX_SYNC_H_
diff --git a/chromeos/components/local_search_service/inverted_index_search.cc b/chromeos/components/local_search_service/inverted_index_search.cc
index 8c027b1d..ed6ad93 100644
--- a/chromeos/components/local_search_service/inverted_index_search.cc
+++ b/chromeos/components/local_search_service/inverted_index_search.cc
@@ -62,7 +62,7 @@
 
 InvertedIndexSearch::InvertedIndexSearch(IndexId index_id,
                                          PrefService* local_state)
-    : Index(index_id, Backend::kInvertedIndex, local_state),
+    : IndexSync(index_id, Backend::kInvertedIndex, local_state),
       inverted_index_(std::make_unique<InvertedIndex>()),
       blocking_task_runner_(base::ThreadPool::CreateSequencedTaskRunner(
           {base::TaskPriority::BEST_EFFORT, base::MayBlock(),
@@ -72,12 +72,12 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 }
 
-uint64_t InvertedIndexSearch::GetSize() {
+uint64_t InvertedIndexSearch::GetSizeSync() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   return inverted_index_->NumberDocuments();
 }
 
-void InvertedIndexSearch::AddOrUpdate(
+void InvertedIndexSearch::AddOrUpdateSync(
     const std::vector<local_search_service::Data>& data) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(!data.empty());
@@ -89,7 +89,7 @@
                      weak_ptr_factory_.GetWeakPtr()));
 }
 
-uint32_t InvertedIndexSearch::Delete(const std::vector<std::string>& ids) {
+uint32_t InvertedIndexSearch::DeleteSync(const std::vector<std::string>& ids) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(!ids.empty());
 
@@ -113,13 +113,13 @@
   return ids.size();
 }
 
-void InvertedIndexSearch::ClearIndex() {
+void InvertedIndexSearch::ClearIndexSync() {
   inverted_index_->ClearInvertedIndex();
 }
 
-ResponseStatus InvertedIndexSearch::Find(const base::string16& query,
-                                         uint32_t max_results,
-                                         std::vector<Result>* results) {
+ResponseStatus InvertedIndexSearch::FindSync(const base::string16& query,
+                                             uint32_t max_results,
+                                             std::vector<Result>* results) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   const base::TimeTicks start = base::TimeTicks::Now();
   DCHECK(results);
@@ -129,7 +129,7 @@
     MaybeLogSearchResultsStats(status, 0u, base::TimeDelta());
     return status;
   }
-  if (GetSize() == 0u) {
+  if (GetSizeSync() == 0u) {
     const ResponseStatus status = ResponseStatus::kEmptyIndex;
     MaybeLogSearchResultsStats(status, 0u, base::TimeDelta());
     return status;
diff --git a/chromeos/components/local_search_service/inverted_index_search.h b/chromeos/components/local_search_service/inverted_index_search.h
index bdcdaa0..057716df 100644
--- a/chromeos/components/local_search_service/inverted_index_search.h
+++ b/chromeos/components/local_search_service/inverted_index_search.h
@@ -14,7 +14,7 @@
 #include "base/sequence_checker.h"
 #include "base/sequenced_task_runner.h"
 #include "base/strings/string16.h"
-#include "chromeos/components/local_search_service/index.h"
+#include "chromeos/components/local_search_service/index_sync.h"
 #include "chromeos/components/local_search_service/shared_structs.h"
 
 namespace chromeos {
@@ -24,7 +24,7 @@
 
 // An implementation of Index.
 // A search via the inverted index backend with TF-IDF based document ranking.
-class InvertedIndexSearch : public Index {
+class InvertedIndexSearch : public IndexSync {
  public:
   InvertedIndexSearch(IndexId index_id, PrefService* local_state);
   ~InvertedIndexSearch() override;
@@ -33,24 +33,24 @@
   InvertedIndexSearch& operator=(const InvertedIndexSearch&) = delete;
 
   // Index overrides:
-  uint64_t GetSize() override;
+  uint64_t GetSizeSync() override;
   // TODO(jiameng): we always build the index after documents are updated. May
   // revise this strategy if there is a different use case.
-  void AddOrUpdate(const std::vector<Data>& data) override;
+  void AddOrUpdateSync(const std::vector<Data>& data) override;
   // TODO(jiameng): we always build the index after documents are deleted. May
   // revise this strategy if there is a different use case.
   // TODO(jiameng): for inverted index, the Delete function returns |ids| size,
   // and not actual number of documents deleted. This would change in the next
   // cl when these operations become async.
-  uint32_t Delete(const std::vector<std::string>& ids) override;
-  void ClearIndex() override;
+  uint32_t DeleteSync(const std::vector<std::string>& ids) override;
+  void ClearIndexSync() override;
   // Returns matching results for a given query by approximately matching the
   // query with terms in the documents. Documents are ranked by TF-IDF scores.
   // Scores in results are positive but not guaranteed to be in any particular
   // range.
-  ResponseStatus Find(const base::string16& query,
-                      uint32_t max_results,
-                      std::vector<Result>* results) override;
+  ResponseStatus FindSync(const base::string16& query,
+                          uint32_t max_results,
+                          std::vector<Result>* results) override;
 
   // Returns document id and number of occurrences of |term|.
   // Document ids are sorted in alphabetical order.
diff --git a/chromeos/components/local_search_service/inverted_index_search_unittest.cc b/chromeos/components/local_search_service/inverted_index_search_unittest.cc
index aea7ed8..b2fa2aa 100644
--- a/chromeos/components/local_search_service/inverted_index_search_unittest.cc
+++ b/chromeos/components/local_search_service/inverted_index_search_unittest.cc
@@ -48,9 +48,9 @@
       {"id2", {{"cid_3", "help article on wi-fi"}}}};
 
   const std::vector<Data> data = CreateTestData(data_to_register);
-  search_->AddOrUpdate(data);
+  search_->AddOrUpdateSync(data);
   Wait();
-  EXPECT_EQ(search_->GetSize(), 2u);
+  EXPECT_EQ(search_->GetSizeSync(), 2u);
 
   {
     // "network" does not exist in the index.
@@ -104,9 +104,9 @@
       {"id2", {{"cid_3", "help article on wi-fi"}}}};
 
   const std::vector<Data> data = CreateTestData(data_to_register);
-  search_->AddOrUpdate(data);
+  search_->AddOrUpdateSync(data);
   Wait();
-  EXPECT_EQ(search_->GetSize(), 2u);
+  EXPECT_EQ(search_->GetSizeSync(), 2u);
 
   const std::map<std::string, std::vector<ContentWithId>> data_to_update = {
       {"id1",
@@ -115,9 +115,9 @@
       {"id3", {{"cid_3", "Google Map"}}}};
 
   const std::vector<Data> updated_data = CreateTestData(data_to_update);
-  search_->AddOrUpdate(updated_data);
+  search_->AddOrUpdateSync(updated_data);
   Wait();
-  EXPECT_EQ(search_->GetSize(), 3u);
+  EXPECT_EQ(search_->GetSizeSync(), 3u);
 
   {
     const TermOccurrence doc_with_freq =
@@ -146,7 +146,7 @@
   }
 }
 
-TEST_F(InvertedIndexSearchTest, Delete) {
+TEST_F(InvertedIndexSearchTest, DeleteSync) {
   const std::map<std::string, std::vector<ContentWithId>> data_to_register = {
       {"id1",
        {{"cid_1", "This is a help wi-fi article"},
@@ -154,11 +154,11 @@
       {"id2", {{"cid_3", "help article on wi-fi"}}}};
 
   const std::vector<Data> data = CreateTestData(data_to_register);
-  search_->AddOrUpdate(data);
+  search_->AddOrUpdateSync(data);
   Wait();
-  EXPECT_EQ(search_->GetSize(), 2u);
+  EXPECT_EQ(search_->GetSizeSync(), 2u);
 
-  EXPECT_EQ(search_->Delete({"id1", "id3"}), 2u);
+  EXPECT_EQ(search_->DeleteSync({"id1", "id3"}), 2u);
   Wait();
 
   {
@@ -170,7 +170,7 @@
   }
 }
 
-TEST_F(InvertedIndexSearchTest, ClearIndex) {
+TEST_F(InvertedIndexSearchTest, ClearIndexSync) {
   const std::map<std::string, std::vector<ContentWithId>> data_to_register = {
       {"id1",
        {{"cid_1", "This is a help wi-fi article"},
@@ -179,13 +179,13 @@
 
   const std::vector<Data> data = CreateTestData(data_to_register);
 
-  search_->AddOrUpdate(data);
+  search_->AddOrUpdateSync(data);
   Wait();
-  EXPECT_EQ(search_->GetSize(), 2u);
+  EXPECT_EQ(search_->GetSizeSync(), 2u);
 
-  search_->ClearIndex();
+  search_->ClearIndexSync();
   Wait();
-  EXPECT_EQ(search_->GetSize(), 0u);
+  EXPECT_EQ(search_->GetSizeSync(), 0u);
 }
 
 TEST_F(InvertedIndexSearchTest, Find) {
@@ -198,44 +198,45 @@
 
   // Nothing has been added to the index.
   std::vector<Result> results;
-  EXPECT_EQ(
-      search_->Find(base::UTF8ToUTF16("network"), /*max_results=*/10, &results),
-      ResponseStatus::kEmptyIndex);
+  EXPECT_EQ(search_->FindSync(base::UTF8ToUTF16("network"), /*max_results=*/10,
+                              &results),
+            ResponseStatus::kEmptyIndex);
   EXPECT_TRUE(results.empty());
 
   // Data is added and then deleted from index, making the index empty.
-  search_->AddOrUpdate(data);
+  search_->AddOrUpdateSync(data);
   Wait();
-  EXPECT_EQ(search_->GetSize(), 2u);
-  EXPECT_EQ(search_->Delete({"id1", "id2"}), 2u);
+  EXPECT_EQ(search_->GetSizeSync(), 2u);
+  EXPECT_EQ(search_->DeleteSync({"id1", "id2"}), 2u);
   Wait();
-  EXPECT_EQ(search_->GetSize(), 0u);
+  EXPECT_EQ(search_->GetSizeSync(), 0u);
 
-  EXPECT_EQ(
-      search_->Find(base::UTF8ToUTF16("network"), /*max_results=*/10, &results),
-      ResponseStatus::kEmptyIndex);
+  EXPECT_EQ(search_->FindSync(base::UTF8ToUTF16("network"), /*max_results=*/10,
+                              &results),
+            ResponseStatus::kEmptyIndex);
   EXPECT_TRUE(results.empty());
 
   // Index is populated again, but query is empty.
-  search_->AddOrUpdate(data);
+  search_->AddOrUpdateSync(data);
   Wait();
-  EXPECT_EQ(search_->GetSize(), 2u);
+  EXPECT_EQ(search_->GetSizeSync(), 2u);
 
-  EXPECT_EQ(search_->Find(base::UTF8ToUTF16(""), /*max_results=*/10, &results),
-            ResponseStatus::kEmptyQuery);
+  EXPECT_EQ(
+      search_->FindSync(base::UTF8ToUTF16(""), /*max_results=*/10, &results),
+      ResponseStatus::kEmptyQuery);
   EXPECT_TRUE(results.empty());
 
   // No document is found for a given query.
-  EXPECT_EQ(search_->Find(base::UTF8ToUTF16("networkstuff"), /*max_results=*/10,
-                          &results),
+  EXPECT_EQ(search_->FindSync(base::UTF8ToUTF16("networkstuff"),
+                              /*max_results=*/10, &results),
             ResponseStatus::kSuccess);
   EXPECT_TRUE(results.empty());
 
   {
     // A document is found.
     // Query's case is normalized.
-    EXPECT_EQ(search_->Find(base::UTF8ToUTF16("ANOTHER networkstuff"),
-                            /*max_results=*/10, &results),
+    EXPECT_EQ(search_->FindSync(base::UTF8ToUTF16("ANOTHER networkstuff"),
+                                /*max_results=*/10, &results),
               ResponseStatus::kSuccess);
     EXPECT_EQ(results.size(), 1u);
 
@@ -251,8 +252,8 @@
 
   {
     // Two documents are found.
-    EXPECT_EQ(search_->Find(base::UTF8ToUTF16("another help"),
-                            /*max_results=*/10, &results),
+    EXPECT_EQ(search_->FindSync(base::UTF8ToUTF16("another help"),
+                                /*max_results=*/10, &results),
               ResponseStatus::kSuccess);
     EXPECT_EQ(results.size(), 2u);
 
@@ -282,8 +283,8 @@
 
   {
     // Same as above,  but max number of results is set to 1.
-    EXPECT_EQ(search_->Find(base::UTF8ToUTF16("another help"),
-                            /*max_results=*/1, &results),
+    EXPECT_EQ(search_->FindSync(base::UTF8ToUTF16("another help"),
+                                /*max_results=*/1, &results),
               ResponseStatus::kSuccess);
     EXPECT_EQ(results.size(), 1u);
     EXPECT_EQ(results[0].id, "id1");
@@ -291,14 +292,14 @@
 
   {
     // Same as above, but set max_results to 0, meaning no max.
-    EXPECT_EQ(search_->Find(base::UTF8ToUTF16("another help"),
-                            /*max_results=*/0, &results),
+    EXPECT_EQ(search_->FindSync(base::UTF8ToUTF16("another help"),
+                                /*max_results=*/0, &results),
               ResponseStatus::kSuccess);
     EXPECT_EQ(results.size(), 2u);
   }
 }
 
-TEST_F(InvertedIndexSearchTest, SequenceOfDeletes) {
+TEST_F(InvertedIndexSearchTest, SequenceOfDeleteSyncs) {
   const std::map<std::string, std::vector<ContentWithId>> data_to_register = {
       {"id1",
        {{"cid_1", "This is a help wi-fi article"},
@@ -306,7 +307,7 @@
       {"id2", {{"cid_3", "help article on wi-fi"}}}};
 
   const std::vector<Data> data = CreateTestData(data_to_register);
-  search_->AddOrUpdate(data);
+  search_->AddOrUpdateSync(data);
 
   const std::map<std::string, std::vector<ContentWithId>> data_to_update = {
       {"id1",
@@ -315,14 +316,14 @@
       {"id3", {{"cid_3", "Google Map"}}}};
 
   const std::vector<Data> updated_data = CreateTestData(data_to_update);
-  search_->AddOrUpdate(updated_data);
+  search_->AddOrUpdateSync(updated_data);
 
-  EXPECT_EQ(search_->Delete({"id1"}), 1u);
-  EXPECT_EQ(search_->Delete({"id2", "id3"}), 2u);
+  EXPECT_EQ(search_->DeleteSync({"id1"}), 1u);
+  EXPECT_EQ(search_->DeleteSync({"id2", "id3"}), 2u);
 
   // Force all operations to complete.
   Wait();
-  EXPECT_EQ(search_->GetSize(), 0u);
+  EXPECT_EQ(search_->GetSizeSync(), 0u);
 }
 
 }  // namespace local_search_service
diff --git a/chromeos/components/local_search_service/linear_map_search.cc b/chromeos/components/local_search_service/linear_map_search.cc
index 180083e..eedb0d0 100644
--- a/chromeos/components/local_search_service/linear_map_search.cc
+++ b/chromeos/components/local_search_service/linear_map_search.cc
@@ -70,15 +70,15 @@
 }  // namespace
 
 LinearMapSearch::LinearMapSearch(IndexId index_id, PrefService* local_state)
-    : Index(index_id, Backend::kLinearMap, local_state) {}
+    : IndexSync(index_id, Backend::kLinearMap, local_state) {}
 
 LinearMapSearch::~LinearMapSearch() = default;
 
-uint64_t LinearMapSearch::GetSize() {
+uint64_t LinearMapSearch::GetSizeSync() {
   return data_.size();
 }
 
-void LinearMapSearch::AddOrUpdate(
+void LinearMapSearch::AddOrUpdateSync(
     const std::vector<local_search_service::Data>& data) {
   for (const auto& item : data) {
     const auto& id = item.id;
@@ -92,7 +92,7 @@
   MaybeLogIndexSize();
 }
 
-uint32_t LinearMapSearch::Delete(const std::vector<std::string>& ids) {
+uint32_t LinearMapSearch::DeleteSync(const std::vector<std::string>& ids) {
   uint32_t num_deleted = 0u;
   for (const auto& id : ids) {
     DCHECK(!id.empty());
@@ -109,13 +109,13 @@
   return num_deleted;
 }
 
-void LinearMapSearch::ClearIndex() {
+void LinearMapSearch::ClearIndexSync() {
   data_.clear();
 }
 
-ResponseStatus LinearMapSearch::Find(const base::string16& query,
-                                     uint32_t max_results,
-                                     std::vector<Result>* results) {
+ResponseStatus LinearMapSearch::FindSync(const base::string16& query,
+                                         uint32_t max_results,
+                                         std::vector<Result>* results) {
   const base::TimeTicks start = base::TimeTicks::Now();
   DCHECK(results);
   results->clear();
diff --git a/chromeos/components/local_search_service/linear_map_search.h b/chromeos/components/local_search_service/linear_map_search.h
index 61b995e..5c63e2c 100644
--- a/chromeos/components/local_search_service/linear_map_search.h
+++ b/chromeos/components/local_search_service/linear_map_search.h
@@ -12,7 +12,7 @@
 
 #include "base/macros.h"
 #include "base/strings/string16.h"
-#include "chromeos/components/local_search_service/index.h"
+#include "chromeos/components/local_search_service/index_sync.h"
 #include "chromeos/components/local_search_service/shared_structs.h"
 
 class PrefService;
@@ -29,7 +29,7 @@
 // A search backend that linearly scans all documents in the storage and finds
 // documents that match the input query. Search is done by matching query with
 // documents' search tags.
-class LinearMapSearch : public Index {
+class LinearMapSearch : public IndexSync {
  public:
   LinearMapSearch(IndexId index_id, PrefService* local_state);
   ~LinearMapSearch() override;
@@ -38,16 +38,16 @@
   LinearMapSearch& operator=(const LinearMapSearch&) = delete;
 
   // Index overrides:
-  uint64_t GetSize() override;
-  void AddOrUpdate(const std::vector<Data>& data) override;
-  uint32_t Delete(const std::vector<std::string>& ids) override;
-  void ClearIndex() override;
+  uint64_t GetSizeSync() override;
+  void AddOrUpdateSync(const std::vector<Data>& data) override;
+  uint32_t DeleteSync(const std::vector<std::string>& ids) override;
+  void ClearIndexSync() override;
   // For each data in the index, we return the 1st search tag that matches
   // the query (i.e. above the threshold). Client should put the most
   // important search tag first when registering the data in the index.
-  ResponseStatus Find(const base::string16& query,
-                      uint32_t max_results,
-                      std::vector<Result>* results) override;
+  ResponseStatus FindSync(const base::string16& query,
+                          uint32_t max_results,
+                          std::vector<Result>* results) override;
 
  private:
   // Returns all search results for a given query.
diff --git a/chromeos/components/local_search_service/linear_map_search_unittest.cc b/chromeos/components/local_search_service/linear_map_search_unittest.cc
index 84f0da0..aa5238ad 100644
--- a/chromeos/components/local_search_service/linear_map_search_unittest.cc
+++ b/chromeos/components/local_search_service/linear_map_search_unittest.cc
@@ -40,7 +40,8 @@
   DCHECK(index);
 
   std::vector<Result> results;
-  auto status = index->Find(base::UTF8ToUTF16(query), max_results, &results);
+  auto status =
+      index->FindSync(base::UTF8ToUTF16(query), max_results, &results);
 
   EXPECT_EQ(status, expected_status);
 
@@ -107,8 +108,8 @@
   const std::map<std::string, std::vector<ContentWithId>> data_to_register = {
       {"id1", {{"tag1", "Wi-Fi"}}}, {"id2", {{"tag2", "famous"}}}};
   std::vector<Data> data = CreateTestData(data_to_register);
-  index_->AddOrUpdate(data);
-  EXPECT_EQ(index_->GetSize(), 2u);
+  index_->AddOrUpdateSync(data);
+  EXPECT_EQ(index_->GetSizeSync(), 2u);
   {
     SearchParams search_params;
     search_params.relevance_threshold = 0.0;
@@ -145,8 +146,8 @@
       {"id1", {{"tag1", "abcde"}, {"tag2", "Wi-Fi"}}},
       {"id2", {{"tag3", "wifi"}}}};
   std::vector<Data> data = CreateTestData(data_to_register);
-  index_->AddOrUpdate(data);
-  EXPECT_EQ(index_->GetSize(), 2u);
+  index_->AddOrUpdateSync(data);
+  EXPECT_EQ(index_->GetSizeSync(), 2u);
   SearchParams search_params;
   search_params.relevance_threshold = 0.3;
   index_->SetSearchParams(search_params);
@@ -173,8 +174,8 @@
   std::vector<Data> data = CreateTestData(data_to_register);
   EXPECT_EQ(data.size(), 2u);
 
-  index_->AddOrUpdate(data);
-  EXPECT_EQ(index_->GetSize(), 2u);
+  index_->AddOrUpdateSync(data);
+  EXPECT_EQ(index_->GetSizeSync(), 2u);
 
   // Find result with query "id1". It returns an exact match.
   const std::vector<ResultWithIds> expected_results = {{"id1", {"cid1"}}};
@@ -192,11 +193,11 @@
   std::vector<Data> data = CreateTestData(data_to_register);
   EXPECT_EQ(data.size(), 2u);
 
-  index_->AddOrUpdate(data);
-  EXPECT_EQ(index_->GetSize(), 2u);
+  index_->AddOrUpdateSync(data);
+  EXPECT_EQ(index_->GetSizeSync(), 2u);
 
-  index_->ClearIndex();
-  EXPECT_EQ(index_->GetSize(), 0u);
+  index_->ClearIndexSync();
+  EXPECT_EQ(index_->GetSizeSync(), 0u);
 }
 
 }  // namespace local_search_service
diff --git a/chromeos/components/local_search_service/local_search_service.h b/chromeos/components/local_search_service/local_search_service.h
deleted file mode 100644
index c13fdcf4..0000000
--- a/chromeos/components/local_search_service/local_search_service.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// 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 CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_LOCAL_SEARCH_SERVICE_H_
-#define CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_LOCAL_SEARCH_SERVICE_H_
-
-#include <map>
-#include <memory>
-
-#include "base/macros.h"
-#include "chromeos/components/local_search_service/shared_structs.h"
-#include "components/keyed_service/core/keyed_service.h"
-
-class PrefService;
-
-namespace chromeos {
-
-namespace local_search_service {
-
-class Index;
-
-// LocalSearchService creates and owns content-specific Indices. Clients can
-// call it |GetIndex| method to get an Index for a given index id.
-class LocalSearchService : public KeyedService {
- public:
-  LocalSearchService();
-  ~LocalSearchService() override;
-  LocalSearchService(const LocalSearchService&) = delete;
-  LocalSearchService& operator=(const LocalSearchService&) = delete;
-
-  Index* GetIndex(IndexId index_id, Backend backend, PrefService* local_state);
-
- private:
-  std::map<IndexId, std::unique_ptr<Index>> indices_;
-};
-
-}  // namespace local_search_service
-}  // namespace chromeos
-
-#endif  // CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_LOCAL_SEARCH_SERVICE_H_
diff --git a/chromeos/components/local_search_service/local_search_service_factory.cc b/chromeos/components/local_search_service/local_search_service_factory.cc
deleted file mode 100644
index 69ce1a0..0000000
--- a/chromeos/components/local_search_service/local_search_service_factory.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-// 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 "chromeos/components/local_search_service/local_search_service_factory.h"
-
-#include "chromeos/components/local_search_service/local_search_service.h"
-#include "components/keyed_service/content/browser_context_dependency_manager.h"
-
-namespace chromeos {
-namespace local_search_service {
-
-LocalSearchService* LocalSearchServiceFactory::GetForBrowserContext(
-    content::BrowserContext* context) {
-  return static_cast<LocalSearchService*>(
-      LocalSearchServiceFactory::GetInstance()->GetServiceForBrowserContext(
-          context, true /* create */));
-}
-
-LocalSearchServiceFactory* LocalSearchServiceFactory::GetInstance() {
-  return base::Singleton<LocalSearchServiceFactory>::get();
-}
-
-LocalSearchServiceFactory::LocalSearchServiceFactory()
-    : BrowserContextKeyedServiceFactory(
-          "LocalSearchService",
-          BrowserContextDependencyManager::GetInstance()) {}
-
-LocalSearchServiceFactory::~LocalSearchServiceFactory() = default;
-
-content::BrowserContext* LocalSearchServiceFactory::GetBrowserContextToUse(
-    content::BrowserContext* context) const {
-  // The service should exist in incognito mode.
-  return context;
-}
-
-KeyedService* LocalSearchServiceFactory::BuildServiceInstanceFor(
-    content::BrowserContext* /* context */) const {
-  return new LocalSearchService();
-}
-
-}  // namespace local_search_service
-}  // namespace chromeos
diff --git a/chromeos/components/local_search_service/local_search_service_proxy.cc b/chromeos/components/local_search_service/local_search_service_proxy.cc
index 84cce16..6b4d7b3 100644
--- a/chromeos/components/local_search_service/local_search_service_proxy.cc
+++ b/chromeos/components/local_search_service/local_search_service_proxy.cc
@@ -5,7 +5,7 @@
 #include "chromeos/components/local_search_service/local_search_service_proxy.h"
 
 #include "chromeos/components/local_search_service/index_proxy.h"
-#include "chromeos/components/local_search_service/local_search_service.h"
+#include "chromeos/components/local_search_service/local_search_service_sync.h"
 #include "chromeos/components/local_search_service/shared_structs.h"
 #include "components/prefs/pref_service.h"
 
@@ -13,7 +13,7 @@
 namespace local_search_service {
 
 LocalSearchServiceProxy::LocalSearchServiceProxy(
-    local_search_service::LocalSearchService* local_search_service)
+    local_search_service::LocalSearchServiceSync* local_search_service)
     : service_(local_search_service) {
   DCHECK(service_);
 }
@@ -34,7 +34,7 @@
     mojo::PendingReceiver<mojom::IndexProxy> index_receiver) {
   auto it = indices_.find(index_id);
   if (it == indices_.end()) {
-    Index* index = service_->GetIndex(index_id, backend, local_state);
+    IndexSync* index = service_->GetIndexSync(index_id, backend, local_state);
     it = indices_.emplace(index_id, std::make_unique<IndexProxy>(index)).first;
   }
   it->second->BindReceiver(std::move(index_receiver));
diff --git a/chromeos/components/local_search_service/local_search_service_proxy.h b/chromeos/components/local_search_service/local_search_service_proxy.h
index e10e6f65..b3eed102 100644
--- a/chromeos/components/local_search_service/local_search_service_proxy.h
+++ b/chromeos/components/local_search_service/local_search_service_proxy.h
@@ -17,7 +17,7 @@
 namespace chromeos {
 namespace local_search_service {
 
-class LocalSearchService;
+class LocalSearchServiceSync;
 class IndexProxy;
 enum class IndexId;
 enum class Backend;
@@ -25,7 +25,8 @@
 class LocalSearchServiceProxy : public mojom::LocalSearchServiceProxy,
                                 public KeyedService {
  public:
-  explicit LocalSearchServiceProxy(LocalSearchService* local_search_service);
+  explicit LocalSearchServiceProxy(
+      LocalSearchServiceSync* local_search_service);
   ~LocalSearchServiceProxy() override;
 
   LocalSearchServiceProxy(const LocalSearchServiceProxy&) = delete;
@@ -53,7 +54,7 @@
                 mojo::PendingReceiver<mojom::IndexProxy> index_receiver);
 
  private:
-  LocalSearchService* const service_;
+  LocalSearchServiceSync* const service_;
   mojo::ReceiverSet<mojom::LocalSearchServiceProxy> receivers_;
   std::map<IndexId, std::unique_ptr<IndexProxy>> indices_;
 };
diff --git a/chromeos/components/local_search_service/local_search_service_proxy_factory.cc b/chromeos/components/local_search_service/local_search_service_proxy_factory.cc
index 61cd62d..ebfff35 100644
--- a/chromeos/components/local_search_service/local_search_service_proxy_factory.cc
+++ b/chromeos/components/local_search_service/local_search_service_proxy_factory.cc
@@ -4,8 +4,8 @@
 
 #include "chromeos/components/local_search_service/local_search_service_proxy_factory.h"
 
-#include "chromeos/components/local_search_service/local_search_service_factory.h"
 #include "chromeos/components/local_search_service/local_search_service_proxy.h"
+#include "chromeos/components/local_search_service/local_search_service_sync_factory.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 
 namespace chromeos {
@@ -29,7 +29,7 @@
     : BrowserContextKeyedServiceFactory(
           "LocalSearchServiceProxy",
           BrowserContextDependencyManager::GetInstance()) {
-  DependsOn(LocalSearchServiceFactory::GetInstance());
+  DependsOn(LocalSearchServiceSyncFactory::GetInstance());
 }
 
 LocalSearchServiceProxyFactory::~LocalSearchServiceProxyFactory() = default;
@@ -44,7 +44,7 @@
     content::BrowserContext* context) const {
   DCHECK(context);
   return new LocalSearchServiceProxy(
-      LocalSearchServiceFactory::GetForBrowserContext(context));
+      LocalSearchServiceSyncFactory::GetForBrowserContext(context));
 }
 
 }  // namespace local_search_service
diff --git a/chromeos/components/local_search_service/local_search_service_proxy_unittest.cc b/chromeos/components/local_search_service/local_search_service_proxy_unittest.cc
index ba3a8bc5..6dc705bd 100644
--- a/chromeos/components/local_search_service/local_search_service_proxy_unittest.cc
+++ b/chromeos/components/local_search_service/local_search_service_proxy_unittest.cc
@@ -8,7 +8,7 @@
 #include "base/run_loop.h"
 #include "base/test/task_environment.h"
 #include "chromeos/components/local_search_service/index_proxy.h"
-#include "chromeos/components/local_search_service/local_search_service.h"
+#include "chromeos/components/local_search_service/local_search_service_sync.h"
 #include "chromeos/components/local_search_service/mojom/types.mojom.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -29,7 +29,7 @@
  private:
   base::test::TaskEnvironment task_environment_;
 
-  LocalSearchService service_;
+  LocalSearchServiceSync service_;
   std::unique_ptr<LocalSearchServiceProxy> service_proxy_;
 };
 
diff --git a/chromeos/components/local_search_service/local_search_service.cc b/chromeos/components/local_search_service/local_search_service_sync.cc
similarity index 76%
rename from chromeos/components/local_search_service/local_search_service.cc
rename to chromeos/components/local_search_service/local_search_service_sync.cc
index 4c2d5f6a..9ddea234 100644
--- a/chromeos/components/local_search_service/local_search_service.cc
+++ b/chromeos/components/local_search_service/local_search_service_sync.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/components/local_search_service/local_search_service.h"
+#include "chromeos/components/local_search_service/local_search_service_sync.h"
 
 #include <utility>
 
@@ -12,13 +12,13 @@
 namespace chromeos {
 namespace local_search_service {
 
-LocalSearchService::LocalSearchService() = default;
+LocalSearchServiceSync::LocalSearchServiceSync() = default;
 
-LocalSearchService::~LocalSearchService() = default;
+LocalSearchServiceSync::~LocalSearchServiceSync() = default;
 
-Index* LocalSearchService::GetIndex(IndexId index_id,
-                                    Backend backend,
-                                    PrefService* local_state) {
+IndexSync* LocalSearchServiceSync::GetIndexSync(IndexId index_id,
+                                                Backend backend,
+                                                PrefService* local_state) {
   auto it = indices_.find(index_id);
   if (it == indices_.end()) {
     switch (backend) {
diff --git a/chromeos/components/local_search_service/local_search_service_sync.h b/chromeos/components/local_search_service/local_search_service_sync.h
new file mode 100644
index 0000000..ecd5f29
--- /dev/null
+++ b/chromeos/components/local_search_service/local_search_service_sync.h
@@ -0,0 +1,43 @@
+// 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 CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_LOCAL_SEARCH_SERVICE_SYNC_H_
+#define CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_LOCAL_SEARCH_SERVICE_SYNC_H_
+
+#include <map>
+#include <memory>
+
+#include "base/macros.h"
+#include "chromeos/components/local_search_service/shared_structs.h"
+#include "components/keyed_service/core/keyed_service.h"
+
+class PrefService;
+
+namespace chromeos {
+
+namespace local_search_service {
+
+class IndexSync;
+
+// LocalSearchServiceSync creates and owns content-specific Indices. Clients can
+// call it |GetIndexSync| method to get an IndexSync for a given index id.
+class LocalSearchServiceSync : public KeyedService {
+ public:
+  LocalSearchServiceSync();
+  ~LocalSearchServiceSync() override;
+  LocalSearchServiceSync(const LocalSearchServiceSync&) = delete;
+  LocalSearchServiceSync& operator=(const LocalSearchServiceSync&) = delete;
+
+  IndexSync* GetIndexSync(IndexId index_id,
+                          Backend backend,
+                          PrefService* local_state);
+
+ private:
+  std::map<IndexId, std::unique_ptr<IndexSync>> indices_;
+};
+
+}  // namespace local_search_service
+}  // namespace chromeos
+
+#endif  // CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_LOCAL_SEARCH_SERVICE_SYNC_H_
diff --git a/chromeos/components/local_search_service/local_search_service_sync_factory.cc b/chromeos/components/local_search_service/local_search_service_sync_factory.cc
new file mode 100644
index 0000000..875f9dd
--- /dev/null
+++ b/chromeos/components/local_search_service/local_search_service_sync_factory.cc
@@ -0,0 +1,43 @@
+// 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 "chromeos/components/local_search_service/local_search_service_sync_factory.h"
+
+#include "chromeos/components/local_search_service/local_search_service_sync.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+
+namespace chromeos {
+namespace local_search_service {
+
+LocalSearchServiceSync* LocalSearchServiceSyncFactory::GetForBrowserContext(
+    content::BrowserContext* context) {
+  return static_cast<LocalSearchServiceSync*>(
+      LocalSearchServiceSyncFactory::GetInstance()->GetServiceForBrowserContext(
+          context, true /* create */));
+}
+
+LocalSearchServiceSyncFactory* LocalSearchServiceSyncFactory::GetInstance() {
+  return base::Singleton<LocalSearchServiceSyncFactory>::get();
+}
+
+LocalSearchServiceSyncFactory::LocalSearchServiceSyncFactory()
+    : BrowserContextKeyedServiceFactory(
+          "LocalSearchServiceSync",
+          BrowserContextDependencyManager::GetInstance()) {}
+
+LocalSearchServiceSyncFactory::~LocalSearchServiceSyncFactory() = default;
+
+content::BrowserContext* LocalSearchServiceSyncFactory::GetBrowserContextToUse(
+    content::BrowserContext* context) const {
+  // The service should exist in incognito mode.
+  return context;
+}
+
+KeyedService* LocalSearchServiceSyncFactory::BuildServiceInstanceFor(
+    content::BrowserContext* /* context */) const {
+  return new LocalSearchServiceSync();
+}
+
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/components/local_search_service/local_search_service_factory.h b/chromeos/components/local_search_service/local_search_service_sync_factory.h
similarity index 60%
rename from chromeos/components/local_search_service/local_search_service_factory.h
rename to chromeos/components/local_search_service/local_search_service_sync_factory.h
index 66275fd..24a3ca4 100644
--- a/chromeos/components/local_search_service/local_search_service_factory.h
+++ b/chromeos/components/local_search_service/local_search_service_sync_factory.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_LOCAL_SEARCH_SERVICE_FACTORY_H_
-#define CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_LOCAL_SEARCH_SERVICE_FACTORY_H_
+#ifndef CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_LOCAL_SEARCH_SERVICE_SYNC_FACTORY_H_
+#define CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_LOCAL_SEARCH_SERVICE_SYNC_FACTORY_H_
 
 #include "base/macros.h"
 #include "base/memory/singleton.h"
@@ -13,24 +13,24 @@
 
 namespace local_search_service {
 
-class LocalSearchService;
+class LocalSearchServiceSync;
 
-class LocalSearchServiceFactory : public BrowserContextKeyedServiceFactory {
+class LocalSearchServiceSyncFactory : public BrowserContextKeyedServiceFactory {
  public:
-  static LocalSearchService* GetForBrowserContext(
+  static LocalSearchServiceSync* GetForBrowserContext(
       content::BrowserContext* context);
 
-  static LocalSearchServiceFactory* GetInstance();
+  static LocalSearchServiceSyncFactory* GetInstance();
 
  private:
-  friend struct base::DefaultSingletonTraits<LocalSearchServiceFactory>;
+  friend struct base::DefaultSingletonTraits<LocalSearchServiceSyncFactory>;
 
-  LocalSearchServiceFactory();
-  ~LocalSearchServiceFactory() override;
+  LocalSearchServiceSyncFactory();
+  ~LocalSearchServiceSyncFactory() override;
 
-  LocalSearchServiceFactory(const LocalSearchServiceFactory&) = delete;
-  LocalSearchServiceFactory& operator=(const LocalSearchServiceFactory&) =
-      delete;
+  LocalSearchServiceSyncFactory(const LocalSearchServiceSyncFactory&) = delete;
+  LocalSearchServiceSyncFactory& operator=(
+      const LocalSearchServiceSyncFactory&) = delete;
 
   // BrowserContextKeyedServiceFactory overrides.
   content::BrowserContext* GetBrowserContextToUse(
@@ -42,4 +42,4 @@
 }  // namespace local_search_service
 }  // namespace chromeos
 
-#endif  // CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_LOCAL_SEARCH_SERVICE_FACTORY_H_
+#endif  // CHROMEOS_COMPONENTS_LOCAL_SEARCH_SERVICE_LOCAL_SEARCH_SERVICE_SYNC_FACTORY_H_
diff --git a/chromeos/components/local_search_service/local_search_service_sync_unittest.cc b/chromeos/components/local_search_service/local_search_service_sync_unittest.cc
new file mode 100644
index 0000000..e0749481
--- /dev/null
+++ b/chromeos/components/local_search_service/local_search_service_sync_unittest.cc
@@ -0,0 +1,46 @@
+// 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 <map>
+#include <set>
+#include <sstream>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/test/task_environment.h"
+#include "chromeos/components/local_search_service/index_sync.h"
+#include "chromeos/components/local_search_service/local_search_service_sync.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+namespace local_search_service {
+
+class LocalSearchServiceSyncTest : public testing::Test {
+ protected:
+  LocalSearchServiceSync service_;
+  base::test::TaskEnvironment task_environment_{
+      base::test::TaskEnvironment::MainThreadType::DEFAULT,
+      base::test::TaskEnvironment::ThreadPoolExecutionMode::QUEUED};
+};
+
+TEST_F(LocalSearchServiceSyncTest, GetLinearMapSearch) {
+  IndexSync* const index = service_.GetIndexSync(
+      IndexId::kCrosSettings, Backend::kLinearMap, nullptr /* local_state */);
+  CHECK(index);
+
+  EXPECT_EQ(index->GetSizeSync(), 0u);
+}
+
+TEST_F(LocalSearchServiceSyncTest, GetInvertedIndexSearch) {
+  IndexSync* const index =
+      service_.GetIndexSync(IndexId::kCrosSettings, Backend::kInvertedIndex,
+                            nullptr /* local_state */);
+  CHECK(index);
+
+  EXPECT_EQ(index->GetSizeSync(), 0u);
+}
+
+}  // namespace local_search_service
+}  // namespace chromeos
diff --git a/chromeos/components/local_search_service/local_search_service_unittest.cc b/chromeos/components/local_search_service/local_search_service_unittest.cc
deleted file mode 100644
index e857abd..0000000
--- a/chromeos/components/local_search_service/local_search_service_unittest.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// 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 <map>
-#include <set>
-#include <sstream>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/test/task_environment.h"
-#include "chromeos/components/local_search_service/index.h"
-#include "chromeos/components/local_search_service/local_search_service.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace chromeos {
-namespace local_search_service {
-
-class LocalSearchServiceTest : public testing::Test {
- protected:
-  LocalSearchService service_;
-  base::test::TaskEnvironment task_environment_{
-      base::test::TaskEnvironment::MainThreadType::DEFAULT,
-      base::test::TaskEnvironment::ThreadPoolExecutionMode::QUEUED};
-};
-
-TEST_F(LocalSearchServiceTest, GetLinearMapSearch) {
-  Index* const index = service_.GetIndex(
-      IndexId::kCrosSettings, Backend::kLinearMap, nullptr /* local_state */);
-  CHECK(index);
-
-  EXPECT_EQ(index->GetSize(), 0u);
-}
-
-TEST_F(LocalSearchServiceTest, GetInvertedIndexSearch) {
-  Index* const index =
-      service_.GetIndex(IndexId::kCrosSettings, Backend::kInvertedIndex,
-                        nullptr /* local_state */);
-  CHECK(index);
-
-  EXPECT_EQ(index->GetSize(), 0u);
-}
-
-}  // namespace local_search_service
-}  // namespace chromeos
diff --git a/chromeos/components/phonehub/BUILD.gn b/chromeos/components/phonehub/BUILD.gn
index c102f67..4ca1d6d7 100644
--- a/chromeos/components/phonehub/BUILD.gn
+++ b/chromeos/components/phonehub/BUILD.gn
@@ -45,6 +45,8 @@
     "message_sender.h",
     "message_sender_impl.cc",
     "message_sender_impl.h",
+    "multidevice_setup_state_updater.cc",
+    "multidevice_setup_state_updater.h",
     "mutable_phone_model.cc",
     "mutable_phone_model.h",
     "notification.cc",
@@ -170,6 +172,7 @@
     "find_my_device_controller_impl_unittest.cc",
     "message_receiver_unittest.cc",
     "message_sender_unittest.cc",
+    "multidevice_setup_state_updater_unittest.cc",
     "mutable_phone_model_unittest.cc",
     "notification_access_manager_impl_unittest.cc",
     "notification_manager_impl_unittest.cc",
diff --git a/chromeos/components/phonehub/multidevice_setup_state_updater.cc b/chromeos/components/phonehub/multidevice_setup_state_updater.cc
new file mode 100644
index 0000000..56574ad
--- /dev/null
+++ b/chromeos/components/phonehub/multidevice_setup_state_updater.cc
@@ -0,0 +1,95 @@
+// Copyright 2020 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 "chromeos/components/phonehub/multidevice_setup_state_updater.h"
+
+#include "chromeos/components/multidevice/logging/logging.h"
+#include "chromeos/components/phonehub/pref_names.h"
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/pref_service.h"
+
+namespace chromeos {
+namespace phonehub {
+namespace {
+using multidevice_setup::mojom::Feature;
+using multidevice_setup::mojom::HostStatus;
+}  // namespace
+
+// static
+void MultideviceSetupStateUpdater::RegisterPrefs(PrefRegistrySimple* registry) {
+  registry->RegisterBooleanPref(prefs::kIsAwaitingVerifiedHost, false);
+}
+
+MultideviceSetupStateUpdater::MultideviceSetupStateUpdater(
+    PrefService* pref_service,
+    multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client,
+    NotificationAccessManager* notification_access_manager)
+    : pref_service_(pref_service),
+      multidevice_setup_client_(multidevice_setup_client),
+      notification_access_manager_(notification_access_manager) {
+  multidevice_setup_client_->AddObserver(this);
+  notification_access_manager_->AddObserver(this);
+
+  const HostStatus host_status =
+      multidevice_setup_client_->GetHostStatus().first;
+  UpdateIsAwaitingVerifiedHost(host_status);
+}
+
+MultideviceSetupStateUpdater::~MultideviceSetupStateUpdater() {
+  multidevice_setup_client_->RemoveObserver(this);
+  notification_access_manager_->RemoveObserver(this);
+}
+
+void MultideviceSetupStateUpdater::OnNotificationAccessChanged() {
+  if (notification_access_manager_->HasAccessBeenGranted())
+    return;
+
+  PA_LOG(INFO) << "Disabling PhoneHubNotifications feature.";
+
+  // Disable kPhoneHubNotifications if notification access has been revoked by
+  // the phone.
+  multidevice_setup_client_->SetFeatureEnabledState(
+      Feature::kPhoneHubNotifications, /*enabled=*/false,
+      /*auth_token=*/base::nullopt, base::DoNothing());
+}
+
+void MultideviceSetupStateUpdater::OnHostStatusChanged(
+    const multidevice_setup::MultiDeviceSetupClient::HostStatusWithDevice&
+        host_device_with_status) {
+  const HostStatus host_status = host_device_with_status.first;
+
+  bool is_awaiting_verified_host =
+      pref_service_->GetBoolean(prefs::kIsAwaitingVerifiedHost);
+
+  // Enable the PhoneHub feature if phone is verified and there was an
+  // intent to enable the feature.
+  if (is_awaiting_verified_host && host_status == HostStatus::kHostVerified) {
+    multidevice_setup_client_->SetFeatureEnabledState(
+        Feature::kPhoneHub, /*enabled=*/true, /*auth_token=*/base::nullopt,
+        base::DoNothing());
+  }
+
+  UpdateIsAwaitingVerifiedHost(host_status);
+}
+
+void MultideviceSetupStateUpdater::UpdateIsAwaitingVerifiedHost(
+    HostStatus host_status) {
+  // Keep |prefs::kIsAwaitingVerifiedHost| at the same state.
+  if (host_status == HostStatus::kHostSetButNotYetVerified)
+    return;
+
+  // Begin waiting for a verified host if the phone is
+  // |kHostSetLocallyButWaitingForBackendConfirmation|.
+  bool is_awaiting_verified_host =
+      host_status ==
+      HostStatus::kHostSetLocallyButWaitingForBackendConfirmation;
+
+  // Must be persisted in the event that this class is destroyed
+  // before the phone is verified.
+  pref_service_->SetBoolean(prefs::kIsAwaitingVerifiedHost,
+                            is_awaiting_verified_host);
+}
+
+}  // namespace phonehub
+}  // namespace chromeos
diff --git a/chromeos/components/phonehub/multidevice_setup_state_updater.h b/chromeos/components/phonehub/multidevice_setup_state_updater.h
new file mode 100644
index 0000000..d5c7e628
--- /dev/null
+++ b/chromeos/components/phonehub/multidevice_setup_state_updater.h
@@ -0,0 +1,56 @@
+// Copyright 2020 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 CHROMEOS_COMPONENTS_PHONEHUB_MULTIDEVICE_SETUP_STATE_UPDATER_H_
+#define CHROMEOS_COMPONENTS_PHONEHUB_MULTIDEVICE_SETUP_STATE_UPDATER_H_
+
+#include "chromeos/components/phonehub/notification_access_manager.h"
+#include "chromeos/services/multidevice_setup/public/cpp/multidevice_setup_client.h"
+
+class PrefRegistrySimple;
+class PrefService;
+
+namespace chromeos {
+namespace phonehub {
+
+// This class enables the PhoneHub Multidevice feature state when the HostStatus
+// (provided by the MultideviceSetupClient) of the phone is initially
+// |kHostSetLocallyButWaitingForBackendConfirmation|, and becomes either 1)
+// |kHostVerified|, or 2) becomes |kHostSetButNotYetVerified| first, and then
+// later |kHostVerified|. This class also disables the PhoneHubNotification
+// Multidevice feature state when Notification access has been revoked by the
+// phone, provided via NotificationAccessManager.
+class MultideviceSetupStateUpdater
+    : public multidevice_setup::MultiDeviceSetupClient::Observer,
+      public NotificationAccessManager::Observer {
+ public:
+  static void RegisterPrefs(PrefRegistrySimple* registry);
+
+  MultideviceSetupStateUpdater(
+      PrefService* pref_service,
+      multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client,
+      NotificationAccessManager* notification_access_manager);
+  ~MultideviceSetupStateUpdater() override;
+
+ private:
+  // multidevice_setup::MultiDeviceSetupClient::Observer:
+  void OnHostStatusChanged(
+      const multidevice_setup::MultiDeviceSetupClient::HostStatusWithDevice&
+          host_device_with_status) override;
+
+  // NotificationAccessManager::Observer:
+  void OnNotificationAccessChanged() override;
+
+  void UpdateIsAwaitingVerifiedHost(
+      multidevice_setup::mojom::HostStatus host_status);
+
+  PrefService* pref_service_;
+  multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client_;
+  NotificationAccessManager* notification_access_manager_;
+};
+
+}  // namespace phonehub
+}  // namespace chromeos
+
+#endif  // CHROMEOS_COMPONENTS_PHONEHUB_MULTIDEVICE_SETUP_STATE_UPDATER_H_
diff --git a/chromeos/components/phonehub/multidevice_setup_state_updater_unittest.cc b/chromeos/components/phonehub/multidevice_setup_state_updater_unittest.cc
new file mode 100644
index 0000000..3233fe5e
--- /dev/null
+++ b/chromeos/components/phonehub/multidevice_setup_state_updater_unittest.cc
@@ -0,0 +1,99 @@
+// Copyright 2020 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 "chromeos/components/phonehub/multidevice_setup_state_updater.h"
+
+#include "chromeos/components/phonehub/fake_notification_access_manager.h"
+#include "chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup_client.h"
+#include "components/prefs/testing_pref_service.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+namespace phonehub {
+
+using multidevice_setup::mojom::Feature;
+using multidevice_setup::mojom::FeatureState;
+using multidevice_setup::mojom::HostStatus;
+
+class MultideviceSetupStateUpdaterTest : public testing::Test {
+ protected:
+  MultideviceSetupStateUpdaterTest() = default;
+  ~MultideviceSetupStateUpdaterTest() override = default;
+
+  MultideviceSetupStateUpdaterTest(const MultideviceSetupStateUpdaterTest&) =
+      delete;
+  MultideviceSetupStateUpdaterTest& operator=(
+      const MultideviceSetupStateUpdaterTest&) = delete;
+
+  // testing::Test:
+  void SetUp() override {
+    MultideviceSetupStateUpdater::RegisterPrefs(pref_service_.registry());
+
+    updater_ = std::make_unique<MultideviceSetupStateUpdater>(
+        &pref_service_, &fake_multidevice_setup_client_,
+        &fake_notification_access_manager_);
+  }
+
+  void SetNotififcationAccess(bool enabled) {
+    fake_notification_access_manager_.SetHasAccessBeenGrantedInternal(enabled);
+  }
+
+  void SetFeatureState(Feature feature, FeatureState feature_state) {
+    fake_multidevice_setup_client_.SetFeatureState(feature, feature_state);
+  }
+
+  void SetHostStatus(HostStatus host_status) {
+    fake_multidevice_setup_client_.SetHostStatusWithDevice(
+        std::make_pair(host_status, base::nullopt /* host_device */));
+  }
+
+  multidevice_setup::FakeMultiDeviceSetupClient*
+  fake_multidevice_setup_client() {
+    return &fake_multidevice_setup_client_;
+  }
+
+ private:
+  std::unique_ptr<MultideviceSetupStateUpdater> updater_;
+
+  TestingPrefServiceSimple pref_service_;
+  multidevice_setup::FakeMultiDeviceSetupClient fake_multidevice_setup_client_;
+  FakeNotificationAccessManager fake_notification_access_manager_;
+};
+
+TEST_F(MultideviceSetupStateUpdaterTest, EnablePhoneHub) {
+  // Test that there is a call to enable kPhoneHub when host status goes from
+  // kHostSetLocallyButWaitingForBackendConfirmation to kHostVerified.
+  SetHostStatus(HostStatus::kHostSetLocallyButWaitingForBackendConfirmation);
+  SetHostStatus(HostStatus::kHostVerified);
+  fake_multidevice_setup_client()->InvokePendingSetFeatureEnabledStateCallback(
+      /*expected_feature=*/Feature::kPhoneHub,
+      /*expected_enabled=*/true, /*expected_auth_token=*/base::nullopt,
+      /*success=*/true);
+
+  // Test that there is a call to enable kPhoneHub when host status goes from
+  // kHostSetLocallyButWaitingForBackendConfirmation to
+  // kHostSetButNotYetVerified, then finally to kHostVerified.
+  SetHostStatus(HostStatus::kHostSetLocallyButWaitingForBackendConfirmation);
+  SetHostStatus(HostStatus::kHostSetButNotYetVerified);
+  SetHostStatus(HostStatus::kHostVerified);
+  fake_multidevice_setup_client()->InvokePendingSetFeatureEnabledStateCallback(
+      /*expected_feature=*/Feature::kPhoneHub,
+      /*expected_enabled=*/true, /*expected_auth_token=*/base::nullopt,
+      /*success=*/true);
+}
+
+TEST_F(MultideviceSetupStateUpdaterTest, DisablePhoneHubNotifications) {
+  SetNotififcationAccess(true);
+
+  // Test that there is a call to disable kPhoneHubNotifications when
+  // notification access has been revoked.
+  SetNotififcationAccess(false);
+  fake_multidevice_setup_client()->InvokePendingSetFeatureEnabledStateCallback(
+      /*expected_feature=*/Feature::kPhoneHubNotifications,
+      /*expected_enabled=*/false, /*expected_auth_token=*/base::nullopt,
+      /*success=*/true);
+}
+
+}  // namespace phonehub
+}  // namespace chromeos
diff --git a/chromeos/components/phonehub/phone_hub_manager_impl.cc b/chromeos/components/phonehub/phone_hub_manager_impl.cc
index 9e84451..31455bbf 100644
--- a/chromeos/components/phonehub/phone_hub_manager_impl.cc
+++ b/chromeos/components/phonehub/phone_hub_manager_impl.cc
@@ -15,6 +15,7 @@
 #include "chromeos/components/phonehub/find_my_device_controller_impl.h"
 #include "chromeos/components/phonehub/message_receiver_impl.h"
 #include "chromeos/components/phonehub/message_sender_impl.h"
+#include "chromeos/components/phonehub/multidevice_setup_state_updater.h"
 #include "chromeos/components/phonehub/mutable_phone_model.h"
 #include "chromeos/components/phonehub/notification_access_manager_impl.h"
 #include "chromeos/components/phonehub/notification_manager_impl.h"
@@ -87,7 +88,12 @@
           std::make_unique<BrowserTabsModelController>(
               multidevice_setup_client,
               browser_tabs_model_provider_.get(),
-              phone_model_.get())) {}
+              phone_model_.get())),
+      multidevice_setup_state_updater_(
+          std::make_unique<MultideviceSetupStateUpdater>(
+              pref_service,
+              multidevice_setup_client,
+              notification_access_manager_.get())) {}
 
 PhoneHubManagerImpl::~PhoneHubManagerImpl() = default;
 
@@ -130,6 +136,7 @@
 // These should be destroyed in the opposite order of how these objects are
 // initialized in the constructor.
 void PhoneHubManagerImpl::Shutdown() {
+  multidevice_setup_state_updater_.reset();
   browser_tabs_model_controller_.reset();
   browser_tabs_model_provider_.reset();
   tether_controller_.reset();
diff --git a/chromeos/components/phonehub/phone_hub_manager_impl.h b/chromeos/components/phonehub/phone_hub_manager_impl.h
index e56f794a..d2baf9a 100644
--- a/chromeos/components/phonehub/phone_hub_manager_impl.h
+++ b/chromeos/components/phonehub/phone_hub_manager_impl.h
@@ -35,6 +35,7 @@
 class CrosStateSender;
 class MessageSender;
 class MessageReceiver;
+class MultideviceSetupStateUpdater;
 class MutablePhoneModel;
 class PhoneStatusProcessor;
 
@@ -82,6 +83,8 @@
   std::unique_ptr<TetherController> tether_controller_;
   std::unique_ptr<BrowserTabsModelProvider> browser_tabs_model_provider_;
   std::unique_ptr<BrowserTabsModelController> browser_tabs_model_controller_;
+  std::unique_ptr<MultideviceSetupStateUpdater>
+      multidevice_setup_state_updater_;
 };
 
 }  // namespace phonehub
diff --git a/chromeos/components/phonehub/pref_names.cc b/chromeos/components/phonehub/pref_names.cc
index 9c7cc83..0170d0e 100644
--- a/chromeos/components/phonehub/pref_names.cc
+++ b/chromeos/components/phonehub/pref_names.cc
@@ -16,6 +16,11 @@
 const char kHasDismissedUiAfterCompletingOnboarding[] =
     "cros.phonehub.has_completed_onboarding_before";
 
+// Whether the MultideviceSetupStateUpdater is waiting for a verified host
+// in order to enable the Multidevice PhoneHub feature.
+const char kIsAwaitingVerifiedHost[] =
+    "cros.phonehub.is_awaiting_verified_host";
+
 }  // namespace prefs
 }  // namespace phonehub
 }  // namespace chromeos
diff --git a/chromeos/components/phonehub/pref_names.h b/chromeos/components/phonehub/pref_names.h
index 3e9f7ae..c43d09a 100644
--- a/chromeos/components/phonehub/pref_names.h
+++ b/chromeos/components/phonehub/pref_names.h
@@ -11,6 +11,7 @@
 
 extern const char kNotificationAccessGranted[];
 extern const char kHasDismissedUiAfterCompletingOnboarding[];
+extern const char kIsAwaitingVerifiedHost[];
 
 }  // namespace prefs
 }  // namespace phonehub
diff --git a/chromeos/components/scanning/mojom/scanning.mojom b/chromeos/components/scanning/mojom/scanning.mojom
index 22375dc..3724f43 100644
--- a/chromeos/components/scanning/mojom/scanning.mojom
+++ b/chromeos/components/scanning/mojom/scanning.mojom
@@ -14,6 +14,13 @@
   kColor,
 };
 
+// The file types that can be used when saving scanned images.
+enum FileType {
+  kJpg,
+  kPdf,
+  kPng,
+};
+
 // The source types from which a scan can be obtained.
 enum SourceType {
   // An unknown source type.
@@ -49,6 +56,8 @@
 struct ScanSettings {
   // The SANE name of the ScanSource from which to scan.
   string source_name;
+  // The file type to use when saving scanned images.
+  FileType file_type;
   // The color mode with which to scan.
   ColorMode color_mode;
   // The resolution with which to scan in DPI.
diff --git a/chromeos/components/scanning/resources/scanning_app.js b/chromeos/components/scanning/resources/scanning_app.js
index b87ff7e6..5125b6f 100644
--- a/chromeos/components/scanning/resources/scanning_app.js
+++ b/chromeos/components/scanning/resources/scanning_app.js
@@ -172,8 +172,11 @@
     this.settingsDisabled_ = true;
     this.scanButtonDisabled_ = true;
 
+    // TODO(jschettler): Set file type using the selected value when the
+    // corresponding dropdown is added.
     const settings = {
       'sourceName': this.selectedSource,
+      'fileType': chromeos.scanning.mojom.FileType.kPng,
       'colorMode': this.selectedColorMode,
       'resolutionDpi': this.selectedResolution,
     };
diff --git a/chromeos/components/sensors/mojom/sensor.mojom b/chromeos/components/sensors/mojom/sensor.mojom
index 299b973..4112cfb 100644
--- a/chromeos/components/sensors/mojom/sensor.mojom
+++ b/chromeos/components/sensors/mojom/sensor.mojom
@@ -75,7 +75,12 @@
   // Returns base::nullopt if the attribute cannot be read.
   GetAttribute@1(string attr_name) => (string? value);
 
-  // Sets the frequency of the device before starting to read samples.
+  // Sets the frequency in Hz of the device before starting to read samples.
+  // If no frequency or an invalid frequency is set, an
+  // ObserverErrorType::FREQUENCY_INVALID error will occur after calling
+  // |StartReadingSamples|.
+  // After starting to read samples, the client can set the frequency to 0 to
+  // pause the reading, and set a valid frequency later to resume the reading.
   // |result_freq| would be the frequency set by iioservice for the client.
   SetFrequency@2(double frequency) => (double result_freq);
 
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc
index 31eb31c..33c8cbe 100644
--- a/chromeos/constants/chromeos_features.cc
+++ b/chromeos/constants/chromeos_features.cc
@@ -400,7 +400,7 @@
 
 // Enables or disables language settings update.
 const base::Feature kLanguageSettingsUpdate{"LanguageSettingsUpdate",
-                                            base::FEATURE_DISABLED_BY_DEFAULT};
+                                            base::FEATURE_ENABLED_BY_DEFAULT};
 
 // Enables or disables device management disclosure on login / lock screen.
 const base::Feature kLoginDeviceManagementDisclosure{
diff --git a/chromeos/dbus/cros_healthd/fake_cros_healthd_service.cc b/chromeos/dbus/cros_healthd/fake_cros_healthd_service.cc
index 484a01d..7b8dee6 100644
--- a/chromeos/dbus/cros_healthd/fake_cros_healthd_service.cc
+++ b/chromeos/dbus/cros_healthd/fake_cros_healthd_service.cc
@@ -222,6 +222,11 @@
   std::move(callback).Run(run_routine_response_.Clone());
 }
 
+void FakeCrosHealthdService::RunHasSecureWiFiConnectionRoutine(
+    RunHasSecureWiFiConnectionRoutineCallback callback) {
+  std::move(callback).Run(run_routine_response_.Clone());
+}
+
 void FakeCrosHealthdService::AddBluetoothObserver(
     mojom::CrosHealthdBluetoothObserverPtr observer) {
   bluetooth_observers_.Add(observer.PassInterface());
diff --git a/chromeos/dbus/cros_healthd/fake_cros_healthd_service.h b/chromeos/dbus/cros_healthd/fake_cros_healthd_service.h
index cccdb60..b01a0d8 100644
--- a/chromeos/dbus/cros_healthd/fake_cros_healthd_service.h
+++ b/chromeos/dbus/cros_healthd/fake_cros_healthd_service.h
@@ -104,6 +104,8 @@
       RunSignalStrengthRoutineCallback callback) override;
   void RunGatewayCanBePingedRoutine(
       RunGatewayCanBePingedRoutineCallback callback) override;
+  void RunHasSecureWiFiConnectionRoutine(
+      RunHasSecureWiFiConnectionRoutineCallback callback) override;
 
   // CrosHealthdEventService overrides:
   void AddBluetoothObserver(
diff --git a/chromeos/services/chromebox_for_meetings/public/cpp/service_connection.cc b/chromeos/services/chromebox_for_meetings/public/cpp/service_connection.cc
index 7a904523..3902677 100644
--- a/chromeos/services/chromebox_for_meetings/public/cpp/service_connection.cc
+++ b/chromeos/services/chromebox_for_meetings/public/cpp/service_connection.cc
@@ -53,10 +53,9 @@
       const std::string& interface_name,
       mojo::PendingRemote<mojom::CfmServiceAdaptor> adaptor_remote,
       ProvideAdaptorCallback callback) override;
-  void BindRegistry(
-      const std::string& interface_name,
-      mojo::PendingReceiver<mojom::CfmServiceRegistry> broker_receiver,
-      BindRegistryCallback callback) override;
+  void RequestBindService(const std::string& interface_name,
+                          mojo::ScopedMessagePipeHandle receiver_pipe,
+                          RequestBindServiceCallback callback) override;
 
   void OnMojoConnectionError();
 
@@ -154,14 +153,14 @@
                           std::move(callback));
 }
 
-void ServiceConnectionImpl::BindRegistry(
+void ServiceConnectionImpl::RequestBindService(
     const std::string& interface_name,
-    mojo::PendingReceiver<mojom::CfmServiceRegistry> broker_receiver,
-    BindRegistryCallback callback) {
+    mojo::ScopedMessagePipeHandle receiver_pipe,
+    RequestBindServiceCallback callback) {
   BindPlatformServiceContextIfNeeded();
 
-  remote_->BindRegistry(std::move(interface_name), std::move(broker_receiver),
-                        std::move(callback));
+  remote_->RequestBindService(std::move(interface_name),
+                              std::move(receiver_pipe), std::move(callback));
 }
 
 void ServiceConnectionImpl::OnMojoConnectionError() {
diff --git a/chromeos/services/chromebox_for_meetings/public/mojom/README.md b/chromeos/services/chromebox_for_meetings/public/mojom/README.md
index 6c52062..39873e8 100644
--- a/chromeos/services/chromebox_for_meetings/public/mojom/README.md
+++ b/chromeos/services/chromebox_for_meetings/public/mojom/README.md
@@ -1,5 +1,5 @@
 These mojoms are for a service that exists outside of chromium. Implementation
-for CfmServiceContext and CfmServiceRegistry are found in the private CrOS repo.
+for CfmServiceContext are found in the private CrOS repo.
 
 Note: //chromeos/services/chromebox_for_meetings/public/mojom/cfm_service_manager.mojom
 is copied as is from its chromeos version as such the original file should be
diff --git a/chromeos/services/chromebox_for_meetings/public/mojom/cfm_service_manager.mojom b/chromeos/services/chromebox_for_meetings/public/mojom/cfm_service_manager.mojom
index 35a155d9..9ecbae5 100644
--- a/chromeos/services/chromebox_for_meetings/public/mojom/cfm_service_manager.mojom
+++ b/chromeos/services/chromebox_for_meetings/public/mojom/cfm_service_manager.mojom
@@ -17,20 +17,10 @@
       string interface_name,
       pending_remote<CfmServiceAdaptor> adaptor_remote) => (bool success);
 
-  // Request to bind |CfmServiceRegistry| requests assuming a valid
-  // |interface_name| is given.
-  // Note: |interface_name| MUST be the interface name, i.e. Interface::Name_
-  BindRegistry@1(
-    string interface_name,
-    pending_receiver<CfmServiceRegistry> registry_receiver) => (bool success);
-};
-
-// Interface used to bind to registered interfaces by name
-interface CfmServiceRegistry {
   // Attempt to bind the |receiver_pipe| of an intended mojo::Receiver
   // to a remote service that is internally identified as |interface_name|
   // Note: |interface_name| MUST be the interface name, i.e. Interface::Name_
-  RequestBindService@0(
+  RequestBindService@1(
       string interface_name,
       handle<message_pipe> receiver_pipe) => (bool success);
 };
@@ -47,5 +37,5 @@
   // FooImpl assuming FooImpl also implements the CfmServiceAdaptor.
   // Note: Ideally services should handle multiple clients (i.e BindingSet)
   // unless explicitly stated.
-  BindService@0(handle<message_pipe> receiver_pipe);
+  OnBindService@0(handle<message_pipe> receiver_pipe);
 };
diff --git a/chromeos/services/cros_healthd/public/cpp/service_connection.cc b/chromeos/services/cros_healthd/public/cpp/service_connection.cc
index 1fc72dc..d8ba75f 100644
--- a/chromeos/services/cros_healthd/public/cpp/service_connection.cc
+++ b/chromeos/services/cros_healthd/public/cpp/service_connection.cc
@@ -113,6 +113,9 @@
   void RunGatewayCanBePingedRoutine(
       mojom::CrosHealthdDiagnosticsService::RunGatewayCanBePingedRoutineCallback
           callback) override;
+  void RunHasSecureWiFiConnectionRoutine(
+      mojom::CrosHealthdDiagnosticsService::
+          RunHasSecureWiFiConnectionRoutineCallback callback) override;
   void AddBluetoothObserver(
       mojo::PendingRemote<mojom::CrosHealthdBluetoothObserver> pending_observer)
       override;
@@ -389,6 +392,15 @@
       std::move(callback));
 }
 
+void ServiceConnectionImpl::RunHasSecureWiFiConnectionRoutine(
+    mojom::CrosHealthdDiagnosticsService::
+        RunHasSecureWiFiConnectionRoutineCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  BindCrosHealthdDiagnosticsServiceIfNeeded();
+  cros_healthd_diagnostics_service_->RunHasSecureWiFiConnectionRoutine(
+      std::move(callback));
+}
+
 void ServiceConnectionImpl::AddBluetoothObserver(
     mojo::PendingRemote<mojom::CrosHealthdBluetoothObserver> pending_observer) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/chromeos/services/cros_healthd/public/cpp/service_connection.h b/chromeos/services/cros_healthd/public/cpp/service_connection.h
index 93a1396..034fcd68 100644
--- a/chromeos/services/cros_healthd/public/cpp/service_connection.h
+++ b/chromeos/services/cros_healthd/public/cpp/service_connection.h
@@ -200,6 +200,13 @@
       mojom::CrosHealthdDiagnosticsService::RunGatewayCanBePingedRoutineCallback
           callback) = 0;
 
+  // Requests that cros_healthd runs the has secure wifi routine. See
+  // src/chromeos/service/cros_healthd/public/mojom/cros_healthd.mojom for
+  // details.
+  virtual void RunHasSecureWiFiConnectionRoutine(
+      mojom::CrosHealthdDiagnosticsService::
+          RunHasSecureWiFiConnectionRoutineCallback callback) = 0;
+
   // Subscribes to cros_healthd's Bluetooth-related events. See
   // src/chromeos/services/cros_healthd/public/mojom/cros_healthd.mojom for
   // details.
diff --git a/chromeos/services/cros_healthd/public/cpp/service_connection_unittest.cc b/chromeos/services/cros_healthd/public/cpp/service_connection_unittest.cc
index 1ab654d..6427fb9 100644
--- a/chromeos/services/cros_healthd/public/cpp/service_connection_unittest.cc
+++ b/chromeos/services/cros_healthd/public/cpp/service_connection_unittest.cc
@@ -562,6 +562,19 @@
   run_loop.Run();
 }
 
+// Test that we can run the has secure wifi connection routine.
+TEST_F(CrosHealthdServiceConnectionTest, RunHasSecureWiFiConnectionRoutine) {
+  auto response = MakeRunRoutineResponse();
+  FakeCrosHealthdClient::Get()->SetRunRoutineResponseForTesting(response);
+  base::RunLoop run_loop;
+  ServiceConnection::GetInstance()->RunHasSecureWiFiConnectionRoutine(
+      base::BindLambdaForTesting([&](mojom::RunRoutineResponsePtr response) {
+        EXPECT_EQ(response, MakeRunRoutineResponse());
+        run_loop.Quit();
+      }));
+  run_loop.Run();
+}
+
 // Test that we can add a Bluetooth observer.
 TEST_F(CrosHealthdServiceConnectionTest, AddBluetoothObserver) {
   MockCrosHealthdBluetoothObserver observer;
diff --git a/chromeos/services/cros_healthd/public/mojom/cros_healthd.mojom b/chromeos/services/cros_healthd/public/mojom/cros_healthd.mojom
index 6e1e0a2..e2c274db 100644
--- a/chromeos/services/cros_healthd/public/mojom/cros_healthd.mojom
+++ b/chromeos/services/cros_healthd/public/mojom/cros_healthd.mojom
@@ -336,6 +336,17 @@
   // * |response| - contains a unique identifier and status for the created
   //                routine.
   RunGatewayCanBePingedRoutine() => (RunRoutineResponse response);
+
+  // Requests that the HasSecureWiFiConnection routine is created and started
+  // on the platform. This routine checks whether the WiFi connection is
+  // secure. Note that if WiFi is not connected, the routine will not run. This
+  // routine is only available if GetAvailableRoutines returned
+  // kHasSecureWiFiConnection.
+  //
+  // The response:
+  // * |response| - contains a unique identifier and status for the created
+  //                routine.
+  RunHasSecureWiFiConnectionRoutine() => (RunRoutineResponse response);
 };
 
 // Event interface exposed by the cros_healthd daemon.
diff --git a/chromeos/services/cros_healthd/public/mojom/cros_healthd_diagnostics.mojom b/chromeos/services/cros_healthd/public/mojom/cros_healthd_diagnostics.mojom
index 29768c20..658750bf 100644
--- a/chromeos/services/cros_healthd/public/mojom/cros_healthd_diagnostics.mojom
+++ b/chromeos/services/cros_healthd/public/mojom/cros_healthd_diagnostics.mojom
@@ -34,6 +34,7 @@
   kLanConnectivity = 15,
   kSignalStrength = 16,
   kGatewayCanBePinged = 17,
+  kHasSecureWiFiConnection = 18,
 };
 
 // Enumeration of the possible DiskRead routine's command type
diff --git a/chromeos/services/multidevice_setup/feature_state_manager_impl_unittest.cc b/chromeos/services/multidevice_setup/feature_state_manager_impl_unittest.cc
index 5ba06a1..e6707602 100644
--- a/chromeos/services/multidevice_setup/feature_state_manager_impl_unittest.cc
+++ b/chromeos/services/multidevice_setup/feature_state_manager_impl_unittest.cc
@@ -489,6 +489,9 @@
   VerifyFeatureStateChange(1u /* expected_index */, mojom::Feature::kPhoneHub,
                            mojom::FeatureState::kNotSupportedByPhone);
 
+  // This pref should is disabled for existing Better Together users;
+  // they must go to settings to explicitly enable PhoneHub.
+  test_pref_service()->SetBoolean(kPhoneHubEnabledPrefName, true);
   SetSoftwareFeatureState(false /* use_local_device */,
                           multidevice::SoftwareFeature::kPhoneHubHost,
                           multidevice::SoftwareFeatureState::kEnabled);
diff --git a/chromeos/services/multidevice_setup/public/cpp/prefs.cc b/chromeos/services/multidevice_setup/public/cpp/prefs.cc
index dfc9a39..162706c 100644
--- a/chromeos/services/multidevice_setup/public/cpp/prefs.cc
+++ b/chromeos/services/multidevice_setup/public/cpp/prefs.cc
@@ -55,7 +55,10 @@
   registry->RegisterBooleanPref(kMessagesEnabledPrefName, true);
   registry->RegisterBooleanPref(kSmartLockEnabledDeprecatedPrefName, true);
   registry->RegisterBooleanPref(kSmartLockEnabledPrefName, true);
-  registry->RegisterBooleanPref(kPhoneHubEnabledPrefName, true);
+
+  // This pref should be disabled for existing Better Together users;
+  // they must go to settings to explicitly enable PhoneHub.
+  registry->RegisterBooleanPref(kPhoneHubEnabledPrefName, false);
   registry->RegisterBooleanPref(kPhoneHubNotificationsEnabledPrefName, true);
   registry->RegisterBooleanPref(kPhoneHubTaskContinuationEnabledPrefName, true);
 }
diff --git a/components/exo/shell_surface.cc b/components/exo/shell_surface.cc
index 901e261..6d738eb 100644
--- a/components/exo/shell_surface.cc
+++ b/components/exo/shell_surface.cc
@@ -501,32 +501,28 @@
 ////////////////////////////////////////////////////////////////////////////////
 // ShellSurface, private:
 
-void ShellSurface::SetParentWindow(aura::Window* parent) {
-  if (parent_) {
-    parent_->RemoveObserver(this);
+void ShellSurface::SetParentWindow(aura::Window* new_parent) {
+  if (parent()) {
+    parent()->RemoveObserver(this);
     if (widget_) {
       aura::Window* child_window = widget_->GetNativeWindow();
       wm::TransientWindowManager::GetOrCreate(child_window)
           ->set_parent_controls_visibility(false);
-      wm::RemoveTransientChild(parent_, child_window);
+      wm::RemoveTransientChild(parent(), child_window);
     }
   }
-  parent_ = parent;
-  if (parent_) {
-    parent_->AddObserver(this);
+  SetParentInternal(new_parent);
+  if (parent()) {
+    parent()->AddObserver(this);
     MaybeMakeTransient();
   }
-
-  // If |parent_| is set effects the ability to maximize the window.
-  if (widget_)
-    widget_->OnSizeConstraintsChanged();
 }
 
 void ShellSurface::MaybeMakeTransient() {
-  if (!parent_ || !widget_)
+  if (!parent() || !widget_)
     return;
   aura::Window* child_window = widget_->GetNativeWindow();
-  wm::AddTransientChild(parent_, child_window);
+  wm::AddTransientChild(parent(), child_window);
   // In the case of activatable non-popups, we also want the parent to control
   // the child's visibility.
   if (!widget_->is_top_level() || !widget_->CanActivate())
diff --git a/components/exo/shell_surface_base.cc b/components/exo/shell_surface_base.cc
index d4f38b2..4367cbc 100644
--- a/components/exo/shell_surface_base.cc
+++ b/components/exo/shell_surface_base.cc
@@ -323,6 +323,9 @@
   host_window()->Show();
   set_owned_by_client();
 
+  SetCanMinimize(can_minimize_);
+  SetCanMaximize(ash::desks_util::IsDeskContainerId(container_));
+  SetCanResize(true);
   SetShowTitle(false);
 }
 
@@ -483,8 +486,7 @@
 
 void ShellSurfaceBase::SetContainer(int container) {
   TRACE_EVENT1("exo", "ShellSurfaceBase::SetContainer", "container", container);
-
-  container_ = container;
+  SetContainerInternal(container);
 }
 
 void ShellSurfaceBase::SetMaximumSize(const gfx::Size& size) {
@@ -513,10 +515,12 @@
                can_minimize);
 
   can_minimize_ = can_minimize;
+  WidgetDelegate::SetCanMinimize(!parent_ && can_minimize_);
 }
 
 void ShellSurfaceBase::DisableMovement() {
   movement_disabled_ = true;
+  SetCanResize(false);
 
   if (widget_)
     widget_->set_movement_disabled(true);
@@ -677,28 +681,6 @@
 ////////////////////////////////////////////////////////////////////////////////
 // views::WidgetDelegate overrides:
 
-bool ShellSurfaceBase::CanResize() const {
-  if (movement_disabled_)
-    return false;
-  // The shell surface is resizable by default when min/max size is empty,
-  // othersize it's resizable when min size != max size.
-  return minimum_size_.IsEmpty() || minimum_size_ != maximum_size_;
-}
-
-bool ShellSurfaceBase::CanMaximize() const {
-  // Shell surfaces in system modal container cannot be maximized.
-  if (!ash::desks_util::IsDeskContainerId(container_))
-    return false;
-
-  // Non-transient shell surfaces can be maximized.
-  return !parent_;
-}
-
-bool ShellSurfaceBase::CanMinimize() const {
-  // Non-transient shell surfaces can be minimized.
-  return !parent_ && can_minimize_;
-}
-
 bool ShellSurfaceBase::OnCloseRequested(
     views::Widget::ClosedReason close_reason) {
   if (!pre_close_callback_.is_null())
@@ -834,12 +816,8 @@
 // aura::WindowObserver overrides:
 
 void ShellSurfaceBase::OnWindowDestroying(aura::Window* window) {
-  if (window == parent_) {
-    parent_ = nullptr;
-    // |parent_| being set to null effects the ability to maximize the window.
-    if (widget_)
-      widget_->OnSizeConstraintsChanged();
-  }
+  if (window == parent_)
+    SetParentInternal(nullptr);
   window->RemoveObserver(this);
 }
 
@@ -903,7 +881,7 @@
     // override redirect is used for menu, tooltips etc, which should be placed
     // above normal windows, but below lock screen. Specify the container here
     // to avoid using parent_ in params.parent.
-    container_ = ash::kShellWindowId_ShelfBubbleContainer;
+    SetContainerInternal(ash::kShellWindowId_ShelfBubbleContainer);
     // X11 override redirect should not be activatable.
     activatable_ = false;
     DisableMovement();
@@ -1140,6 +1118,23 @@
   shadow_bounds_changed_ = false;
 }
 
+void ShellSurfaceBase::SetContainerInternal(int container) {
+  container_ = container;
+  WidgetDelegate::SetCanMaximize(
+      !parent_ && ash::desks_util::IsDeskContainerId(container_));
+  if (widget_)
+    widget_->OnSizeConstraintsChanged();
+}
+
+void ShellSurfaceBase::SetParentInternal(aura::Window* parent) {
+  parent_ = parent;
+  WidgetDelegate::SetCanMinimize(!parent_ && can_minimize_);
+  WidgetDelegate::SetCanMaximize(
+      !parent_ && ash::desks_util::IsDeskContainerId(container_));
+  if (widget_)
+    widget_->OnSizeConstraintsChanged();
+}
+
 void ShellSurfaceBase::CommitWidget() {
   // Apply new window geometry.
   geometry_ = pending_geometry_;
@@ -1150,6 +1145,8 @@
                                  maximum_size_ != pending_maximum_size_;
   minimum_size_ = pending_minimum_size_;
   maximum_size_ = pending_maximum_size_;
+  SetCanResize(!movement_disabled_ &&
+               (minimum_size_.IsEmpty() || minimum_size_ != maximum_size_));
 
   if (!widget_)
     return;
diff --git a/components/exo/shell_surface_base.h b/components/exo/shell_surface_base.h
index b8f67fc..3ff7114 100644
--- a/components/exo/shell_surface_base.h
+++ b/components/exo/shell_surface_base.h
@@ -156,9 +156,6 @@
                         aura::Window* gained_capture) override;
 
   // views::WidgetDelegate:
-  bool CanResize() const override;
-  bool CanMaximize() const override;
-  bool CanMinimize() const override;
   bool OnCloseRequested(views::Widget::ClosedReason close_reason) override;
   void WindowClosing() override;
   views::Widget* GetWidget() override;
@@ -242,6 +239,7 @@
   void StartCapture();
 
   const gfx::Rect& geometry() const { return geometry_; }
+  aura::Window* parent() const { return parent_; }
 
   // Install custom window targeter. Used to restore window targeter.
   void InstallCustomWindowTargeter();
@@ -253,8 +251,10 @@
 
   virtual void OnPostWidgetCommit();
 
+  void SetParentInternal(aura::Window* window);
+  void SetContainerInternal(int container);
+
   views::Widget* widget_ = nullptr;
-  aura::Window* parent_ = nullptr;
   bool movement_disabled_ = false;
   gfx::Point origin_;
 
@@ -291,6 +291,7 @@
 
   void CommitWidget();
 
+  aura::Window* parent_ = nullptr;
   bool activatable_ = true;
   bool can_minimize_ = true;
   bool has_frame_colors_ = false;
diff --git a/components/media_router/browser/android/BUILD.gn b/components/media_router/browser/android/BUILD.gn
index de523d7..b4f30e9 100644
--- a/components/media_router/browser/android/BUILD.gn
+++ b/components/media_router/browser/android/BUILD.gn
@@ -168,7 +168,6 @@
     "java/res/drawable/ic_cast_dark_chrome.xml",
     "java/res/layout/caf_controller_media_route_button.xml",
     "java/res/layout/expanded_cast_controller.xml",
-    "java/res/values/ids.xml",
     "java/res/values/styles.xml",
   ]
   deps = [
diff --git a/components/media_router/browser/android/java/res/values/ids.xml b/components/media_router/browser/android/java/res/values/ids.xml
deleted file mode 100644
index 71f611b..0000000
--- a/components/media_router/browser/android/java/res/values/ids.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!-- Copyright 2020 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.
--->
-
-<resources>
-    <!-- RemotePlayback API notification -->
-    <item type="id" name="remote_notification" />
-
-    <!-- Presentation API notification -->
-    <item type="id" name="presentation_notification" />
-</resources>
diff --git a/components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaRouterClient.java b/components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaRouterClient.java
index 10c2464..99a0ee4 100644
--- a/components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaRouterClient.java
+++ b/components/media_router/browser/android/java/src/org/chromium/components/media_router/MediaRouterClient.java
@@ -49,6 +49,12 @@
      */
     public abstract void showNotification(MediaNotificationInfo notificationInfo);
 
+    /** Returns the ID to be used for Presentation API notifications. */
+    public abstract int getPresentationNotificationId();
+
+    /** Returns the ID to be used for Remote Playback API notifications. */
+    public abstract int getRemotingNotificationId();
+
     /**
      * @param initiator the web contents that initiated the request.
      * @return a {@link FragmentManager} suitable for displaying a media router {@link
diff --git a/components/media_router/browser/android/java/src/org/chromium/components/media_router/TestMediaRouterClient.java b/components/media_router/browser/android/java/src/org/chromium/components/media_router/TestMediaRouterClient.java
index 22d5dc8..580a72e 100644
--- a/components/media_router/browser/android/java/src/org/chromium/components/media_router/TestMediaRouterClient.java
+++ b/components/media_router/browser/android/java/src/org/chromium/components/media_router/TestMediaRouterClient.java
@@ -32,6 +32,16 @@
     public void showNotification(MediaNotificationInfo notificationInfo) {}
 
     @Override
+    public int getPresentationNotificationId() {
+        return 2;
+    }
+
+    @Override
+    public int getRemotingNotificationId() {
+        return 3;
+    }
+
+    @Override
     public FragmentManager getSupportFragmentManager(WebContents initiator) {
         return null;
     }
diff --git a/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/CafNotificationController.java b/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/CafNotificationController.java
index 16e0683..c4aeb8f 100644
--- a/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/CafNotificationController.java
+++ b/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/CafNotificationController.java
@@ -7,7 +7,7 @@
 import android.content.Intent;
 
 import org.chromium.components.browser_ui.media.MediaNotificationUma;
-import org.chromium.components.media_router.R;
+import org.chromium.components.media_router.MediaRouterClient;
 
 /** NotificationController implementation for presentation. */
 public class CafNotificationController extends BaseNotificationController {
@@ -28,6 +28,6 @@
 
     @Override
     public int getNotificationId() {
-        return R.id.presentation_notification;
+        return MediaRouterClient.getInstance().getPresentationNotificationId();
     }
 }
diff --git a/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/remoting/RemotingNotificationController.java b/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/remoting/RemotingNotificationController.java
index 61ddc3a..f59229ec 100644
--- a/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/remoting/RemotingNotificationController.java
+++ b/components/media_router/browser/android/java/src/org/chromium/components/media_router/caf/remoting/RemotingNotificationController.java
@@ -8,7 +8,7 @@
 
 import org.chromium.base.ContextUtils;
 import org.chromium.components.browser_ui.media.MediaNotificationUma;
-import org.chromium.components.media_router.R;
+import org.chromium.components.media_router.MediaRouterClient;
 import org.chromium.components.media_router.caf.BaseNotificationController;
 import org.chromium.components.media_router.caf.BaseSessionController;
 
@@ -30,6 +30,6 @@
 
     @Override
     public int getNotificationId() {
-        return R.id.remote_notification;
+        return MediaRouterClient.getInstance().getRemotingNotificationId();
     }
 }
diff --git a/components/sync/driver/sync_service_utils.cc b/components/sync/driver/sync_service_utils.cc
index c33fb5b..f62a104 100644
--- a/components/sync/driver/sync_service_utils.cc
+++ b/components/sync/driver/sync_service_utils.cc
@@ -71,10 +71,6 @@
   return UploadState::NOT_ACTIVE;
 }
 
-void RecordSyncEvent(SyncEventCodes code) {
-  UMA_HISTOGRAM_ENUMERATION("Sync.EventCodes", code, MAX_SYNC_EVENT_CODE);
-}
-
 void RecordKeyRetrievalTrigger(KeyRetrievalTriggerForUMA trigger) {
   base::UmaHistogramEnumeration("Sync.TrustedVaultKeyRetrievalTrigger",
                                 trigger);
diff --git a/components/sync/driver/sync_service_utils.h b/components/sync/driver/sync_service_utils.h
index 3265b9c..debadd0 100644
--- a/components/sync/driver/sync_service_utils.h
+++ b/components/sync/driver/sync_service_utils.h
@@ -37,29 +37,6 @@
   kMaxValue = ACTIVE
 };
 
-// NOTE: Used in a UMA histogram, do not reorder etc.
-enum SyncEventCodes {
-  // Events starting the sync service.
-  // START_FROM_NTP = 1,
-  // START_FROM_WRENCH = 2,
-  // START_FROM_OPTIONS = 3,
-  // START_FROM_BOOKMARK_MANAGER = 4,
-  // START_FROM_PROFILE_MENU = 5,
-  // START_FROM_URL = 6,
-
-  // Events regarding cancellation of the signon process of sync.
-  // CANCEL_FROM_SIGNON_WITHOUT_AUTH = 10,
-  // CANCEL_DURING_SIGNON = 11,
-  CANCEL_DURING_CONFIGURE = 12,  // Cancelled before choosing data types and
-                                 // clicking OK.
-
-  // Events resulting in the stoppage of sync service.
-  STOP_FROM_OPTIONS = 20,  // Sync was stopped from Wrench->Options.
-  // STOP_FROM_ADVANCED_DIALOG = 21,
-
-  MAX_SYNC_EVENT_CODE = 22
-};
-
 // Used for UMA histogram, do not reorder. Represents the UI elements which
 // contain trusted vault error button.
 // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.sync
@@ -83,8 +60,6 @@
 UploadState GetUploadToGoogleState(const SyncService* sync_service,
                                    ModelType type);
 
-void RecordSyncEvent(SyncEventCodes code);
-
 void RecordKeyRetrievalTrigger(KeyRetrievalTriggerForUMA trigger);
 
 }  // namespace syncer
diff --git a/components/viz/demo/BUILD.gn b/components/viz/demo/BUILD.gn
index f3fe9d9c..4688919b 100644
--- a/components/viz/demo/BUILD.gn
+++ b/components/viz/demo/BUILD.gn
@@ -55,6 +55,7 @@
 
   deps = [
     "//base",
+    "//base:base_static",
     "//base:i18n",
     "//build/win:default_exe_manifest",
     "//components/viz/demo:host",
diff --git a/components/viz/demo/demo_main.cc b/components/viz/demo/demo_main.cc
index a24f3c36d..ab1ad202 100644
--- a/components/viz/demo/demo_main.cc
+++ b/components/viz/demo/demo_main.cc
@@ -5,6 +5,7 @@
 #include <utility>
 
 #include "base/at_exit.h"
+#include "base/base_switches.h"
 #include "base/command_line.h"
 #include "base/i18n/icu_util.h"
 #include "base/macros.h"
@@ -27,7 +28,9 @@
 #include "ui/platform_window/platform_window_init_properties.h"
 
 #if defined(USE_OZONE)
+#include "ui/ozone/public/ozone_gpu_test_helper.h"
 #include "ui/ozone/public/ozone_platform.h"
+#include "ui/ozone/public/surface_factory_ozone.h"
 #endif
 
 #if defined(OS_WIN)
@@ -84,10 +87,6 @@
 class InitUI {
  public:
   InitUI() {
-#if defined(USE_X11)
-    if (!features::IsUsingOzonePlatform())
-      XInitThreads();
-#endif
     event_source_ = ui::PlatformEventSource::CreateDefault();
   }
 
@@ -207,12 +206,57 @@
   return 0;
 }
 
+#if defined(USE_OZONE)
+std::unique_ptr<ui::OzoneGpuTestHelper> gpu_helper;
+
+static void SetupOzone(base::WaitableEvent* done) {
+  base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
+  cmd_line->AppendSwitchASCII(switches::kUseGL, gl::kGLImplementationEGLName);
+  ui::OzonePlatform::InitParams params;
+  params.single_process = true;
+  ui::OzonePlatform::InitializeForGPU(params);
+  done->Signal();
+}
+#endif
+
 }  // namespace
 
 int main(int argc, char** argv) {
+#if defined(USE_OZONE)
+  base::CommandLine command_line(argc, argv);
+  auto feature_list = std::make_unique<base::FeatureList>();
+  feature_list->InitializeFromCommandLine(
+      command_line.GetSwitchValueASCII(switches::kEnableFeatures),
+      command_line.GetSwitchValueASCII(switches::kDisableFeatures));
+  base::FeatureList::SetInstance(std::move(feature_list));
+
+  base::Thread rendering_thread("GLRenderingVEAClientThread");
+#endif
+
   InitBase base(argc, argv);
   InitMojo mojo;
   InitUI ui;
 
+#if defined(USE_OZONE)
+  if (features::IsUsingOzonePlatform()) {
+    ui::OzonePlatform::InitParams params;
+    params.single_process = true;
+    ui::OzonePlatform::InitializeForUI(params);
+
+    base::Thread::Options options;
+    options.message_pump_type = base::MessagePumpType::UI;
+    CHECK(rendering_thread.StartWithOptions(options));
+    base::WaitableEvent done(base::WaitableEvent::ResetPolicy::AUTOMATIC,
+                             base::WaitableEvent::InitialState::NOT_SIGNALED);
+    rendering_thread.task_runner()->PostTask(
+        FROM_HERE, base::BindOnce(&SetupOzone, &done));
+    done.Wait();
+
+    // To create dmabuf through gbm, Ozone needs to be set up.
+    gpu_helper = std::make_unique<ui::OzoneGpuTestHelper>();
+    gpu_helper->Initialize(base::ThreadTaskRunnerHandle::Get());
+  }
+#endif
+
   return DemoMain();
 }
diff --git a/components/viz/service/display_embedder/skia_output_device_vulkan.cc b/components/viz/service/display_embedder/skia_output_device_vulkan.cc
index 12cfa7d..d68844e 100644
--- a/components/viz/service/display_embedder/skia_output_device_vulkan.cc
+++ b/components/viz/service/display_embedder/skia_output_device_vulkan.cc
@@ -200,8 +200,6 @@
     vk_image_info.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
     vk_image_info.fImageLayout = scoped_write_->image_layout();
     vk_image_info.fFormat = surface_format;
-    vk_image_info.fImageUsageFlags = scoped_write_->image_usage();
-    vk_image_info.fSampleCount = 1;
     vk_image_info.fLevelCount = 1;
     vk_image_info.fCurrentQueueFamily = VK_QUEUE_FAMILY_IGNORED;
     vk_image_info.fProtected =
diff --git a/content/browser/child_process_security_policy_impl.cc b/content/browser/child_process_security_policy_impl.cc
index 4811577..1bb9dc8 100644
--- a/content/browser/child_process_security_policy_impl.cc
+++ b/content/browser/child_process_security_policy_impl.cc
@@ -1712,9 +1712,7 @@
 
         // A process that's not locked to any site can only access data from
         // origins that do not require a locked process.
-        bool should_lock_target = site_info.ShouldLockProcessToSite(
-            isolation_context, /* is_guest= */ false);
-        if (!should_lock_target)
+        if (!site_info.ShouldLockProcessToSite(isolation_context))
           return true;
         failure_reason = " citadel_enforcement";
 #endif
diff --git a/content/browser/child_process_security_policy_unittest.cc b/content/browser/child_process_security_policy_unittest.cc
index 3d5c7b37..5e98051 100644
--- a/content/browser/child_process_security_policy_unittest.cc
+++ b/content/browser/child_process_security_policy_unittest.cc
@@ -88,7 +88,7 @@
           CoopCoepCrossOriginIsolatedInfo::CreateNonIsolated());
   if (site_instance->RequiresDedicatedProcess() &&
       site_instance->GetSiteInfo().ShouldLockProcessToSite(
-          site_instance->GetIsolationContext(), site_instance->IsGuest())) {
+          site_instance->GetIsolationContext())) {
     ChildProcessSecurityPolicyImpl::GetInstance()->LockProcess(
         site_instance->GetIsolationContext(), process_id,
         site_instance->GetProcessLock());
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index aa76137..da2850b 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -152,7 +152,9 @@
 }
 
 // Forgive one GPU process crash after this many minutes.
-constexpr int kForgiveGpuCrashMinutes = 60;
+// This value should not be too small because then Chrome could end up in an
+// endless loop where it hangs and gets killed by GPU watchdog and hangs again.
+constexpr int kForgiveGpuCrashMinutes = 5;
 
 // Forgive one GPU process crash, when the GPU process is launched to run only
 // the display compositor, after this many minutes.
diff --git a/content/browser/isolated_origin_browsertest.cc b/content/browser/isolated_origin_browsertest.cc
index 47f9419..d6f2090 100644
--- a/content/browser/isolated_origin_browsertest.cc
+++ b/content/browser/isolated_origin_browsertest.cc
@@ -1962,8 +1962,7 @@
                                                const GURL& url) {
     return RenderProcessHostImpl::IsSuitableHost(
         process, isolation_context,
-        SiteInstanceImpl::ComputeSiteInfoForTesting(isolation_context, url),
-        /* is_guest= */ false);
+        SiteInstanceImpl::ComputeSiteInfoForTesting(isolation_context, url));
   };
   EXPECT_TRUE(is_suitable_host(foo_process, foo_url));
   EXPECT_FALSE(is_suitable_host(foo_process, isolated_foo_url));
diff --git a/content/browser/loader/file_url_loader_factory.cc b/content/browser/loader/file_url_loader_factory.cc
index 135c6c1..59ef32f 100644
--- a/content/browser/loader/file_url_loader_factory.cc
+++ b/content/browser/loader/file_url_loader_factory.cc
@@ -12,7 +12,6 @@
 #include "base/bind.h"
 #include "base/callback_forward.h"
 #include "base/command_line.h"
-#include "base/feature_list.h"
 #include "base/files/file.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -36,7 +35,6 @@
 #include "content/public/browser/file_url_loader.h"
 #include "content/public/browser/shared_cors_origin_access_list.h"
 #include "content/public/common/content_client.h"
-#include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
@@ -56,7 +54,6 @@
 #include "services/network/public/cpp/cors/cors.h"
 #include "services/network/public/cpp/cors/cors_error_status.h"
 #include "services/network/public/cpp/cors/origin_access_list.h"
-#include "services/network/public/cpp/features.h"
 #include "services/network/public/cpp/request_mode.h"
 #include "services/network/public/cpp/resource_request.h"
 #include "services/network/public/mojom/cors.mojom-shared.h"
@@ -770,19 +767,6 @@
   DISALLOW_COPY_AND_ASSIGN(FileURLLoader);
 };
 
-const url::Origin& GetCorsOrigin(const network::ResourceRequest& request) {
-  // Presence of |request_initiator| needs to be verified/ensured by the caller.
-  DCHECK(request.request_initiator.has_value());
-
-  if (request.isolated_world_origin.has_value() &&
-      base::FeatureList::IsEnabled(
-          features::kRelaxIsolatedWorldCorsInFileUrlLoaderFactory)) {
-    return request.isolated_world_origin.value();
-  }
-
-  return request.request_initiator.value();
-}
-
 }  // namespace
 
 FileURLLoaderFactory::FileURLLoaderFactory(
@@ -838,7 +822,7 @@
             url::Origin::Create(request.url)) ||
         (shared_cors_origin_access_list_ &&
          shared_cors_origin_access_list_->GetOriginAccessList()
-                 .CheckAccessState(GetCorsOrigin(request), request.url) ==
+                 .CheckAccessState(*request.request_initiator, request.url) ==
              network::cors::OriginAccessList::AccessState::kAllowed)));
 
   network::mojom::FetchResponseType response_type =
diff --git a/content/browser/loader/file_url_loader_factory_unittest.cc b/content/browser/loader/file_url_loader_factory_unittest.cc
index 7c1e0c4..3b6571a1 100644
--- a/content/browser/loader/file_url_loader_factory_unittest.cc
+++ b/content/browser/loader/file_url_loader_factory_unittest.cc
@@ -8,11 +8,9 @@
 #include <string>
 
 #include "base/path_service.h"
-#include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "base/threading/thread_restrictions.h"
 #include "content/public/browser/shared_cors_origin_access_list.h"
-#include "content/public/common/content_features.h"
 #include "content/public/common/content_paths.h"
 #include "content/public/test/simple_url_loader_test_helper.h"
 #include "net/base/filename_util.h"
@@ -155,35 +153,10 @@
                 network::mojom::RequestMode::kCorsWithForcedPreflight)));
 }
 
-// Test whether FileURLLoaderFactory can fetch/XHR files based on the
-// request_initiator and isolated_world_origin.
-//
-// The behavior for isolated_world_origin depends on a feature, and the test is
-// parameterized to cover both enabled and disabled cases.
-class FileURLLoaderFactoryTestWithRelaxedIsolatedWorlds
-    : public FileURLLoaderFactoryTest,
-      public testing::WithParamInterface<bool> {
- public:
-  FileURLLoaderFactoryTestWithRelaxedIsolatedWorlds() {
-    const base::Feature& feature =
-        features::kRelaxIsolatedWorldCorsInFileUrlLoaderFactory;
-    if (ShouldRelaxCorsForIsolatedWorlds()) {
-      feature_list_.InitAndEnableFeature(feature);
-    } else {
-      feature_list_.InitAndDisableFeature(feature);
-    }
-  }
-
-  bool ShouldRelaxCorsForIsolatedWorlds() { return GetParam(); }
-
- private:
-  base::test::ScopedFeatureList feature_list_;
-};
-
 // Verify that FileURLLoaderFactory takes OriginAccessList into account when
 // deciding whether to exempt a request from CORS.  See also
 // https://crbug.com/1049604.
-TEST_P(FileURLLoaderFactoryTestWithRelaxedIsolatedWorlds, Test) {
+TEST_F(FileURLLoaderFactoryTest, Allowlist) {
   const url::Origin not_permitted_origin =
       url::Origin::Create(GURL("https://www.example.com"));
 
@@ -197,20 +170,12 @@
   EXPECT_EQ(net::OK, CreateLoaderAndRun(CreateCorsRequestWithInitiator(
                          GetPermittedSourceOrigin())));
 
-  // In the long-term, isolated world origin should *not* be used to check the
-  // permission.  In the short-term we allow consulting isolated world origin if
-  // the RelaxIsolatedWorldCorsInFileUrlLoaderFactory feature is enabled (see
-  // https://crbug.com/1049604 for more discussion and details).
+  // Isolated world origin should *not* be used to check the permission.
   auto request = CreateCorsRequestWithInitiator(not_permitted_origin);
   request->isolated_world_origin = GetPermittedSourceOrigin();
-  EXPECT_EQ(ShouldRelaxCorsForIsolatedWorlds() ? net::OK : net::ERR_FAILED,
-            CreateLoaderAndRun(std::move(request)));
+  EXPECT_EQ(net::ERR_FAILED, CreateLoaderAndRun(std::move(request)));
 }
 
-INSTANTIATE_TEST_SUITE_P(FeatureState,
-                         FileURLLoaderFactoryTestWithRelaxedIsolatedWorlds,
-                         testing::Values(true, false));
-
 }  // namespace
 
 }  // namespace content
diff --git a/content/browser/renderer_host/navigator.cc b/content/browser/renderer_host/navigator.cc
index 8793218..36f30f7 100644
--- a/content/browser/renderer_host/navigator.cc
+++ b/content/browser/renderer_host/navigator.cc
@@ -138,8 +138,8 @@
   // this method should take this into account.
   SiteInstanceImpl* site_instance = render_frame_host->GetSiteInstance();
   SiteInfo site_info = site_instance->DeriveSiteInfo(url_info);
-  bool should_lock_process = site_info.ShouldLockProcessToSite(
-      site_instance->GetIsolationContext(), site_instance->IsGuest());
+  bool should_lock_process =
+      site_info.ShouldLockProcessToSite(site_instance->GetIsolationContext());
 
   // If the |render_frame_host| has any WebUI bindings, disallow URLs that are
   // not allowed in a WebUI renderer process.
diff --git a/content/browser/renderer_host/render_frame_host_manager.cc b/content/browser/renderer_host/render_frame_host_manager.cc
index 4bb97fe3..61f2d2f 100644
--- a/content/browser/renderer_host/render_frame_host_manager.cc
+++ b/content/browser/renderer_host/render_frame_host_manager.cc
@@ -1876,8 +1876,8 @@
         RenderProcessHostImpl::ShouldUseProcessPerSite(
             current_instance_impl->GetBrowserContext(), dest_site_info) &&
         RenderProcessHostImpl::GetSoleProcessHostForSite(
-            current_instance_impl->GetIsolationContext(), dest_site_info,
-            current_instance_impl->IsGuest());
+            current_instance_impl->GetIsolationContext(), dest_site_info);
+
     if (current_instance_impl->HasRelatedSiteInstance(dest_site_info) ||
         use_process_per_site) {
       return SiteInstanceDescriptor(
diff --git a/content/browser/renderer_host/render_frame_host_manager_browsertest.cc b/content/browser/renderer_host/render_frame_host_manager_browsertest.cc
index 1179a66d..e772e36 100644
--- a/content/browser/renderer_host/render_frame_host_manager_browsertest.cc
+++ b/content/browser/renderer_host/render_frame_host_manager_browsertest.cc
@@ -5845,7 +5845,7 @@
   EXPECT_EQ(c_site_instance->GetProcess(),
             RenderProcessHostImpl::GetSoleProcessHostForSite(
                 c_site_instance->GetIsolationContext(),
-                c_site_instance->GetSiteInfo(), c_site_instance->IsGuest()));
+                c_site_instance->GetSiteInfo()));
 
   // Make sure we will not use process-per-site for B.
   content_browser_client.SetShouldUseProcessPerSite(false);
@@ -5903,8 +5903,7 @@
   EXPECT_EQ(process_for_b,
             RenderProcessHostImpl::GetSoleProcessHostForSite(
                 placeholder_b_site_instance->GetIsolationContext(),
-                placeholder_b_site_instance->GetSiteInfo(),
-                placeholder_b_site_instance->IsGuest()));
+                placeholder_b_site_instance->GetSiteInfo()));
   // Make sure we will use process-per-site for B.
   content_browser_client.SetShouldUseProcessPerSite(true);
 
@@ -5925,7 +5924,7 @@
   EXPECT_EQ(b_site_instance->GetProcess(),
             RenderProcessHostImpl::GetSoleProcessHostForSite(
                 b_site_instance->GetIsolationContext(),
-                b_site_instance->GetSiteInfo(), b_site_instance->IsGuest()));
+                b_site_instance->GetSiteInfo()));
 
   SetBrowserClientForTesting(old_client);
 }
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index 62457ee..254093bd 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -861,7 +861,7 @@
       if (!host->MayReuseHost() ||
           !RenderProcessHostImpl::IsSuitableHost(
               host, site_instance->GetIsolationContext(),
-              site_instance->GetSiteInfo(), site_instance->IsGuest())) {
+              site_instance->GetSiteInfo())) {
         continue;
       }
 
@@ -1067,10 +1067,9 @@
     // |site_instance|, for example if it was used for a ServiceWorker for a
     // nonexistent extension URL.  See https://crbug.com/782349 and
     // https://crbug.com/780661.
-    if (!host->MayReuseHost() ||
-        !RenderProcessHostImpl::IsSuitableHost(
-            host, site_instance->GetIsolationContext(),
-            site_instance->GetSiteInfo(), site_instance->IsGuest()))
+    if (!host->MayReuseHost() || !RenderProcessHostImpl::IsSuitableHost(
+                                     host, site_instance->GetIsolationContext(),
+                                     site_instance->GetSiteInfo()))
       return nullptr;
 
     site_process_set_.erase(site_process_pair);
@@ -4095,8 +4094,7 @@
 bool RenderProcessHostImpl::IsSuitableHost(
     RenderProcessHost* host,
     const IsolationContext& isolation_context,
-    const SiteInfo& site_info,
-    const bool is_guest) {
+    const SiteInfo& site_info) {
   BrowserContext* browser_context =
       isolation_context.browser_or_resource_context().ToBrowserContext();
   DCHECK(browser_context);
@@ -4113,9 +4111,9 @@
   // and non-guest storage gets mixed. In the future, we might consider
   // enabling the sharing of guests, in this case this check should be removed
   // and InSameStoragePartition should handle the possible sharing. Also
-  // deny any attempt where a guest request tries to use a |host| that is not
+  // deny any attempt where a guest SiteInfo tries to use a |host| that is not
   // explicitly created for guests.
-  if (host->IsForGuestsOnly() || is_guest)
+  if (host->IsForGuestsOnly() || site_info.is_guest())
     return false;
 
   // Check whether the given host and the intended site_url will be using the
@@ -4151,7 +4149,7 @@
       // destination that doesn't require a dedicated process, even for the
       // same site. This can happen with dynamic isolated origins (see
       // https://crbug.com/950453).
-      if (!site_info.ShouldLockProcessToSite(isolation_context, is_guest))
+      if (!site_info.ShouldLockProcessToSite(isolation_context))
         return false;
 
       // If the destination requires a different process lock, this process
@@ -4169,7 +4167,7 @@
       }
 
       if (!host->IsUnused() &&
-          site_info.ShouldLockProcessToSite(isolation_context, is_guest)) {
+          site_info.ShouldLockProcessToSite(isolation_context)) {
         // If this process has been used to host any other content, it cannot
         // be reused if the destination site requires a dedicated process and
         // should use a process locked to just that site.
@@ -4277,7 +4275,7 @@
     if (iter.GetCurrentValue()->MayReuseHost() &&
         RenderProcessHostImpl::IsSuitableHost(
             iter.GetCurrentValue(), site_instance->GetIsolationContext(),
-            site_instance->GetSiteInfo(), site_instance->IsGuest())) {
+            site_instance->GetSiteInfo())) {
       // The spare is always considered before process reuse.
       DCHECK_NE(iter.GetCurrentValue(),
                 SpareRenderProcessHostManager::GetInstance()
@@ -4323,7 +4321,7 @@
         iter.GetCurrentValue()->IsUnused() &&
         RenderProcessHostImpl::IsSuitableHost(
             iter.GetCurrentValue(), site_instance->GetIsolationContext(),
-            site_instance->GetSiteInfo(), site_instance->IsGuest())) {
+            site_instance->GetSiteInfo())) {
       return host;
     }
     iter.Advance();
@@ -4358,8 +4356,7 @@
 // static
 RenderProcessHost* RenderProcessHostImpl::GetSoleProcessHostForSite(
     const IsolationContext& isolation_context,
-    const SiteInfo& site_info,
-    const bool is_guest) {
+    const SiteInfo& site_info) {
   // Look up the map of site to process for the given browser_context.
   SiteProcessMap* map = GetSiteProcessMapForBrowserContext(
       isolation_context.browser_or_resource_context().ToBrowserContext());
@@ -4369,7 +4366,7 @@
   // Note that IsSuitableHost expects a SiteInfo rather than the full |url|.
   RenderProcessHost* host = map->FindProcess(site_info);
   if (host && (!host->MayReuseHost() ||
-               !IsSuitableHost(host, isolation_context, site_info, is_guest))) {
+               !IsSuitableHost(host, isolation_context, site_info))) {
     // The registered process does not have an appropriate set of bindings for
     // the url.  Remove it from the map so we can register a better one.
     RecordAction(
@@ -4413,9 +4410,8 @@
   // First, attempt to reuse an existing RenderProcessHost if necessary.
   switch (process_reuse_policy) {
     case SiteInstanceImpl::ProcessReusePolicy::PROCESS_PER_SITE:
-      render_process_host =
-          GetSoleProcessHostForSite(site_instance->GetIsolationContext(),
-                                    site_info, site_instance->IsGuest());
+      render_process_host = GetSoleProcessHostForSite(
+          site_instance->GetIsolationContext(), site_info);
       break;
     case SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE:
       render_process_host =
@@ -4497,8 +4493,8 @@
   // site.
   if (render_process_host &&
       !RenderProcessHostImpl::IsSuitableHost(
-          render_process_host, site_instance->GetIsolationContext(), site_info,
-          site_instance->IsGuest())) {
+          render_process_host, site_instance->GetIsolationContext(),
+          site_info)) {
     base::debug::SetCrashKeyString(bad_message::GetRequestedSiteInfoKey(),
                                    site_info.GetDebugString());
     ChildProcessSecurityPolicyImpl::GetInstance()->LogKilledProcessOriginLock(
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h
index 140aaec..d86657e 100644
--- a/content/browser/renderer_host/render_process_host_impl.h
+++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -339,26 +339,20 @@
   // its SiteInstance site URL, and its process would be locked to
   // |site_info.lock_url()|. Site and lock urls may differ in cases where
   // an effective URL is not the actual site that the process is locked to,
-  // which happens for hosted apps. |is_guest| should be set to true if the call
-  // is being made for a <webview> guest SiteInstance.
-  // TODO(wjmaclean): move is_guest into SiteInfo at some point.
+  // which happens for hosted apps.
   static bool IsSuitableHost(RenderProcessHost* host,
                              const IsolationContext& isolation_context,
-                             const SiteInfo& site_info,
-                             bool is_guest);
+                             const SiteInfo& site_info);
 
   // Returns an existing RenderProcessHost for |site_info| in
   // |isolation_context|, if one exists.  Otherwise a new RenderProcessHost
   // should be created and registered using RegisterProcessHostForSite(). This
   // should only be used for process-per-site mode, which can be enabled
   // globally with a command line flag or per-site, as determined by
-  // SiteInstanceImpl::ShouldUseProcessPerSite. |is_guest| should be set to
-  // true if the call is being made for a <webview> guest SiteInstance.
-  // TODO(wjmaclean): Move is_guest into SiteInfo at some point.
+  // SiteInstanceImpl::ShouldUseProcessPerSite.
   static RenderProcessHost* GetSoleProcessHostForSite(
       const IsolationContext& isolation_context,
-      const SiteInfo& site_info,
-      const bool is_guest);
+      const SiteInfo& site_info);
 
   // Registers the given |process| to be used for all sites identified by
   // |site_instance| within its BrowserContext. This should only be used for
diff --git a/content/browser/renderer_host/render_process_host_unittest.cc b/content/browser/renderer_host/render_process_host_unittest.cc
index e20ca70..195d4b0 100644
--- a/content/browser/renderer_host/render_process_host_unittest.cc
+++ b/content/browser/renderer_host/render_process_host_unittest.cc
@@ -54,10 +54,10 @@
   scoped_refptr<SiteInstanceImpl> site_instance = CreateForUrl(test_url);
   EXPECT_FALSE(RenderProcessHostImpl::IsSuitableHost(
       &guest_host, site_instance->GetIsolationContext(),
-      site_instance->GetSiteInfo(), site_instance->IsGuest()));
+      site_instance->GetSiteInfo()));
   EXPECT_TRUE(RenderProcessHostImpl::IsSuitableHost(
       process(), site_instance->GetIsolationContext(),
-      site_instance->GetSiteInfo(), site_instance->IsGuest()));
+      site_instance->GetSiteInfo()));
   EXPECT_EQ(process(),
             RenderProcessHostImpl::GetExistingProcessHost(site_instance.get()));
 }
diff --git a/content/browser/service_worker/service_worker_registry_unittest.cc b/content/browser/service_worker/service_worker_registry_unittest.cc
index 4070cea..f969079 100644
--- a/content/browser/service_worker/service_worker_registry_unittest.cc
+++ b/content/browser/service_worker/service_worker_registry_unittest.cc
@@ -416,6 +416,35 @@
     return result;
   }
 
+  blink::ServiceWorkerStatusCode UpdateToActiveState(
+      const ServiceWorkerRegistration* registration) {
+    base::RunLoop loop;
+    blink::ServiceWorkerStatusCode result;
+    registry()->UpdateToActiveState(
+        registration->id(), registration->scope().GetOrigin(),
+        base::BindLambdaForTesting([&](blink::ServiceWorkerStatusCode status) {
+          result = status;
+          loop.Quit();
+        }));
+    loop.Run();
+    return result;
+  }
+
+  blink::ServiceWorkerStatusCode UpdateLastUpdateCheckTime(
+      const ServiceWorkerRegistration* registration) {
+    base::RunLoop loop;
+    blink::ServiceWorkerStatusCode result;
+    registry()->UpdateLastUpdateCheckTime(
+        registration->id(), registration->scope().GetOrigin(),
+        registration->last_update_check(),
+        base::BindLambdaForTesting([&](blink::ServiceWorkerStatusCode status) {
+          result = status;
+          loop.Quit();
+        }));
+    loop.Run();
+    return result;
+  }
+
   GetStorageUsageForOriginResult GetStorageUsageForOrigin(
       const url::Origin& origin) {
     GetStorageUsageForOriginResult result;
@@ -569,6 +598,195 @@
   }
 }
 
+TEST_F(ServiceWorkerRegistryTest, StoreFindUpdateDeleteRegistration) {
+  const GURL kScope("http://www.test.not/scope/");
+  const GURL kDocumentUrl("http://www.test.not/scope/document.html");
+  const GURL kResource1("http://www.test.not/scope/resource1.js");
+  const int64_t kResource1Size = 1591234;
+  const GURL kResource2("http://www.test.not/scope/resource2.js");
+  const int64_t kResource2Size = 51;
+  const int64_t kRegistrationId = 0;
+  const int64_t kVersionId = 0;
+  const base::Time kToday = base::Time::Now();
+  const base::Time kYesterday = kToday - base::TimeDelta::FromDays(1);
+  std::set<blink::mojom::WebFeature> used_features = {
+      blink::mojom::WebFeature::kServiceWorkerControlledPage,
+      blink::mojom::WebFeature::kReferrerPolicyHeader,
+      blink::mojom::WebFeature::kLocationOrigin};
+
+  scoped_refptr<ServiceWorkerRegistration> found_registration;
+
+  // We shouldn't find anything without having stored anything.
+  EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
+            FindRegistrationForClientUrl(kDocumentUrl, found_registration));
+  EXPECT_FALSE(found_registration.get());
+
+  EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
+            FindRegistrationForScope(kScope, found_registration));
+  EXPECT_FALSE(found_registration.get());
+
+  EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
+            FindRegistrationForId(kRegistrationId, url::Origin::Create(kScope),
+                                  found_registration));
+  EXPECT_FALSE(found_registration.get());
+
+  std::vector<storage::mojom::ServiceWorkerResourceRecordPtr> resources;
+  resources.push_back(CreateResourceRecord(1, kResource1, kResource1Size));
+  resources.push_back(CreateResourceRecord(2, kResource2, kResource2Size));
+
+  // Store something.
+  blink::mojom::ServiceWorkerRegistrationOptions options;
+  options.scope = kScope;
+  scoped_refptr<ServiceWorkerRegistration> live_registration =
+      new ServiceWorkerRegistration(options, kRegistrationId,
+                                    context()->AsWeakPtr());
+  scoped_refptr<ServiceWorkerVersion> live_version = new ServiceWorkerVersion(
+      live_registration.get(), kResource1, blink::mojom::ScriptType::kClassic,
+      kVersionId,
+      mojo::PendingRemote<storage::mojom::ServiceWorkerLiveVersionRef>(),
+      context()->AsWeakPtr());
+  live_version->set_fetch_handler_existence(
+      ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
+  live_version->SetStatus(ServiceWorkerVersion::INSTALLED);
+  live_version->script_cache_map()->SetResources(resources);
+  live_version->set_used_features(
+      std::set<blink::mojom::WebFeature>(used_features));
+  network::CrossOriginEmbedderPolicy coep_require_corp;
+  coep_require_corp.value =
+      network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp;
+  live_version->set_cross_origin_embedder_policy(coep_require_corp);
+  live_registration->SetWaitingVersion(live_version);
+  live_registration->set_last_update_check(kYesterday);
+  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+            StoreRegistration(live_registration, live_version));
+
+  // Now we should find it and get the live ptr back immediately.
+  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+            FindRegistrationForClientUrl(kDocumentUrl, found_registration));
+  EXPECT_EQ(live_registration, found_registration);
+  EXPECT_EQ(kResource1Size + kResource2Size,
+            live_registration->resources_total_size_bytes());
+  EXPECT_EQ(kResource1Size + kResource2Size,
+            found_registration->resources_total_size_bytes());
+  EXPECT_EQ(used_features,
+            found_registration->waiting_version()->used_features());
+  EXPECT_EQ(
+      found_registration->waiting_version()->cross_origin_embedder_policy(),
+      coep_require_corp);
+  found_registration = nullptr;
+
+  // But FindRegistrationForScope is always async.
+  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+            FindRegistrationForScope(kScope, found_registration));
+  EXPECT_EQ(live_registration, found_registration);
+  found_registration = nullptr;
+
+  // Can be found by id too.
+  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+            FindRegistrationForId(kRegistrationId, url::Origin::Create(kScope),
+                                  found_registration));
+  ASSERT_TRUE(found_registration.get());
+  EXPECT_EQ(kRegistrationId, found_registration->id());
+  EXPECT_EQ(live_registration, found_registration);
+  found_registration = nullptr;
+
+  // Can be found by just the id too.
+  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+            FindRegistrationForIdOnly(kRegistrationId, found_registration));
+  ASSERT_TRUE(found_registration.get());
+  EXPECT_EQ(kRegistrationId, found_registration->id());
+  EXPECT_EQ(live_registration, found_registration);
+  found_registration = nullptr;
+
+  // Drop the live registration, but keep the version live.
+  live_registration = nullptr;
+
+  // Now FindRegistrationForClientUrl should be async.
+  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+            FindRegistrationForClientUrl(kDocumentUrl, found_registration));
+  ASSERT_TRUE(found_registration.get());
+  EXPECT_EQ(kRegistrationId, found_registration->id());
+  EXPECT_TRUE(found_registration->HasOneRef());
+
+  // Check that sizes are populated correctly
+  EXPECT_EQ(live_version.get(), found_registration->waiting_version());
+  EXPECT_EQ(kResource1Size + kResource2Size,
+            found_registration->resources_total_size_bytes());
+  std::vector<ServiceWorkerRegistrationInfo> all_registrations;
+  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+            GetAllRegistrationsInfos(&all_registrations));
+  EXPECT_EQ(1u, all_registrations.size());
+  ServiceWorkerRegistrationInfo info = all_registrations[0];
+  EXPECT_EQ(kResource1Size + kResource2Size, info.stored_version_size_bytes);
+  all_registrations.clear();
+
+  // Finding by origin should provide the same result if origin is kScope.
+  std::vector<scoped_refptr<ServiceWorkerRegistration>>
+      registrations_for_origin;
+  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+            GetRegistrationsForOrigin(url::Origin::Create(kScope),
+                                      registrations_for_origin));
+  EXPECT_EQ(1u, registrations_for_origin.size());
+  registrations_for_origin.clear();
+
+  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+            GetRegistrationsForOrigin(
+                url::Origin::Create(GURL("http://example.com/")),
+                registrations_for_origin));
+  EXPECT_TRUE(registrations_for_origin.empty());
+
+  found_registration = nullptr;
+
+  // Drop the live version too.
+  live_version = nullptr;
+
+  // And FindRegistrationForScope is always async.
+  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+            FindRegistrationForScope(kScope, found_registration));
+  ASSERT_TRUE(found_registration.get());
+  EXPECT_EQ(kRegistrationId, found_registration->id());
+  EXPECT_TRUE(found_registration->HasOneRef());
+  EXPECT_FALSE(found_registration->active_version());
+  ASSERT_TRUE(found_registration->waiting_version());
+  EXPECT_EQ(kYesterday, found_registration->last_update_check());
+  EXPECT_EQ(ServiceWorkerVersion::INSTALLED,
+            found_registration->waiting_version()->status());
+
+  // Update to active and update the last check time.
+  scoped_refptr<ServiceWorkerVersion> temp_version =
+      found_registration->waiting_version();
+  temp_version->SetStatus(ServiceWorkerVersion::ACTIVATED);
+  found_registration->SetActiveVersion(temp_version);
+  temp_version = nullptr;
+  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+            UpdateToActiveState(found_registration.get()));
+  found_registration->set_last_update_check(kToday);
+  UpdateLastUpdateCheckTime(found_registration.get());
+
+  found_registration = nullptr;
+
+  // Trying to update a unstored registration to active should fail.
+  scoped_refptr<ServiceWorkerRegistration> unstored_registration =
+      new ServiceWorkerRegistration(options, kRegistrationId + 1,
+                                    context()->AsWeakPtr());
+  EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
+            UpdateToActiveState(unstored_registration.get()));
+  unstored_registration = nullptr;
+
+  // The Find methods should return a registration with an active version
+  // and the expected update time.
+  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+            FindRegistrationForClientUrl(kDocumentUrl, found_registration));
+  ASSERT_TRUE(found_registration.get());
+  EXPECT_EQ(kRegistrationId, found_registration->id());
+  EXPECT_TRUE(found_registration->HasOneRef());
+  EXPECT_FALSE(found_registration->waiting_version());
+  ASSERT_TRUE(found_registration->active_version());
+  EXPECT_EQ(ServiceWorkerVersion::ACTIVATED,
+            found_registration->active_version()->status());
+  EXPECT_EQ(kToday, found_registration->last_update_check());
+}
+
 TEST_F(ServiceWorkerRegistryTest, InstallingRegistrationsAreFindable) {
   const GURL kScope("http://www.test.not/scope/");
   const GURL kScript("http://www.test.not/script.js");
diff --git a/content/browser/service_worker/service_worker_storage_unittest.cc b/content/browser/service_worker/service_worker_storage_unittest.cc
index 38aa8b8..b32fe75 100644
--- a/content/browser/service_worker/service_worker_storage_unittest.cc
+++ b/content/browser/service_worker/service_worker_storage_unittest.cc
@@ -479,18 +479,6 @@
     return result.value();
   }
 
-  blink::ServiceWorkerStatusCode UpdateLastUpdateCheckTime(
-      scoped_refptr<ServiceWorkerRegistration> registration) {
-    base::RunLoop loop;
-    base::Optional<blink::ServiceWorkerStatusCode> result;
-    registry()->UpdateLastUpdateCheckTime(
-        registration->id(), registration->scope().GetOrigin(),
-        registration->last_update_check(),
-        base::BindOnce(&StatusCallback, loop.QuitClosure(), &result));
-    loop.Run();
-    return result.value();
-  }
-
   blink::ServiceWorkerStatusCode FindRegistrationForClientUrl(
       const GURL& document_url,
       scoped_refptr<ServiceWorkerRegistration>* registration) {
@@ -700,195 +688,6 @@
   EXPECT_EQ(blink::mojom::kInvalidServiceWorkerResourceId, GetNewResourceId());
 }
 
-TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
-  const GURL kScope("http://www.test.not/scope/");
-  const GURL kDocumentUrl("http://www.test.not/scope/document.html");
-  const GURL kResource1("http://www.test.not/scope/resource1.js");
-  const int64_t kResource1Size = 1591234;
-  const GURL kResource2("http://www.test.not/scope/resource2.js");
-  const int64_t kResource2Size = 51;
-  const int64_t kRegistrationId = 0;
-  const int64_t kVersionId = 0;
-  const base::Time kToday = base::Time::Now();
-  const base::Time kYesterday = kToday - base::TimeDelta::FromDays(1);
-  std::set<blink::mojom::WebFeature> used_features = {
-      blink::mojom::WebFeature::kServiceWorkerControlledPage,
-      blink::mojom::WebFeature::kReferrerPolicyHeader,
-      blink::mojom::WebFeature::kLocationOrigin};
-
-  scoped_refptr<ServiceWorkerRegistration> found_registration;
-
-  // We shouldn't find anything without having stored anything.
-  EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
-            FindRegistrationForClientUrl(kDocumentUrl, &found_registration));
-  EXPECT_FALSE(found_registration.get());
-
-  EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
-            FindRegistrationForScope(kScope, &found_registration));
-  EXPECT_FALSE(found_registration.get());
-
-  EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
-            FindRegistrationForId(kRegistrationId, url::Origin::Create(kScope),
-                                  &found_registration));
-  EXPECT_FALSE(found_registration.get());
-
-  std::vector<ResourceRecord> resources;
-  resources.push_back(CreateResourceRecord(1, kResource1, kResource1Size));
-  resources.push_back(CreateResourceRecord(2, kResource2, kResource2Size));
-
-  // Store something.
-  blink::mojom::ServiceWorkerRegistrationOptions options;
-  options.scope = kScope;
-  scoped_refptr<ServiceWorkerRegistration> live_registration =
-      new ServiceWorkerRegistration(options, kRegistrationId,
-                                    context()->AsWeakPtr());
-  scoped_refptr<ServiceWorkerVersion> live_version = new ServiceWorkerVersion(
-      live_registration.get(), kResource1, blink::mojom::ScriptType::kClassic,
-      kVersionId,
-      mojo::PendingRemote<storage::mojom::ServiceWorkerLiveVersionRef>(),
-      context()->AsWeakPtr());
-  live_version->set_fetch_handler_existence(
-      ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
-  live_version->SetStatus(ServiceWorkerVersion::INSTALLED);
-  live_version->script_cache_map()->SetResources(resources);
-  live_version->set_used_features(
-      std::set<blink::mojom::WebFeature>(used_features));
-  network::CrossOriginEmbedderPolicy coep_require_corp;
-  coep_require_corp.value =
-      network::mojom::CrossOriginEmbedderPolicyValue::kRequireCorp;
-  live_version->set_cross_origin_embedder_policy(coep_require_corp);
-  live_registration->SetWaitingVersion(live_version);
-  live_registration->set_last_update_check(kYesterday);
-  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
-            StoreRegistration(live_registration, live_version));
-
-  // Now we should find it and get the live ptr back immediately.
-  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
-            FindRegistrationForClientUrl(kDocumentUrl, &found_registration));
-  EXPECT_EQ(live_registration, found_registration);
-  EXPECT_EQ(kResource1Size + kResource2Size,
-            live_registration->resources_total_size_bytes());
-  EXPECT_EQ(kResource1Size + kResource2Size,
-            found_registration->resources_total_size_bytes());
-  EXPECT_EQ(used_features,
-            found_registration->waiting_version()->used_features());
-  EXPECT_EQ(
-      found_registration->waiting_version()->cross_origin_embedder_policy(),
-      coep_require_corp);
-  found_registration = nullptr;
-
-  // But FindRegistrationForScope is always async.
-  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
-            FindRegistrationForScope(kScope, &found_registration));
-  EXPECT_EQ(live_registration, found_registration);
-  found_registration = nullptr;
-
-  // Can be found by id too.
-  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
-            FindRegistrationForId(kRegistrationId, url::Origin::Create(kScope),
-                                  &found_registration));
-  ASSERT_TRUE(found_registration.get());
-  EXPECT_EQ(kRegistrationId, found_registration->id());
-  EXPECT_EQ(live_registration, found_registration);
-  found_registration = nullptr;
-
-  // Can be found by just the id too.
-  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
-            FindRegistrationForIdOnly(kRegistrationId, &found_registration));
-  ASSERT_TRUE(found_registration.get());
-  EXPECT_EQ(kRegistrationId, found_registration->id());
-  EXPECT_EQ(live_registration, found_registration);
-  found_registration = nullptr;
-
-  // Drop the live registration, but keep the version live.
-  live_registration = nullptr;
-
-  // Now FindRegistrationForClientUrl should be async.
-  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
-            FindRegistrationForClientUrl(kDocumentUrl, &found_registration));
-  ASSERT_TRUE(found_registration.get());
-  EXPECT_EQ(kRegistrationId, found_registration->id());
-  EXPECT_TRUE(found_registration->HasOneRef());
-
-  // Check that sizes are populated correctly
-  EXPECT_EQ(live_version.get(), found_registration->waiting_version());
-  EXPECT_EQ(kResource1Size + kResource2Size,
-            found_registration->resources_total_size_bytes());
-  std::vector<ServiceWorkerRegistrationInfo> all_registrations;
-  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
-            GetAllRegistrationsInfos(&all_registrations));
-  EXPECT_EQ(1u, all_registrations.size());
-  ServiceWorkerRegistrationInfo info = all_registrations[0];
-  EXPECT_EQ(kResource1Size + kResource2Size, info.stored_version_size_bytes);
-  all_registrations.clear();
-
-  // Finding by origin should provide the same result if origin is kScope.
-  std::vector<scoped_refptr<ServiceWorkerRegistration>>
-      registrations_for_origin;
-  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
-            GetRegistrationsForOrigin(url::Origin::Create(kScope),
-                                      &registrations_for_origin));
-  EXPECT_EQ(1u, registrations_for_origin.size());
-  registrations_for_origin.clear();
-
-  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
-            GetRegistrationsForOrigin(
-                url::Origin::Create(GURL("http://example.com/")),
-                &registrations_for_origin));
-  EXPECT_TRUE(registrations_for_origin.empty());
-
-  found_registration = nullptr;
-
-  // Drop the live version too.
-  live_version = nullptr;
-
-  // And FindRegistrationForScope is always async.
-  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
-            FindRegistrationForScope(kScope, &found_registration));
-  ASSERT_TRUE(found_registration.get());
-  EXPECT_EQ(kRegistrationId, found_registration->id());
-  EXPECT_TRUE(found_registration->HasOneRef());
-  EXPECT_FALSE(found_registration->active_version());
-  ASSERT_TRUE(found_registration->waiting_version());
-  EXPECT_EQ(kYesterday, found_registration->last_update_check());
-  EXPECT_EQ(ServiceWorkerVersion::INSTALLED,
-            found_registration->waiting_version()->status());
-
-  // Update to active and update the last check time.
-  scoped_refptr<ServiceWorkerVersion> temp_version =
-      found_registration->waiting_version();
-  temp_version->SetStatus(ServiceWorkerVersion::ACTIVATED);
-  found_registration->SetActiveVersion(temp_version);
-  temp_version = nullptr;
-  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
-            UpdateToActiveState(found_registration));
-  found_registration->set_last_update_check(kToday);
-  UpdateLastUpdateCheckTime(found_registration.get());
-
-  found_registration = nullptr;
-
-  // Trying to update a unstored registration to active should fail.
-  scoped_refptr<ServiceWorkerRegistration> unstored_registration =
-      new ServiceWorkerRegistration(options, kRegistrationId + 1,
-                                    context()->AsWeakPtr());
-  EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound,
-            UpdateToActiveState(unstored_registration));
-  unstored_registration = nullptr;
-
-  // The Find methods should return a registration with an active version
-  // and the expected update time.
-  EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
-            FindRegistrationForClientUrl(kDocumentUrl, &found_registration));
-  ASSERT_TRUE(found_registration.get());
-  EXPECT_EQ(kRegistrationId, found_registration->id());
-  EXPECT_TRUE(found_registration->HasOneRef());
-  EXPECT_FALSE(found_registration->waiting_version());
-  ASSERT_TRUE(found_registration->active_version());
-  EXPECT_EQ(ServiceWorkerVersion::ACTIVATED,
-            found_registration->active_version()->status());
-  EXPECT_EQ(kToday, found_registration->last_update_check());
-}
-
 TEST_F(ServiceWorkerStorageTest, StoreUserData) {
   const int64_t kRegistrationId = 1;
   const GURL kScope("http://www.test.not/scope/");
diff --git a/content/browser/site_instance_impl.cc b/content/browser/site_instance_impl.cc
index f92beb6..12e2cf3a 100644
--- a/content/browser/site_instance_impl.cc
+++ b/content/browser/site_instance_impl.cc
@@ -66,7 +66,8 @@
   return SiteInfo(GURL(content::kUnreachableWebDataURL),
                   GURL(content::kUnreachableWebDataURL),
                   false /* is_origin_keyed */,
-                  CoopCoepCrossOriginIsolatedInfo::CreateNonIsolated());
+                  CoopCoepCrossOriginIsolatedInfo::CreateNonIsolated(),
+                  false /* is_guest */);
 }
 
 // static
@@ -74,7 +75,18 @@
     const CoopCoepCrossOriginIsolatedInfo& cross_origin_isolated_info) {
   return SiteInfo(SiteInstanceImpl::GetDefaultSiteURL(),
                   SiteInstanceImpl::GetDefaultSiteURL(),
-                  false /* is_origin_keyed */, cross_origin_isolated_info);
+                  false /* is_origin_keyed */, cross_origin_isolated_info,
+                  false /* is_guest */);
+}
+
+// static
+SiteInfo SiteInfo::CreateForGuest(const GURL& guest_site_url) {
+  // Setting site and lock directly without the site URL conversions we
+  // do for user provided URLs. Callers expect GetSiteURL() to return the
+  // value they provide in |guest_site_url|.
+  return SiteInfo(guest_site_url, guest_site_url, false /* is_origin_keyed */,
+                  CoopCoepCrossOriginIsolatedInfo::CreateNonIsolated(),
+                  true /* is_guest */);
 }
 
 SiteInfo::SiteInfo() = default;
@@ -86,18 +98,21 @@
     const GURL& site_url,
     const GURL& process_lock_url,
     bool is_origin_keyed,
-    const CoopCoepCrossOriginIsolatedInfo& cross_origin_isolated_info)
+    const CoopCoepCrossOriginIsolatedInfo& cross_origin_isolated_info,
+    bool is_guest)
     : site_url_(site_url),
       process_lock_url_(process_lock_url),
       is_origin_keyed_(is_origin_keyed),
-      coop_coep_cross_origin_isolated_info_(cross_origin_isolated_info) {}
+      coop_coep_cross_origin_isolated_info_(cross_origin_isolated_info),
+      is_guest_(is_guest) {}
 
 // static
 auto SiteInfo::MakeTie(const SiteInfo& site_info) {
   return std::tie(site_info.site_url_.possibly_invalid_spec(),
                   site_info.process_lock_url_.possibly_invalid_spec(),
                   site_info.is_origin_keyed_,
-                  site_info.coop_coep_cross_origin_isolated_info_);
+                  site_info.coop_coep_cross_origin_isolated_info_,
+                  site_info.is_guest_);
 }
 
 SiteInfo& SiteInfo::operator=(const SiteInfo& rhs) = default;
@@ -182,8 +197,7 @@
 }
 
 bool SiteInfo::ShouldLockProcessToSite(
-    const IsolationContext& isolation_context,
-    const bool is_guest) const {
+    const IsolationContext& isolation_context) const {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   BrowserContext* browser_context =
       isolation_context.browser_or_resource_context().ToBrowserContext();
@@ -206,7 +220,7 @@
   // and StoragePartition information in SiteInfo instead of packing this info
   // into the guest site URL. Once we have these capabilities we won't need to
   // restrict guests to a single SiteInstance.
-  if (is_guest)
+  if (is_guest_)
     return false;
 
   // Most WebUI processes should be locked on all platforms.  The only exception
@@ -238,7 +252,6 @@
       has_site_(false),
       process_reuse_policy_(ProcessReusePolicy::DEFAULT),
       is_for_service_worker_(false),
-      is_guest_(false),
       process_assignment_(SiteInstanceProcessAssignment::UNKNOWN) {
   DCHECK(browsing_instance);
 }
@@ -333,19 +346,14 @@
     const GURL& guest_site_url) {
   DCHECK(browser_context);
   DCHECK_NE(guest_site_url, GetDefaultSiteURL());
+
+  auto guest_site_info = SiteInfo::CreateForGuest(guest_site_url);
   scoped_refptr<SiteInstanceImpl> site_instance =
       base::WrapRefCounted(new SiteInstanceImpl(new BrowsingInstance(
           browser_context,
-          CoopCoepCrossOriginIsolatedInfo::CreateNonIsolated())));
+          guest_site_info.coop_coep_cross_origin_isolated_info())));
 
-  site_instance->is_guest_ = true;
-
-  // Setting site and lock directly without the site URL conversions we
-  // do for user provided URLs. Callers expect GetSiteURL() to return the
-  // value they provide in |guest_site_url|.
-  site_instance->SetSiteInfoInternal(
-      SiteInfo(guest_site_url, guest_site_url, false /* is_origin_keyed */,
-               site_instance->GetCoopCoepCrossOriginIsolatedInfo()));
+  site_instance->SetSiteInfoInternal(guest_site_info);
 
   return site_instance;
 }
@@ -447,7 +455,7 @@
       RenderProcessHostImpl::ShouldUseProcessPerSite(browser_context,
                                                      site_info_) &&
       RenderProcessHostImpl::GetSoleProcessHostForSite(GetIsolationContext(),
-                                                       site_info_, IsGuest())) {
+                                                       site_info_)) {
     return true;
   }
 
@@ -521,7 +529,7 @@
   // different from this SiteInstance's site.
   if (!current_process->MayReuseHost() ||
       !RenderProcessHostImpl::IsSuitableHost(
-          current_process, GetIsolationContext(), site_info_, IsGuest())) {
+          current_process, GetIsolationContext(), site_info_)) {
     return;
   }
 
@@ -783,14 +791,14 @@
       return true;
     }
 
-    // Otherwise, there's no process, the site URLs don't match, and at least
+    // Otherwise, there's no process, the SiteInfos don't match, and at least
     // one of them requires a dedicated process, so it is not safe to use this
     // SiteInstance.
     return false;
   }
 
   return RenderProcessHostImpl::IsSuitableHost(
-      GetProcess(), GetIsolationContext(), site_info, IsGuest());
+      GetProcess(), GetIsolationContext(), site_info);
 }
 
 bool SiteInstanceImpl::RequiresDedicatedProcess() {
@@ -896,7 +904,7 @@
 }
 
 bool SiteInstanceImpl::IsGuest() {
-  return is_guest_;
+  return site_info_.is_guest();
 }
 
 std::string SiteInstanceImpl::GetPartitionDomain(
@@ -1448,7 +1456,7 @@
   // preassigned site.
   process_->SetIsUsed();
 
-  if (site_info_.ShouldLockProcessToSite(GetIsolationContext(), IsGuest())) {
+  if (site_info_.ShouldLockProcessToSite(GetIsolationContext())) {
     // Sanity check that this won't try to assign an origin lock to a <webview>
     // process, which can't be locked.
     CHECK(!process_->IsForGuestsOnly());
diff --git a/content/browser/site_instance_impl.h b/content/browser/site_instance_impl.h
index 2a69510..1420d0ba 100644
--- a/content/browser/site_instance_impl.h
+++ b/content/browser/site_instance_impl.h
@@ -54,6 +54,7 @@
   static SiteInfo CreateForErrorPage();
   static SiteInfo CreateForDefaultSiteInstance(
       const CoopCoepCrossOriginIsolatedInfo& cross_origin_isolated_info);
+  static SiteInfo CreateForGuest(const GURL& guest_site_url);
 
   // The SiteInfo constructor should take in all values needed for comparing two
   // SiteInfos, to help ensure all creation sites are updated accordingly when
@@ -62,7 +63,8 @@
   SiteInfo(const GURL& site_url,
            const GURL& process_lock_url,
            bool is_origin_keyed,
-           const CoopCoepCrossOriginIsolatedInfo& cross_origin_isolated_info);
+           const CoopCoepCrossOriginIsolatedInfo& cross_origin_isolated_info,
+           bool is_guest = false);
   SiteInfo();
   SiteInfo(const SiteInfo& rhs);
   ~SiteInfo();
@@ -120,6 +122,8 @@
     return coop_coep_cross_origin_isolated_info_;
   }
 
+  bool is_guest() const { return is_guest_; }
+
   // Returns false if the site_url() is empty.
   bool is_empty() const { return site_url().possibly_invalid_spec().empty(); }
 
@@ -153,11 +157,7 @@
   // be reused for different extensions.  Most of these special cases should
   // eventually be removed, and this function should become equivalent to
   // RequiresDedicatedProcess().
-  //
-  // |is_guest| should be set to true if the call is being made for a <webview>
-  // guest SiteInstance(i.e. SiteInstance::IsGuest() returns true).
-  bool ShouldLockProcessToSite(const IsolationContext& isolation_context,
-                               const bool is_guest) const;
+  bool ShouldLockProcessToSite(const IsolationContext& isolation_context) const;
 
  private:
   static auto MakeTie(const SiteInfo& site_info);
@@ -179,6 +179,9 @@
   // process allocation decisions.
   CoopCoepCrossOriginIsolatedInfo coop_coep_cross_origin_isolated_info_ =
       CoopCoepCrossOriginIsolatedInfo::CreateNonIsolated();
+
+  // Indicates this SiteInfo is for a <webview> guest.
+  bool is_guest_ = false;
 };
 
 CONTENT_EXPORT std::ostream& operator<<(std::ostream& out,
@@ -752,10 +755,6 @@
   // Whether the SiteInstance was created for a service worker.
   bool is_for_service_worker_;
 
-  // Whether the SiteInstance was created for a <webview> guest.
-  // TODO(734722): Move this into the SecurityPrincipal once it is available.
-  bool is_guest_;
-
   // How |this| was last assigned to a renderer process.
   SiteInstanceProcessAssignment process_assignment_;
 
diff --git a/content/browser/site_instance_impl_unittest.cc b/content/browser/site_instance_impl_unittest.cc
index 957493b..c153d21f 100644
--- a/content/browser/site_instance_impl_unittest.cc
+++ b/content/browser/site_instance_impl_unittest.cc
@@ -1089,7 +1089,7 @@
   host.reset(instance->GetProcess());
 
   EXPECT_FALSE(RenderProcessHostImpl::GetSoleProcessHostForSite(
-      instance->GetIsolationContext(), SiteInfo(), false));
+      instance->GetIsolationContext(), SiteInfo()));
 
   DrainMessageLoop();
 }
diff --git a/content/browser/webui/shared_resources_data_source.cc b/content/browser/webui/shared_resources_data_source.cc
index 4d47f0a..45626528 100644
--- a/content/browser/webui/shared_resources_data_source.cc
+++ b/content/browser/webui/shared_resources_data_source.cc
@@ -93,44 +93,12 @@
        "mojo/mojo/public/mojom/base/unguessable_token.mojom-lite.js"},
       {IDR_URL_MOJO_HTML, "mojo/url/mojom/url.mojom.html"},
       {IDR_URL_MOJO_JS, "mojo/url/mojom/url.mojom-lite.js"},
+      {IDR_URL_MOJOM_WEBUI_JS, "mojo/url/mojom/url.mojom-webui.js"},
       {IDR_VULKAN_INFO_MOJO_JS, "gpu/ipc/common/vulkan_info.mojom-lite.js"},
       {IDR_VULKAN_TYPES_MOJO_JS, "gpu/ipc/common/vulkan_types.mojom-lite.js"},
   };
 }
 
-const std::map<int, std::string> CreateMojoResourceIdToAliasMap() {
-  return std::map<int, std::string> {
-    {IDR_MOJO_MOJO_BINDINGS_LITE_HTML,
-     "mojo/mojo/public/js/mojo_bindings_lite.html"},
-        {IDR_MOJO_MOJO_BINDINGS_LITE_JS,
-         "mojo/mojo/public/js/mojo_bindings_lite.js"},
-        {IDR_MOJO_BIG_BUFFER_MOJOM_HTML,
-         "mojo/mojo/public/mojom/base/big_buffer.mojom.html"},
-        {IDR_MOJO_BIG_BUFFER_MOJOM_LITE_JS,
-         "mojo/mojo/public/mojom/base/big_buffer.mojom-lite.js"},
-        {IDR_MOJO_FILE_MOJOM_HTML,
-         "mojo/mojo/public/mojom/base/file.mojom.html"},
-        {IDR_MOJO_FILE_MOJOM_LITE_JS,
-         "mojo/mojo/public/mojom/base/file.mojom-lite.js"},
-        {IDR_MOJO_STRING16_MOJOM_HTML,
-         "mojo/mojo/public/mojom/base/string16.mojom.html"},
-        {IDR_MOJO_STRING16_MOJOM_LITE_JS,
-         "mojo/mojo/public/mojom/base/string16.mojom-lite.js"},
-        {IDR_MOJO_TEXT_DIRECTION_MOJOM_HTML,
-         "mojo/mojo/public/mojom/base/text_direction.mojom.html"},
-        {IDR_MOJO_TEXT_DIRECTION_MOJOM_LITE_JS,
-         "mojo/mojo/public/mojom/base/text_direction.mojom-lite.js"},
-#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \
-    defined(OS_CHROMEOS) || defined(OS_ANDROID)
-        {IDR_MOJO_TIME_MOJOM_HTML,
-         "mojo/mojo/public/mojom/base/time.mojom.html"},
-        {IDR_MOJO_TIME_MOJOM_LITE_JS,
-         "mojo/mojo/public/mojom/base/time.mojom-lite.js"},
-#endif  // defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) ||
-        // defined(OS_CHROMEOS) || defined(OS_ANDROID)
-  };
-}
-
 const std::map<int, std::string> CreateSkiaResourceIdToAliasMap() {
   return std::map<int, std::string>{
       {IDR_SKIA_BITMAP_MOJOM_LITE_JS,
@@ -248,6 +216,14 @@
   }
 }
 
+// Adds |resources| to |resources_map| using the path given by resource_path in
+// each GRD entry.
+void AddGritResourcesToMap(base::span<const GritResourceMap> resources,
+                           ResourcesMap* resources_map) {
+  for (const GritResourceMap& entry : resources)
+    AddResource(entry.name, entry.value, resources_map);
+}
+
 const ResourcesMap* CreateResourcesMap() {
   ResourcesMap* result = new ResourcesMap();
   AddResourcesToMap(result);
@@ -256,9 +232,9 @@
   AddAliasedResourcesToMap(CreateContentResourceIdToAliasMap(),
                            kMediaInternalsResources,
                            kMediaInternalsResourcesSize, result);
-  AddAliasedResourcesToMap(CreateMojoResourceIdToAliasMap(),
-                           kMojoBindingsResources, kMojoBindingsResourcesSize,
-                           result);
+  AddGritResourcesToMap(
+      base::make_span(kMojoBindingsResources, kMojoBindingsResourcesSize),
+      result);
   AddAliasedResourcesToMap(CreateSkiaResourceIdToAliasMap(), kSkiaResources,
                            kSkiaResourcesSize, result);
 #if defined(OS_CHROMEOS)
diff --git a/content/browser/webui/web_ui_mojo_browsertest.cc b/content/browser/webui/web_ui_mojo_browsertest.cc
index 43056e7..7af92a0 100644
--- a/content/browser/webui/web_ui_mojo_browsertest.cc
+++ b/content/browser/webui/web_ui_mojo_browsertest.cc
@@ -8,11 +8,9 @@
 #include "base/bind.h"
 #include "base/callback.h"
 #include "base/containers/flat_map.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
+#include "base/containers/span.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted_memory.h"
-#include "base/path_service.h"
 #include "base/run_loop.h"
 #include "base/strings/string_util.h"
 #include "base/threading/thread_restrictions.h"
@@ -29,8 +27,6 @@
 #include "content/public/browser/web_ui_data_source.h"
 #include "content/public/common/bindings_policy.h"
 #include "content/public/common/content_client.h"
-#include "content/public/common/content_paths.h"
-#include "content/public/common/content_switches.h"
 #include "content/public/common/referrer.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/common/url_utils.h"
@@ -41,7 +37,10 @@
 #include "content/public/test/test_navigation_observer.h"
 #include "content/public/test/test_utils.h"
 #include "content/shell/browser/shell.h"
-#include "content/test/data/web_ui_test_mojo_bindings.mojom.h"
+#include "content/test/data/web_ui_test.test-mojom.h"
+#include "content/test/data/web_ui_test_types.test-mojom.h"
+#include "content/test/grit/web_ui_mojo_test_resources.h"
+#include "content/test/grit/web_ui_mojo_test_resources_map.h"
 #include "mojo/public/cpp/bindings/binder_map.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/receiver.h"
@@ -49,87 +48,58 @@
 namespace content {
 namespace {
 
-bool g_got_message = false;
+const char kMojoWebUiHost[] = "mojo-web-ui";
+const char kDummyWebUiHost[] = "dummy-web-ui";
 
-base::FilePath GetFilePathForJSResource(const std::string& path) {
-  base::ScopedAllowBlockingForTesting allow_blocking;
-
-  std::string binding_path = "gen/" + path;
-#if defined(OS_WIN)
-  base::ReplaceChars(binding_path, "//", "\\", &binding_path);
-#endif
-  base::FilePath exe_dir;
-  base::PathService::Get(base::DIR_EXE, &exe_dir);
-  return exe_dir.AppendASCII(binding_path);
-}
-
-// The bindings for the page are generated from a .mojom file. This code looks
-// up the generated file from disk and returns it.
-void GetResource(const std::string& id,
-                 WebUIDataSource::GotDataCallback callback) {
-  base::ScopedAllowBlockingForTesting allow_blocking;
-
-  std::string contents;
-  if (base::EndsWith(id, ".mojom-lite.js", base::CompareCase::SENSITIVE)) {
-    CHECK(base::ReadFileToString(GetFilePathForJSResource(id), &contents))
-        << id;
-  } else {
-    base::FilePath path;
-    CHECK(base::PathService::Get(content::DIR_TEST_DATA, &path));
-    path = path.AppendASCII(id.substr(0, id.find("?")));
-    CHECK(base::ReadFileToString(path, &contents)) << path.value();
-  }
-
-  base::RefCountedString* ref_contents = new base::RefCountedString;
-  ref_contents->data() = contents;
-  std::move(callback).Run(ref_contents);
-}
-
-class BrowserTargetImpl : public mojom::BrowserTarget {
+class WebUIMojoTestCacheImpl : public mojom::WebUIMojoTestCache {
  public:
-  BrowserTargetImpl(base::RunLoop* run_loop,
-                    mojo::PendingReceiver<mojom::BrowserTarget> receiver)
-      : run_loop_(run_loop), receiver_(this, std::move(receiver)) {}
+  explicit WebUIMojoTestCacheImpl(
+      mojo::PendingReceiver<mojom::WebUIMojoTestCache> receiver)
+      : receiver_(this, std::move(receiver)) {}
 
-  ~BrowserTargetImpl() override {}
+  ~WebUIMojoTestCacheImpl() override = default;
 
-  // mojom::BrowserTarget overrides:
-  void Start(StartCallback closure) override { std::move(closure).Run(); }
-  void Stop() override {
-    g_got_message = true;
-    run_loop_->Quit();
+  // mojom::WebUIMojoTestCache overrides:
+  void Put(const GURL& url, const std::string& contents) override {
+    cache_[url] = contents;
   }
 
- protected:
-  base::RunLoop* const run_loop_;
+  void GetAll(GetAllCallback callback) override {
+    std::vector<mojom::CacheItemPtr> items;
+    for (const auto& entry : cache_)
+      items.push_back(mojom::CacheItem::New(entry.first, entry.second));
+    std::move(callback).Run(std::move(items));
+  }
 
  private:
-  mojo::Receiver<mojom::BrowserTarget> receiver_;
-  DISALLOW_COPY_AND_ASSIGN(BrowserTargetImpl);
+  mojo::Receiver<mojom::WebUIMojoTestCache> receiver_;
+  std::map<GURL, std::string> cache_;
 };
 
 // WebUIController that sets up mojo bindings.
 class TestWebUIController : public WebUIController {
  public:
-  TestWebUIController(WebUI* web_ui,
-                      base::RunLoop* run_loop,
-                      int bindings = BINDINGS_POLICY_MOJO_WEB_UI)
-      : WebUIController(web_ui), run_loop_(run_loop) {
+  explicit TestWebUIController(WebUI* web_ui,
+                               int bindings = BINDINGS_POLICY_MOJO_WEB_UI)
+      : WebUIController(web_ui) {
+    const base::span<const GritResourceMap> kMojoWebUiResources =
+        base::make_span(kWebUiMojoTestResources, kWebUiMojoTestResourcesSize);
+
     web_ui->SetBindings(bindings);
     {
-      WebUIDataSource* data_source = WebUIDataSource::Create("mojo-web-ui");
+      WebUIDataSource* data_source = WebUIDataSource::Create(kMojoWebUiHost);
       data_source->OverrideContentSecurityPolicy(
           network::mojom::CSPDirectiveName::ScriptSrc,
           "script-src chrome://resources 'self' 'unsafe-eval';");
       data_source->DisableTrustedTypesCSP();
-      data_source->SetRequestFilter(
-          base::BindRepeating([](const std::string& path) { return true; }),
-          base::BindRepeating(&GetResource));
+      for (const GritResourceMap& resource : kMojoWebUiResources)
+        data_source->AddResourcePath(resource.name, resource.value);
+      data_source->AddResourcePath("", IDR_WEB_UI_MOJO_HTML);
       WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(),
                            data_source);
     }
     {
-      WebUIDataSource* data_source = WebUIDataSource::Create("dummy-web-ui");
+      WebUIDataSource* data_source = WebUIDataSource::Create(kDummyWebUiHost);
       data_source->SetRequestFilter(
           base::BindRepeating([](const std::string& path) { return true; }),
           base::BindRepeating([](const std::string& id,
@@ -142,40 +112,34 @@
   }
 
  protected:
-  base::RunLoop* const run_loop_;
-  std::unique_ptr<BrowserTargetImpl> browser_target_;
+  std::unique_ptr<WebUIMojoTestCacheImpl> cache_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(TestWebUIController);
 };
 
-// TestWebUIController that additionally creates the ping test BrowserTarget
-// implementation at the right time.
-class PingTestWebUIController : public TestWebUIController {
+// TestWebUIController that can bind a WebUIMojoTestCache interface when
+// requested by the page.
+class CacheTestWebUIController : public TestWebUIController {
  public:
-  PingTestWebUIController(WebUI* web_ui, base::RunLoop* run_loop)
-      : TestWebUIController(web_ui, run_loop) {}
+  explicit CacheTestWebUIController(WebUI* web_ui)
+      : TestWebUIController(web_ui) {}
+  ~CacheTestWebUIController() override = default;
 
-  ~PingTestWebUIController() override {}
-
-  void CreateHandler(mojo::PendingReceiver<mojom::BrowserTarget> receiver) {
-    browser_target_ =
-        std::make_unique<BrowserTargetImpl>(run_loop_, std::move(receiver));
+  void CreateHandler(
+      mojo::PendingReceiver<mojom::WebUIMojoTestCache> receiver) {
+    cache_ = std::make_unique<WebUIMojoTestCacheImpl>(std::move(receiver));
   }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(PingTestWebUIController);
 };
 
 // WebUIControllerFactory that creates TestWebUIController.
 class TestWebUIControllerFactory : public WebUIControllerFactory {
  public:
   TestWebUIControllerFactory()
-      : run_loop_(nullptr),
-        registered_controllers_(
-            {{"ping", base::BindRepeating(
-                          &TestWebUIControllerFactory::CreatePingController,
-                          base::Unretained(this))},
+      : registered_controllers_(
+            {{"cache", base::BindRepeating(
+                           &TestWebUIControllerFactory::CreateCacheController,
+                           base::Unretained(this))},
              {"hybrid", base::BindRepeating(
                             &TestWebUIControllerFactory::CreateHybridController,
                             base::Unretained(this))},
@@ -184,8 +148,6 @@
                   &TestWebUIControllerFactory::CreateWebUIController,
                   base::Unretained(this))}}) {}
 
-  void set_run_loop(base::RunLoop* run_loop) { run_loop_ = run_loop; }
-
   std::unique_ptr<WebUIController> CreateWebUIControllerForURL(
       WebUI* web_ui,
       const GURL& url) override {
@@ -196,7 +158,7 @@
     if (it != registered_controllers_.end())
       return it->second.Run(web_ui);
 
-    return std::make_unique<TestWebUIController>(web_ui, run_loop_);
+    return std::make_unique<TestWebUIController>(web_ui);
   }
 
   WebUI::TypeID GetWebUIType(BrowserContext* browser_context,
@@ -219,22 +181,20 @@
   void set_web_ui_enabled(bool enabled) { web_ui_enabled_ = enabled; }
 
  private:
-  std::unique_ptr<WebUIController> CreatePingController(WebUI* web_ui) {
-    return std::make_unique<PingTestWebUIController>(web_ui, run_loop_);
+  std::unique_ptr<WebUIController> CreateCacheController(WebUI* web_ui) {
+    return std::make_unique<CacheTestWebUIController>(web_ui);
   }
 
   std::unique_ptr<WebUIController> CreateHybridController(WebUI* web_ui) {
     return std::make_unique<TestWebUIController>(
-        web_ui, run_loop_,
-        BINDINGS_POLICY_WEB_UI | BINDINGS_POLICY_MOJO_WEB_UI);
+        web_ui, BINDINGS_POLICY_WEB_UI | BINDINGS_POLICY_MOJO_WEB_UI);
   }
 
   std::unique_ptr<WebUIController> CreateWebUIController(WebUI* web_ui) {
-    return std::make_unique<TestWebUIController>(web_ui, run_loop_,
+    return std::make_unique<TestWebUIController>(web_ui,
                                                  BINDINGS_POLICY_WEB_UI);
   }
 
-  base::RunLoop* run_loop_;
   bool web_ui_enabled_ = true;
   const base::flat_map<
       std::string,
@@ -256,14 +216,15 @@
   void RegisterBrowserInterfaceBindersForFrame(
       RenderFrameHost* render_frame_host,
       mojo::BinderMapWithContext<content::RenderFrameHost*>* map) override {
-    map->Add<mojom::BrowserTarget>(
-        base::BindRepeating(&TestWebUIContentBrowserClient::BindBrowserTarget,
-                            base::Unretained(this)));
+    map->Add<mojom::WebUIMojoTestCache>(base::BindRepeating(
+        &TestWebUIContentBrowserClient::BindTestCache, base::Unretained(this)));
   }
-  void BindBrowserTarget(content::RenderFrameHost* render_frame_host,
-                         mojo::PendingReceiver<mojom::BrowserTarget> receiver) {
+  void BindTestCache(
+      content::RenderFrameHost* render_frame_host,
+      mojo::PendingReceiver<mojom::WebUIMojoTestCache> receiver) {
     auto* contents = WebContents::FromRenderFrameHost(render_frame_host);
-    static_cast<PingTestWebUIController*>(contents->GetWebUI()->GetController())
+    static_cast<CacheTestWebUIController*>(
+        contents->GetWebUI()->GetController())
         ->CreateHandler(std::move(receiver));
   }
 };
@@ -283,8 +244,9 @@
   void NavigateWithNewWebUI(const std::string& path) {
     // Load a dummy WebUI URL first so that a new WebUI is set up when we load
     // the URL we're actually interested in.
-    EXPECT_TRUE(NavigateToURL(shell(), GetWebUIURL("dummy-web-ui")));
-    EXPECT_TRUE(NavigateToURL(shell(), GetWebUIURL("mojo-web-ui/" + path)));
+    EXPECT_TRUE(NavigateToURL(shell(), GetWebUIURL(kDummyWebUiHost)));
+    EXPECT_TRUE(NavigateToURL(
+        shell(), GetWebUIURL(kMojoWebUiHost + std::string("/") + path)));
   }
 
   // Run |script| and return a boolean result.
@@ -314,78 +276,50 @@
   DISALLOW_COPY_AND_ASSIGN(WebUIMojoTest);
 };
 
-bool IsGeneratedResourceAvailable(const std::string& resource_path) {
-  // Currently there is no way to have a generated file included in the isolate
-  // files. If the bindings file doesn't exist assume we're on such a bot and
-  // pass.
-  // TODO(sky): remove this conditional when isolates support copying from gen.
-  base::ScopedAllowBlockingForTesting allow_blocking;
-  const base::FilePath test_file_path(GetFilePathForJSResource(resource_path));
-  if (base::PathExists(test_file_path))
-    return true;
-  LOG(WARNING) << " mojom binding file doesn't exist, assuming on isolate";
-  return false;
-}
+// Loads a WebUI page that contains Mojo JS bindings and verifies a message
+// round-trip between the page and the browser.
+IN_PROC_BROWSER_TEST_F(WebUIMojoTest, EndToEndCommunication) {
+  GURL kTestUrl(GetWebUIURL(std::string(kMojoWebUiHost) + "/?cache"));
+  const std::string kTestScript = "runTest();";
+  bool passed = false;
+  EXPECT_TRUE(NavigateToURL(shell(), kTestUrl));
+  EXPECT_TRUE(ExecuteScriptAndExtractBool(shell()->web_contents(), kTestScript,
+                                          &passed));
+  EXPECT_TRUE(passed);
 
-// Loads a webui page that contains mojo bindings and verifies a message makes
-// it from the browser to the page and back.
-IN_PROC_BROWSER_TEST_F(WebUIMojoTest, EndToEndPing) {
-  if (!IsGeneratedResourceAvailable(
-          "content/test/data/web_ui_test_mojo_bindings.mojom-lite.js"))
-    return;
-  GURL test_url(GetWebUIURL("mojo-web-ui/web_ui_mojo.html?ping"));
+  // Check that a second shell works correctly.
+  passed = false;
+  Shell* other_shell = CreateBrowser();
+  EXPECT_TRUE(NavigateToURL(other_shell, kTestUrl));
+  EXPECT_TRUE(ExecuteScriptAndExtractBool(other_shell->web_contents(),
+                                          kTestScript, &passed));
+  EXPECT_TRUE(passed);
 
-  {
-    g_got_message = false;
-    base::RunLoop run_loop;
-    factory()->set_run_loop(&run_loop);
-    EXPECT_TRUE(NavigateToURL(shell(), test_url));
-    // RunLoop is quit when message received from page.
-    run_loop.Run();
-    EXPECT_TRUE(g_got_message);
-  }
+  // We expect two independent chrome://foo tabs/shells to use a separate
+  // process.
+  EXPECT_NE(shell()->web_contents()->GetMainFrame()->GetProcess(),
+            other_shell->web_contents()->GetMainFrame()->GetProcess());
 
-  {
-    // Check that a second shell works correctly.
-    Shell* other_shell = CreateBrowser();
-    g_got_message = false;
-    base::RunLoop other_run_loop;
-    factory()->set_run_loop(&other_run_loop);
-    EXPECT_TRUE(NavigateToURL(other_shell, test_url));
-    // RunLoop is quit when message received from page.
-    other_run_loop.Run();
-    EXPECT_TRUE(g_got_message);
+  // Close the second shell and wait until its process exits.
+  RenderProcessHostWatcher process_watcher(
+      other_shell->web_contents()->GetMainFrame()->GetProcess(),
+      RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
+  other_shell->Close();
+  process_watcher.Wait();
 
-    // We expect two independent chrome://foo tabs/shells to use a separate
-    // process.
-    EXPECT_NE(shell()->web_contents()->GetMainFrame()->GetProcess(),
-              other_shell->web_contents()->GetMainFrame()->GetProcess());
+  // Check that a third shell works correctly, even if we force it to share a
+  // process with the first shell, by forcing an artificially low process
+  // limit.
+  RenderProcessHost::SetMaxRendererProcessCount(1);
 
-    // Close the second shell and wait until its process exits.
-    RenderProcessHostWatcher process_watcher(
-        other_shell->web_contents()->GetMainFrame()->GetProcess(),
-        RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
-    other_shell->Close();
-    process_watcher.Wait();
-  }
-
-  {
-    // Check that a third shell works correctly, even if we force it to share a
-    // process with the first shell, by forcing an artificially low process
-    // limit.
-    RenderProcessHost::SetMaxRendererProcessCount(1);
-
-    Shell* other_shell = CreateBrowser();
-    g_got_message = false;
-    base::RunLoop other_run_loop;
-    factory()->set_run_loop(&other_run_loop);
-    EXPECT_TRUE(NavigateToURL(other_shell, test_url));
-    // RunLoop is quit when message received from page.
-    other_run_loop.Run();
-    EXPECT_TRUE(g_got_message);
-    EXPECT_EQ(shell()->web_contents()->GetMainFrame()->GetProcess(),
-              other_shell->web_contents()->GetMainFrame()->GetProcess());
-  }
+  other_shell = CreateBrowser();
+  passed = false;
+  EXPECT_TRUE(NavigateToURL(other_shell, kTestUrl));
+  EXPECT_EQ(shell()->web_contents()->GetMainFrame()->GetProcess(),
+            other_shell->web_contents()->GetMainFrame()->GetProcess());
+  EXPECT_TRUE(ExecuteScriptAndExtractBool(other_shell->web_contents(),
+                                          kTestScript, &passed));
+  EXPECT_TRUE(passed);
 }
 
 // Disabled due to flakiness: crbug.com/860385.
@@ -445,8 +379,8 @@
 }
 
 IN_PROC_BROWSER_TEST_F(WebUIMojoTest, ChromeSendAvailable_AfterCrash) {
-  GURL test_url(
-      GetWebUIURL("mojo-web-ui/web_ui_mojo_native.html?webui_bindings"));
+  GURL test_url(GetWebUIURL(std::string(kMojoWebUiHost) +
+                            "/web_ui_mojo_native.html?webui_bindings"));
 
   // Navigate with normal WebUI bindings and ensure chrome.send is available.
   EXPECT_TRUE(NavigateToURL(shell(), test_url));
diff --git a/content/content_resources.grd b/content/content_resources.grd
index a29870c..4a553b6 100644
--- a/content/content_resources.grd
+++ b/content/content_resources.grd
@@ -35,6 +35,7 @@
       <include name="IDR_UNGUESSABLE_TOKEN_MOJO_JS" file="${root_gen_dir}/mojo/public/mojom/base/unguessable_token.mojom-lite.js" use_base_dir="false" type="BINDATA" />
       <include name="IDR_URL_MOJO_HTML" file="${root_gen_dir}/url/mojom/url.mojom.html" use_base_dir="false" type="BINDATA" />
       <include name="IDR_URL_MOJO_JS" file="${root_gen_dir}/url/mojom/url.mojom-lite.js" use_base_dir="false" type="BINDATA" />
+      <include name="IDR_URL_MOJOM_WEBUI_JS" file="${root_gen_dir}/mojom-webui/url/mojom/url.mojom-webui.js" use_base_dir="false" type="BINDATA" />
       <include name="IDR_VULKAN_INFO_MOJO_JS" file="${root_gen_dir}/gpu/ipc/common/vulkan_info.mojom-lite.js" use_base_dir="false" type="BINDATA" />
       <include name="IDR_VULKAN_TYPES_MOJO_JS" file="${root_gen_dir}/gpu/ipc/common/vulkan_types.mojom-lite.js" use_base_dir="false" type="BINDATA" />
     </includes>
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index ae5ec31..7922e6a 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -511,16 +511,6 @@
 const base::Feature kDirectSockets{"DirectSockets",
                                    base::FEATURE_DISABLED_BY_DEFAULT};
 
-// Controls whether FileURLLoaderFactory can fetch additional files based on the
-// isolated world's origin. This feature is disabled by default because we want
-// content scripts to have the same permissions as the page they are injected
-// into. This feature makes it possible to quickly revert to earlier permissive
-// behavior if significant regressions are detected. See
-// https://crbug.com/1049604.
-const base::Feature kRelaxIsolatedWorldCorsInFileUrlLoaderFactory = {
-    "RelaxIsolatedWorldCorsInFileUrlLoaderFactory",
-    base::FEATURE_DISABLED_BY_DEFAULT};
-
 // Causes hidden tabs with crashed subframes to be marked for reload, meaning
 // that if a user later switches to that tab, the current page will be
 // reloaded.  This will hide crashed subframes from the user at the cost of
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
index dc467f8..94acb9c 100644
--- a/content/public/common/content_features.h
+++ b/content/public/common/content_features.h
@@ -111,8 +111,6 @@
     kProcessSharingWithStrictSiteInstances;
 CONTENT_EXPORT extern const base::Feature kPushSubscriptionChangeEvent;
 CONTENT_EXPORT extern const base::Feature kDirectSockets;
-CONTENT_EXPORT extern const base::Feature
-    kRelaxIsolatedWorldCorsInFileUrlLoaderFactory;
 CONTENT_EXPORT extern const base::Feature kReloadHiddenTabsWithCrashedSubframes;
 CONTENT_EXPORT extern const base::Feature kRenderDocument;
 CONTENT_EXPORT extern const base::Feature kRequestUnbufferedDispatch;
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index 2a78ee8..6b2e25e 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -135,8 +135,6 @@
     "mhtml_handle_writer.h",
     "mojo/blink_interface_registry_impl.cc",
     "mojo/blink_interface_registry_impl.h",
-    "mouse_lock_dispatcher.cc",
-    "mouse_lock_dispatcher.h",
     "navigation_client.cc",
     "navigation_client.h",
     "navigation_state.cc",
@@ -160,8 +158,6 @@
     "render_widget.cc",
     "render_widget.h",
     "render_widget_delegate.h",
-    "render_widget_mouse_lock_dispatcher.cc",
-    "render_widget_mouse_lock_dispatcher.h",
     "renderer_blink_platform_impl.cc",
     "renderer_blink_platform_impl.h",
     "renderer_main.cc",
diff --git a/content/renderer/mouse_lock_dispatcher.cc b/content/renderer/mouse_lock_dispatcher.cc
deleted file mode 100644
index d322228..0000000
--- a/content/renderer/mouse_lock_dispatcher.cc
+++ /dev/null
@@ -1,147 +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.
-
-#include "content/renderer/mouse_lock_dispatcher.h"
-
-#include "base/check.h"
-#include "third_party/blink/public/common/input/web_input_event.h"
-
-namespace content {
-
-MouseLockDispatcher::MouseLockDispatcher()
-    : pending_lock_request_(false),
-      pending_unlock_request_(false),
-      target_(nullptr) {}
-
-MouseLockDispatcher::~MouseLockDispatcher() = default;
-
-bool MouseLockDispatcher::LockMouse(
-    LockTarget* target,
-    blink::WebLocalFrame* requester_frame,
-    blink::WebWidgetClient::PointerLockCallback callback,
-    bool request_unadjusted_movement) {
-  if (MouseLockedOrPendingAction())
-    return false;
-
-  pending_lock_request_ = true;
-  target_ = target;
-
-  lock_mouse_callback_ = std::move(callback);
-
-  SendLockMouseRequest(requester_frame, request_unadjusted_movement);
-  return true;
-}
-
-bool MouseLockDispatcher::ChangeMouseLock(
-    LockTarget* target,
-    blink::WebLocalFrame* requester_frame,
-    blink::WebWidgetClient::PointerLockCallback callback,
-    bool request_unadjusted_movement) {
-  if (!mouse_lock_context_)
-    return false;
-
-  lock_mouse_callback_ = std::move(callback);
-  // Unretained is safe because |this| owns the mojo::Remote
-  mouse_lock_context_->RequestMouseLockChange(
-      request_unadjusted_movement,
-      base::BindOnce(&MouseLockDispatcher::OnChangeLockAck,
-                     base::Unretained(this)));
-  return true;
-}
-
-void MouseLockDispatcher::FlushContextPipeForTesting() {
-  if (mouse_lock_context_)
-    mouse_lock_context_.FlushForTesting();
-}
-
-void MouseLockDispatcher::UnlockMouse(LockTarget* target) {
-  if (IsMouseLockedTo(target)) {
-    mouse_lock_context_.reset();
-    target->OnMouseLockLost();
-  }
-}
-
-void MouseLockDispatcher::OnLockTargetDestroyed(LockTarget* target) {
-  if (target == target_) {
-    UnlockMouse(target);
-    target_ = nullptr;
-  }
-}
-
-void MouseLockDispatcher::ClearLockTarget() {
-  OnLockTargetDestroyed(target_);
-}
-
-bool MouseLockDispatcher::IsMouseLockedTo(LockTarget* target) {
-  return mouse_lock_context_ && target_ == target;
-}
-
-bool MouseLockDispatcher::WillHandleMouseEvent(
-    const blink::WebMouseEvent& event) {
-  if (mouse_lock_context_ && target_)
-    return target_->HandleMouseLockedInputEvent(event);
-  return false;
-}
-
-void MouseLockDispatcher::OnChangeLockAck(
-    blink::mojom::PointerLockResult result) {
-  pending_lock_request_ = false;
-  if (lock_mouse_callback_) {
-    std::move(lock_mouse_callback_).Run(result);
-  }
-}
-
-void MouseLockDispatcher::OnLockMouseACK(
-    blink::mojom::PointerLockResult result,
-    blink::CrossVariantMojoRemote<blink::mojom::PointerLockContextInterfaceBase>
-        context) {
-  DCHECK(!mouse_lock_context_ && pending_lock_request_);
-
-  pending_lock_request_ = false;
-  if (pending_unlock_request_ && !context) {
-    // We have sent an unlock request after the lock request. However, since
-    // the lock request has failed, the unlock request will be ignored by the
-    // browser side and there won't be any response to it.
-    pending_unlock_request_ = false;
-  }
-
-  if (context) {
-    mouse_lock_context_.Bind(std::move(context));
-    // The browser might unlock the mouse for many reasons including closing
-    // the tab, the user hitting esc, the page losing focus, and more.
-    mouse_lock_context_.set_disconnect_handler(base::BindOnce(
-        &MouseLockDispatcher::OnMouseLockLost, base::Unretained(this)));
-  }
-
-  if (lock_mouse_callback_)
-    std::move(lock_mouse_callback_).Run(result);
-
-  LockTarget* last_target = target_;
-  if (!mouse_lock_context_)
-    target_ = nullptr;
-
-  // Callbacks made after all state modification to prevent reentrant errors
-  // such as OnLockMouseACK() synchronously calling LockMouse().
-
-  if (last_target)
-    last_target->OnLockMouseACK(result ==
-                                blink::mojom::PointerLockResult::kSuccess);
-}
-
-void MouseLockDispatcher::OnMouseLockLost() {
-  DCHECK(mouse_lock_context_ && !pending_lock_request_);
-  mouse_lock_context_.reset();
-  pending_unlock_request_ = false;
-
-  LockTarget* last_target = target_;
-  target_ = nullptr;
-
-  // Callbacks made after all state modification to prevent reentrant errors
-  // such as OnMouseLockLost() synchronously calling LockMouse().
-
-  if (last_target)
-    last_target->OnMouseLockLost();
-}
-
-}  // namespace content
diff --git a/content/renderer/mouse_lock_dispatcher.h b/content/renderer/mouse_lock_dispatcher.h
deleted file mode 100644
index 60f0792..0000000
--- a/content/renderer/mouse_lock_dispatcher.h
+++ /dev/null
@@ -1,106 +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.
-
-#ifndef CONTENT_RENDERER_MOUSE_LOCK_DISPATCHER_H_
-#define CONTENT_RENDERER_MOUSE_LOCK_DISPATCHER_H_
-
-#include "base/macros.h"
-#include "content/common/content_export.h"
-#include "mojo/public/cpp/bindings/remote.h"
-#include "third_party/blink/public/mojom/input/pointer_lock_context.mojom.h"
-#include "third_party/blink/public/web/web_widget_client.h"
-
-namespace blink {
-class WebMouseEvent;
-class WebLocalFrame;
-}  // namespace blink
-
-namespace content {
-
-class CONTENT_EXPORT MouseLockDispatcher {
- public:
-  MouseLockDispatcher();
-  virtual ~MouseLockDispatcher();
-
-  class LockTarget {
-   public:
-    virtual ~LockTarget() {}
-    // A mouse lock request was pending and this reports success or failure.
-    virtual void OnLockMouseACK(bool succeeded) = 0;
-    // A mouse lock was in place, but has been lost.
-    virtual void OnMouseLockLost() = 0;
-    // A mouse lock is enabled and mouse events are being delievered.
-    virtual bool HandleMouseLockedInputEvent(
-        const blink::WebMouseEvent& event) = 0;
-  };
-
-  // Locks the mouse to |target| if |requester_frame| has transient user
-  // activation. If true is returned, an asynchronous response to
-  // target->OnLockMouseACK() will follow.
-  bool LockMouse(LockTarget* target,
-                 blink::WebLocalFrame* requester_frame,
-                 blink::WebWidgetClient::PointerLockCallback callback,
-                 bool request_unadjusted_movement);
-  bool ChangeMouseLock(LockTarget* target,
-                       blink::WebLocalFrame* requester_frame,
-                       blink::WebWidgetClient::PointerLockCallback callback,
-                       bool request_unadjusted_movement);
-  // Request to unlock the mouse. This call destroys the |mouse_lock_context_|.
-  // A response to target->OnMouseLockLost() will follow.
-  void UnlockMouse(LockTarget* target);
-  // Clears out the reference to the |target| because it has or is being
-  // destroyed. Unlocks if locked. The pointer will not be accessed.
-  void OnLockTargetDestroyed(LockTarget* target);
-  // Clears out any reference to a lock target. Unlocks if locked.
-  void ClearLockTarget();
-  bool IsMouseLockedTo(LockTarget* target);
-
-  // Allow lock target to consumed a mouse event, if it does return true.
-  bool WillHandleMouseEvent(const blink::WebMouseEvent& event);
-
-  // Subclasses or users have to call these methods to report mouse lock events
-  // from the browser.
-  void OnLockMouseACK(
-      blink::mojom::PointerLockResult result,
-      blink::CrossVariantMojoRemote<
-          blink::mojom::PointerLockContextInterfaceBase> context);
-  void OnChangeLockAck(blink::mojom::PointerLockResult result);
-
-  void FlushContextPipeForTesting();
-
- protected:
-  // Subclasses must implement these methods to send mouse lock requests to the
-  // browser.
-  virtual void SendLockMouseRequest(blink::WebLocalFrame* requester_frame,
-                                    bool request_unadjusted_movement) = 0;
-
- private:
-  bool MouseLockedOrPendingAction() const {
-    return mouse_lock_context_ || pending_lock_request_ ||
-           pending_unlock_request_;
-  }
-
-  void OnMouseLockLost();
-
-  // If both |pending_lock_request_| and |pending_unlock_request_| are true,
-  // it means a lock request was sent before an unlock request and we haven't
-  // received responses for them. The logic in LockMouse() makes sure that a
-  // lock request won't be sent when there is a pending unlock request.
-  bool pending_lock_request_;
-  bool pending_unlock_request_;
-  mojo::Remote<blink::mojom::PointerLockContext> mouse_lock_context_;
-
-  blink::WebWidgetClient::PointerLockCallback lock_mouse_callback_;
-
-  // |target_| is the pending or current owner of mouse lock. We retain a non
-  // owning reference here that must be cleared by |OnLockTargetDestroyed|
-  // when it is destroyed.
-  LockTarget* target_;
-
-  DISALLOW_COPY_AND_ASSIGN(MouseLockDispatcher);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_RENDERER_MOUSE_LOCK_DISPATCHER_H_
diff --git a/content/renderer/mouse_lock_dispatcher_browsertest.cc b/content/renderer/mouse_lock_dispatcher_browsertest.cc
deleted file mode 100644
index af32de7..0000000
--- a/content/renderer/mouse_lock_dispatcher_browsertest.cc
+++ /dev/null
@@ -1,305 +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.
-
-#include <string>
-
-#include "content/common/widget_messages.h"
-#include "content/public/test/render_view_test.h"
-#include "content/renderer/mouse_lock_dispatcher.h"
-#include "content/renderer/render_view_impl.h"
-#include "mojo/public/cpp/bindings/self_owned_receiver.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/common/input/web_mouse_event.h"
-
-using ::testing::_;
-
-namespace content {
-namespace {
-
-class MockLockTarget : public MouseLockDispatcher::LockTarget {
- public:
-   MOCK_METHOD1(OnLockMouseACK, void(bool));
-   MOCK_METHOD0(OnMouseLockLost, void());
-   MOCK_METHOD1(HandleMouseLockedInputEvent,
-                bool(const blink::WebMouseEvent&));
-};
-
-class PointerLockContextImpl : public blink::mojom::PointerLockContext {
- public:
-  void RequestMouseLockChange(
-      bool unadjusted_movement,
-      PointerLockContext::RequestMouseLockChangeCallback response) override {}
-};
-
-// MouseLockDispatcher is a RenderViewObserver, and we test it by creating a
-// fixture containing a RenderViewImpl view() and interacting to that interface.
-class MouseLockDispatcherTest : public RenderViewTest {
- public:
-  void SetUp() override {
-    RenderViewTest::SetUp();
-    route_id_ = widget()->routing_id();
-    target_ = new MockLockTarget();
-    alternate_target_ = new MockLockTarget();
-  }
-
-  void TearDown() override {
-    RenderViewTest::TearDown();
-    delete target_;
-    delete alternate_target_;
-  }
-
- protected:
-  RenderViewImpl* view() { return static_cast<RenderViewImpl*>(view_); }
-  RenderWidget* widget() {
-    return view()->GetMainRenderFrame()->GetLocalRootRenderWidget();
-  }
-  MouseLockDispatcher* dispatcher() {
-    return widget()->mouse_lock_dispatcher();
-  }
-  int route_id_;
-  MockLockTarget* target_;
-  MockLockTarget* alternate_target_;
-};
-
-}  // namespace
-
-// Test simple use of RenderViewImpl interface for pointer lock.
-TEST_F(MouseLockDispatcherTest, BasicWebWidget) {
-  // Start unlocked.
-  EXPECT_FALSE(widget()->IsPointerLocked());
-
-  // Lock.
-  EXPECT_TRUE(widget()->RequestPointerLock(
-      view()->GetMainRenderFrame()->GetWebFrame(), base::DoNothing(),
-      false /* unadjusted_movement */));
-
-  mojo::PendingRemote<blink::mojom::PointerLockContext> remote_context;
-  auto receiver_context = mojo::MakeSelfOwnedReceiver(
-      std::make_unique<PointerLockContextImpl>(),
-      remote_context.InitWithNewPipeAndPassReceiver());
-  dispatcher()->OnLockMouseACK(blink::mojom::PointerLockResult::kSuccess,
-                               std::move(remote_context));
-  EXPECT_TRUE(widget()->IsPointerLocked());
-
-  // Unlock.
-  widget()->RequestPointerUnlock();
-  receiver_context->Close();
-  dispatcher()->FlushContextPipeForTesting();
-  EXPECT_FALSE(widget()->IsPointerLocked());
-
-  // Attempt a lock, and have it fail.
-  EXPECT_TRUE(widget()->RequestPointerLock(
-      view()->GetMainRenderFrame()->GetWebFrame(), base::DoNothing(),
-      false /* unadjusted_movement */));
-  dispatcher()->OnLockMouseACK(blink::mojom::PointerLockResult::kUnknownError,
-                               mojo::NullRemote());
-  EXPECT_FALSE(widget()->IsPointerLocked());
-}
-
-// Test simple use of MouseLockDispatcher with a mock LockTarget.
-TEST_F(MouseLockDispatcherTest, BasicMockLockTarget) {
-  ::testing::InSequence expect_calls_in_sequence;
-  EXPECT_CALL(*target_, OnLockMouseACK(/*succeeded=*/true));
-  EXPECT_CALL(*target_, HandleMouseLockedInputEvent(_));
-  EXPECT_CALL(*target_, OnMouseLockLost());
-  EXPECT_CALL(*target_, OnLockMouseACK(/*succeeded=*/false));
-
-  // Start unlocked.
-  EXPECT_FALSE(dispatcher()->IsMouseLockedTo(nullptr));
-  EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
-
-  // Lock.
-  EXPECT_TRUE(dispatcher()->LockMouse(
-      target_, view()->GetMainRenderFrame()->GetWebFrame(), base::DoNothing(),
-      false /* unadjusted_movement */));
-  mojo::PendingRemote<blink::mojom::PointerLockContext> remote_context;
-  auto receiver_context = mojo::MakeSelfOwnedReceiver(
-      std::make_unique<PointerLockContextImpl>(),
-      remote_context.InitWithNewPipeAndPassReceiver());
-  dispatcher()->OnLockMouseACK(blink::mojom::PointerLockResult::kSuccess,
-                               std::move(remote_context));
-  EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
-
-  // Receive mouse event.
-  dispatcher()->WillHandleMouseEvent(blink::WebMouseEvent());
-
-  // Unlock.
-  receiver_context->Close();
-  dispatcher()->FlushContextPipeForTesting();
-  EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
-
-  // Attempt a lock, and have it fail.
-  EXPECT_TRUE(dispatcher()->LockMouse(
-      target_, view()->GetMainRenderFrame()->GetWebFrame(), base::DoNothing(),
-      false /* unadjusted_movement */));
-  dispatcher()->OnLockMouseACK(blink::mojom::PointerLockResult::kUnknownError,
-                               mojo::NullRemote());
-  EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
-}
-
-// Test deleting a target while it is in use by MouseLockDispatcher.
-TEST_F(MouseLockDispatcherTest, DeleteAndUnlock) {
-  ::testing::InSequence expect_calls_in_sequence;
-  EXPECT_CALL(*target_, OnLockMouseACK(/*succeeded=*/true));
-  EXPECT_CALL(*target_, HandleMouseLockedInputEvent(_)).Times(0);
-  EXPECT_CALL(*target_, OnMouseLockLost()).Times(1);
-
-  // Lock.
-  EXPECT_TRUE(dispatcher()->LockMouse(
-      target_, view()->GetMainRenderFrame()->GetWebFrame(), base::DoNothing(),
-      false /* unadjusted_movement */));
-  mojo::PendingRemote<blink::mojom::PointerLockContext> remote_context;
-  auto receiver_context = mojo::MakeSelfOwnedReceiver(
-      std::make_unique<PointerLockContextImpl>(),
-      remote_context.InitWithNewPipeAndPassReceiver());
-  dispatcher()->OnLockMouseACK(blink::mojom::PointerLockResult::kSuccess,
-                               std::move(remote_context));
-  EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
-
-  // Unlock, with a deleted target and context destruction.
-  // Don't receive mouse events.
-  dispatcher()->OnLockTargetDestroyed(target_);
-  delete target_;
-  target_ = nullptr;
-  dispatcher()->WillHandleMouseEvent(blink::WebMouseEvent());
-  receiver_context->Close();
-  dispatcher()->FlushContextPipeForTesting();
-  EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
-}
-
-// Test deleting a target that is pending a lock request response.
-TEST_F(MouseLockDispatcherTest, DeleteWithPendingLockSuccess) {
-  ::testing::InSequence expect_calls_in_sequence;
-  EXPECT_CALL(*target_, OnLockMouseACK(/*succeeded=*/true)).Times(0);
-  EXPECT_CALL(*target_, OnMouseLockLost()).Times(0);
-
-  // Lock request.
-  EXPECT_TRUE(dispatcher()->LockMouse(
-      target_, view()->GetMainRenderFrame()->GetWebFrame(), base::DoNothing(),
-      false /* unadjusted_movement */));
-
-  // Before receiving response delete the target.
-  dispatcher()->OnLockTargetDestroyed(target_);
-  delete target_;
-  target_ = nullptr;
-
-  // Lock response.
-  mojo::PendingRemote<blink::mojom::PointerLockContext> context;
-  dispatcher()->OnLockMouseACK(blink::mojom::PointerLockResult::kSuccess,
-                               std::move(context));
-}
-
-// Test deleting a target that is pending a lock request failure response.
-TEST_F(MouseLockDispatcherTest, DeleteWithPendingLockFail) {
-  ::testing::InSequence expect_calls_in_sequence;
-  EXPECT_CALL(*target_, OnLockMouseACK(/*succeeded=*/true)).Times(0);
-  EXPECT_CALL(*target_, OnMouseLockLost()).Times(0);
-
-  // Lock request.
-  EXPECT_TRUE(dispatcher()->LockMouse(
-      target_, view()->GetMainRenderFrame()->GetWebFrame(), base::DoNothing(),
-      false /* unadjusted_movement */));
-
-  // Before receiving response delete the target.
-  dispatcher()->OnLockTargetDestroyed(target_);
-  delete target_;
-  target_ = nullptr;
-
-  // Lock response.
-  dispatcher()->OnLockMouseACK(blink::mojom::PointerLockResult::kUnknownError,
-                               mojo::NullRemote());
-}
-
-// Test not receiving mouse events when a target is not locked.
-TEST_F(MouseLockDispatcherTest, MouseEventsNotReceived) {
-  ::testing::InSequence expect_calls_in_sequence;
-  EXPECT_CALL(*target_, HandleMouseLockedInputEvent(_)).Times(0);
-  EXPECT_CALL(*target_, OnLockMouseACK(/*succeeded=*/true));
-  EXPECT_CALL(*target_, HandleMouseLockedInputEvent(_));
-  EXPECT_CALL(*target_, OnMouseLockLost());
-  EXPECT_CALL(*target_, HandleMouseLockedInputEvent(_)).Times(0);
-
-  // (Don't) receive mouse event.
-  dispatcher()->WillHandleMouseEvent(blink::WebMouseEvent());
-
-  // Lock.
-  EXPECT_TRUE(dispatcher()->LockMouse(
-      target_, view()->GetMainRenderFrame()->GetWebFrame(), base::DoNothing(),
-      false /* unadjusted_movement */));
-  mojo::PendingRemote<blink::mojom::PointerLockContext> remote_context;
-  auto receiver_context = mojo::MakeSelfOwnedReceiver(
-      std::make_unique<PointerLockContextImpl>(),
-      remote_context.InitWithNewPipeAndPassReceiver());
-  dispatcher()->OnLockMouseACK(blink::mojom::PointerLockResult::kSuccess,
-                               std::move(remote_context));
-  EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
-
-  // Receive mouse event.
-  dispatcher()->WillHandleMouseEvent(blink::WebMouseEvent());
-
-  // Unlock.
-  receiver_context->Close();
-  dispatcher()->FlushContextPipeForTesting();
-  EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
-
-  // (Don't) receive mouse event.
-  dispatcher()->WillHandleMouseEvent(blink::WebMouseEvent());
-}
-
-// Test multiple targets
-TEST_F(MouseLockDispatcherTest, MultipleTargets) {
-  ::testing::InSequence expect_calls_in_sequence;
-  EXPECT_CALL(*target_, OnLockMouseACK(/*succeeded=*/true));
-  EXPECT_CALL(*target_, HandleMouseLockedInputEvent(_));
-  EXPECT_CALL(*alternate_target_, HandleMouseLockedInputEvent(_)).Times(0);
-  EXPECT_CALL(*target_, OnMouseLockLost()).Times(0);
-  EXPECT_CALL(*alternate_target_, OnMouseLockLost()).Times(0);
-  EXPECT_CALL(*target_, OnMouseLockLost());
-
-  // Lock request for target.
-  EXPECT_TRUE(dispatcher()->LockMouse(
-      target_, view()->GetMainRenderFrame()->GetWebFrame(), base::DoNothing(),
-      false /* unadjusted_movement */));
-
-  // Fail attempt to lock alternate.
-  EXPECT_FALSE(dispatcher()->IsMouseLockedTo(alternate_target_));
-  EXPECT_FALSE(dispatcher()->LockMouse(
-      alternate_target_, view()->GetMainRenderFrame()->GetWebFrame(),
-      base::DoNothing(), false /* unadjusted_movement */));
-
-  // Lock completion for target.
-
-  mojo::PendingRemote<blink::mojom::PointerLockContext> remote_context;
-  auto receiver_context = mojo::MakeSelfOwnedReceiver(
-      std::make_unique<PointerLockContextImpl>(),
-      remote_context.InitWithNewPipeAndPassReceiver());
-
-  dispatcher()->OnLockMouseACK(blink::mojom::PointerLockResult::kSuccess,
-                               std::move(remote_context));
-  EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
-
-  // Fail attempt to lock alternate.
-  EXPECT_FALSE(dispatcher()->IsMouseLockedTo(alternate_target_));
-  EXPECT_FALSE(dispatcher()->LockMouse(
-      alternate_target_, view()->GetMainRenderFrame()->GetWebFrame(),
-      base::DoNothing(), false /* unadjusted_movement */));
-
-  // Receive mouse event to only one target.
-  dispatcher()->WillHandleMouseEvent(blink::WebMouseEvent());
-
-  // Unlock alternate target has no effect.
-  dispatcher()->UnlockMouse(alternate_target_);
-  EXPECT_TRUE(dispatcher()->IsMouseLockedTo(target_));
-  EXPECT_FALSE(dispatcher()->IsMouseLockedTo(alternate_target_));
-
-  // Though the call to UnlockMouse should not unlock any target, we will
-  // cause an unlock by disconnecting the pipe (e.g. user escaped
-  // mouse lock) and verify the correct target is unlocked.
-  receiver_context->Close();
-  dispatcher()->FlushContextPipeForTesting();
-  EXPECT_FALSE(dispatcher()->IsMouseLockedTo(target_));
-}
-
-}  // namespace content
diff --git a/content/renderer/pepper/event_conversion.cc b/content/renderer/pepper/event_conversion.cc
index 8e794219..e2c2278 100644
--- a/content/renderer/pepper/event_conversion.cc
+++ b/content/renderer/pepper/event_conversion.cc
@@ -203,7 +203,6 @@
 }
 
 void AppendMouseEvent(const WebInputEvent& event,
-                      std::unique_ptr<gfx::PointF>* in_out_last_mouse_position,
                       std::vector<InputEventData>* result_events) {
   static_assert(static_cast<int>(WebMouseEvent::Button::kNoButton) ==
                     static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_NONE),
@@ -240,27 +239,8 @@
   result.mouse_position.y = mouse_event.PositionInWidget().y();
   result.mouse_click_count = mouse_event.click_count;
 
-  if (base::FeatureList::IsEnabled(features::kConsolidatedMovementXY)) {
-    if (mouse_event.GetType() == WebInputEvent::Type::kMouseMove &&
-        *in_out_last_mouse_position) {
-      result.mouse_movement.x = mouse_event.PositionInScreen().x() -
-                                (*in_out_last_mouse_position)->x();
-      result.mouse_movement.y = mouse_event.PositionInScreen().y() -
-                                (*in_out_last_mouse_position)->y();
-    }
-    *in_out_last_mouse_position =
-        std::make_unique<gfx::PointF>(mouse_event.PositionInScreen());
-
-    // Filter out event generated by recentering the cursor when mouse locked.
-    // See |RenderWidgetHostViewEventHandler::HandleMouseEventWhileLocked|.
-    if ((mouse_event.GetModifiers() &
-         WebInputEvent::Modifiers::kRelativeMotionEvent)) {
-      return;
-    }
-  } else {
-    result.mouse_movement.x = mouse_event.movement_x;
-    result.mouse_movement.y = mouse_event.movement_y;
-  }
+  result.mouse_movement.x = mouse_event.movement_x;
+  result.mouse_movement.y = mouse_event.movement_y;
 
   result_events->push_back(result);
 }
@@ -626,7 +606,6 @@
 
 void CreateInputEventData(
     const WebInputEvent& event,
-    std::unique_ptr<gfx::PointF>* in_out_last_mouse_position,
     std::vector<InputEventData>* result) {
   result->clear();
 
@@ -637,7 +616,7 @@
     case WebInputEvent::Type::kMouseEnter:
     case WebInputEvent::Type::kMouseLeave:
     case WebInputEvent::Type::kContextMenu:
-      AppendMouseEvent(event, in_out_last_mouse_position, result);
+      AppendMouseEvent(event, result);
       break;
     case WebInputEvent::Type::kMouseWheel:
       AppendMouseWheelEvent(event, result);
diff --git a/content/renderer/pepper/event_conversion.h b/content/renderer/pepper/event_conversion.h
index 1da850f..c33ec99 100644
--- a/content/renderer/pepper/event_conversion.h
+++ b/content/renderer/pepper/event_conversion.h
@@ -29,7 +29,6 @@
 // events will ge generated and the vector will be empty.
 CONTENT_EXPORT void CreateInputEventData(
     const blink::WebInputEvent& event,
-    std::unique_ptr<gfx::PointF>* last_mouse_position,
     std::vector<ppapi::InputEventData>* pp_events);
 
 // Creates a WebInputEvent from the given PP_InputEvent.  If it fails, returns
diff --git a/content/renderer/pepper/event_conversion_unittest.cc b/content/renderer/pepper/event_conversion_unittest.cc
index ec2a622..89ccfc28 100644
--- a/content/renderer/pepper/event_conversion_unittest.cc
+++ b/content/renderer/pepper/event_conversion_unittest.cc
@@ -47,7 +47,7 @@
   touch.PressPoint(1.f, 2.f);
 
   std::vector<ppapi::InputEventData> pp_events;
-  CreateInputEventData(touch, nullptr, &pp_events);
+  CreateInputEventData(touch, &pp_events);
   ASSERT_EQ(1U, pp_events.size());
 
   const ppapi::InputEventData& pp_event = pp_events[0];
@@ -75,7 +75,7 @@
   touch.MovePoint(1, 5.f, 6.f);
 
   std::vector<ppapi::InputEventData> pp_events;
-  CreateInputEventData(touch, nullptr, &pp_events);
+  CreateInputEventData(touch, &pp_events);
   ASSERT_EQ(1U, pp_events.size());
 
   const ppapi::InputEventData& pp_event = pp_events[0];
@@ -103,7 +103,7 @@
   touch.ReleasePoint(0);
 
   std::vector<ppapi::InputEventData> pp_events;
-  CreateInputEventData(touch, nullptr, &pp_events);
+  CreateInputEventData(touch, &pp_events);
   ASSERT_EQ(1U, pp_events.size());
 
   const ppapi::InputEventData& pp_event = pp_events[0];
@@ -132,7 +132,7 @@
   touch.CancelPoint(0);
 
   std::vector<ppapi::InputEventData> pp_events;
-  CreateInputEventData(touch, nullptr, &pp_events);
+  CreateInputEventData(touch, &pp_events);
   ASSERT_EQ(1U, pp_events.size());
 
   const ppapi::InputEventData& pp_event = pp_events[0];
@@ -152,13 +152,12 @@
 }
 
 TEST_F(EventConversionTest, MouseMove) {
-  std::unique_ptr<gfx::PointF> last_mouse_position;
   blink::WebMouseEvent mouse_event =
       blink::SyntheticWebMouseEventBuilder::Build(
           blink::WebInputEvent::Type::kMouseMove, 100, 200, 0);
 
   std::vector<ppapi::InputEventData> pp_events;
-  CreateInputEventData(mouse_event, &last_mouse_position, &pp_events);
+  CreateInputEventData(mouse_event, &pp_events);
   ASSERT_EQ(1U, pp_events.size());
   const ppapi::InputEventData& pp_event = pp_events[0];
   ASSERT_EQ(PP_INPUTEVENT_TYPE_MOUSEMOVE, pp_event.event_type);
@@ -166,14 +165,12 @@
   ASSERT_EQ(pp_event.mouse_position.y, mouse_event.PositionInWidget().y());
   ASSERT_EQ(pp_event.mouse_movement.x, 0);
   ASSERT_EQ(pp_event.mouse_movement.y, 0);
-  if (last_mouse_position) {
-    ASSERT_EQ(*last_mouse_position.get(),
-              gfx::PointF(mouse_event.PositionInScreen()));
-  }
 
   mouse_event = blink::SyntheticWebMouseEventBuilder::Build(
       blink::WebInputEvent::Type::kMouseMove, 123, 188, 0);
-  CreateInputEventData(mouse_event, &last_mouse_position, &pp_events);
+  mouse_event.movement_x = 23;
+  mouse_event.movement_y = -12;
+  CreateInputEventData(mouse_event, &pp_events);
   ASSERT_EQ(PP_INPUTEVENT_TYPE_MOUSEMOVE, pp_event.event_type);
   ASSERT_EQ(pp_event.mouse_position.x, mouse_event.PositionInWidget().x());
   ASSERT_EQ(pp_event.mouse_position.y, mouse_event.PositionInWidget().y());
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.cc b/content/renderer/pepper/pepper_plugin_instance_impl.cc
index 69257ed..7db06759 100644
--- a/content/renderer/pepper/pepper_plugin_instance_impl.cc
+++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc
@@ -344,26 +344,6 @@
   return false;
 }
 
-class PluginInstanceLockTarget : public MouseLockDispatcher::LockTarget {
- public:
-  explicit PluginInstanceLockTarget(PepperPluginInstanceImpl* plugin)
-      : plugin_(plugin) {}
-
-  void OnLockMouseACK(bool succeeded) override {
-    plugin_->OnLockMouseACK(succeeded);
-  }
-
-  void OnMouseLockLost() override { plugin_->OnMouseLockLost(); }
-
-  bool HandleMouseLockedInputEvent(const blink::WebMouseEvent& event) override {
-    plugin_->HandleMouseLockedInputEvent(event);
-    return true;
-  }
-
- private:
-  PepperPluginInstanceImpl* plugin_;
-};
-
 void PrintPDFOutput(PP_Resource print_output,
                     printing::MetafileSkia* metafile) {
 #if BUILDFLAG(ENABLE_PRINTING)
@@ -617,7 +597,6 @@
     browser_connection->DidDeleteInProcessInstance(pp_instance());
   }
 
-  UnSetAndDeleteLockTargetAdapter();
   module_->InstanceDeleted(this);
   // If we switched from the NaCl plugin module, notify it too.
   if (original_module_.get())
@@ -816,7 +795,6 @@
 
   if (render_frame_)
     render_frame_->PluginCrashed(module_->path(), module_->GetPeerProcessId());
-  UnSetAndDeleteLockTargetAdapter();
 }
 
 bool PepperPluginInstanceImpl::Initialize(
@@ -1138,10 +1116,9 @@
       std::unique_ptr<const WebInputEvent> event_in_dip(
           ui::ScaleWebInputEvent(event, viewport_to_dip_scale_));
       if (event_in_dip)
-        CreateInputEventData(*event_in_dip.get(), &last_mouse_position_,
-                             &events);
+        CreateInputEventData(*event_in_dip.get(), &events);
       else
-        CreateInputEventData(event, &last_mouse_position_, &events);
+        CreateInputEventData(event, &events);
 
       // Each input event may generate more than one PP_InputEvent.
       for (size_t i = 0; i < events.size(); i++) {
@@ -2692,7 +2669,7 @@
 }
 
 void PepperPluginInstanceImpl::UnlockMouse(PP_Instance instance) {
-  GetMouseLockDispatcher()->UnlockMouse(GetOrCreateLockTargetAdapter());
+  container_->UnlockMouse();
 }
 
 void PepperPluginInstanceImpl::SetTextInputType(PP_Instance instance,
@@ -3092,36 +3069,11 @@
 }
 
 bool PepperPluginInstanceImpl::IsMouseLocked() {
-  return GetMouseLockDispatcher()->IsMouseLockedTo(
-      GetOrCreateLockTargetAdapter());
+  return container_->IsMouseLocked();
 }
 
 bool PepperPluginInstanceImpl::LockMouse(bool request_unadjusted_movement) {
-  WebLocalFrame* requester_frame = container_->GetDocument().GetFrame();
-  return GetMouseLockDispatcher()->LockMouse(
-      GetOrCreateLockTargetAdapter(), requester_frame,
-      base::OnceCallback<void(blink::mojom::PointerLockResult)>(),
-      request_unadjusted_movement);
-}
-
-MouseLockDispatcher::LockTarget*
-PepperPluginInstanceImpl::GetOrCreateLockTargetAdapter() {
-  if (!lock_target_)
-    lock_target_ = std::make_unique<PluginInstanceLockTarget>(this);
-  return lock_target_.get();
-}
-
-MouseLockDispatcher* PepperPluginInstanceImpl::GetMouseLockDispatcher() {
-  if (render_frame_)
-    return render_frame_->GetLocalRootRenderWidget()->mouse_lock_dispatcher();
-  return nullptr;
-}
-
-void PepperPluginInstanceImpl::UnSetAndDeleteLockTargetAdapter() {
-  if (lock_target_) {
-    GetMouseLockDispatcher()->OnLockTargetDestroyed(lock_target_.get());
-    lock_target_.reset();
-  }
+  return container_->LockMouse(request_unadjusted_movement);
 }
 
 void PepperPluginInstanceImpl::DidDataFromWebURLResponse(
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.h b/content/renderer/pepper/pepper_plugin_instance_impl.h
index 5b059fe..f002dc1 100644
--- a/content/renderer/pepper/pepper_plugin_instance_impl.h
+++ b/content/renderer/pepper/pepper_plugin_instance_impl.h
@@ -33,7 +33,6 @@
 #include "content/public/renderer/plugin_instance_throttler.h"
 #include "content/public/renderer/render_frame.h"
 #include "content/public/renderer/render_frame_observer.h"
-#include "content/renderer/mouse_lock_dispatcher.h"
 #include "gin/handle.h"
 #include "ppapi/c/dev/pp_cursor_type_dev.h"
 #include "ppapi/c/dev/ppp_printing_dev.h"
@@ -607,9 +606,6 @@
 
   bool IsMouseLocked();
   bool LockMouse(bool request_unadjusted_movement);
-  MouseLockDispatcher* GetMouseLockDispatcher();
-  MouseLockDispatcher::LockTarget* GetOrCreateLockTargetAdapter();
-  void UnSetAndDeleteLockTargetAdapter();
 
   void DidDataFromWebURLResponse(const blink::WebURLResponse& response,
                                  int pending_host_id,
@@ -808,11 +804,6 @@
 
   scoped_refptr<ppapi::TrackedCallback> lock_mouse_callback_;
 
-  // Last mouse position from mouse event, used for calculating movements. Null
-  // means no mouse event received yet. This value is updated by
-  // |CreateInputEventData|.
-  std::unique_ptr<gfx::PointF> last_mouse_position_;
-
   // We store the arguments so we can re-send them if we are reset to talk to
   // NaCl via the IPC NaCl proxy.
   std::vector<std::string> argn_;
@@ -832,8 +823,6 @@
   // Isolate in which this Instance was created when interacting with v8.
   v8::Isolate* isolate_;
 
-  std::unique_ptr<MouseLockDispatcher::LockTarget> lock_target_;
-
   bool is_deleted_;
 
   // The text that is currently selected in the plugin.
diff --git a/content/renderer/pepper/pepper_webplugin_impl.cc b/content/renderer/pepper/pepper_webplugin_impl.cc
index 7da0d05..b9388e8a 100644
--- a/content/renderer/pepper/pepper_webplugin_impl.cc
+++ b/content/renderer/pepper/pepper_webplugin_impl.cc
@@ -491,4 +491,14 @@
   return false;
 }
 
+void PepperWebPluginImpl::DidLoseMouseLock() {
+  if (instance_)
+    instance_->OnMouseLockLost();
+}
+
+void PepperWebPluginImpl::DidReceiveMouseLockResult(bool success) {
+  if (instance_)
+    instance_->OnLockMouseACK(success);
+}
+
 }  // namespace content
diff --git a/content/renderer/pepper/pepper_webplugin_impl.h b/content/renderer/pepper/pepper_webplugin_impl.h
index 1e751f4..25590357 100644
--- a/content/renderer/pepper/pepper_webplugin_impl.h
+++ b/content/renderer/pepper/pepper_webplugin_impl.h
@@ -88,6 +88,8 @@
   bool CanRotateView() override;
   void RotateView(RotationType type) override;
   bool IsPlaceholder() override;
+  void DidLoseMouseLock() override;
+  void DidReceiveMouseLockResult(bool success) override;
 
  private:
   friend class base::DeleteHelper<PepperWebPluginImpl>;
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index d3679df..469883c 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -127,32 +127,6 @@
 RenderWidget::CreateRenderWidgetFunction g_create_render_widget_for_frame =
     nullptr;
 
-class WebWidgetLockTarget : public content::MouseLockDispatcher::LockTarget {
- public:
-  explicit WebWidgetLockTarget(RenderWidget* render_widget)
-      : render_widget_(render_widget) {}
-
-  void OnLockMouseACK(bool succeeded) override {
-    if (succeeded)
-      render_widget_->GetWebWidget()->DidAcquirePointerLock();
-    else
-      render_widget_->GetWebWidget()->DidNotAcquirePointerLock();
-  }
-
-  void OnMouseLockLost() override {
-    render_widget_->GetWebWidget()->DidLosePointerLock();
-  }
-
-  bool HandleMouseLockedInputEvent(const blink::WebMouseEvent& event) override {
-    // The WebWidget handles mouse lock in Blink's handleInputEvent().
-    return false;
-  }
-
- private:
-  // The RenderWidget owns this instance and is guaranteed to outlive it.
-  RenderWidget* render_widget_;
-};
-
 WebDragData DropMetaDataToWebDragData(
     const std::vector<DropData::Metadata>& drop_meta_data) {
   std::vector<WebDragData::Item> item_list;
@@ -294,10 +268,6 @@
 
   show_callback_ = std::move(show_callback);
 
-  webwidget_mouse_lock_target_ = std::make_unique<WebWidgetLockTarget>(this);
-  mouse_lock_dispatcher_ =
-      std::make_unique<RenderWidgetMouseLockDispatcher>(this);
-
   agent_scheduling_group_.AddRoute(routing_id_, this);
 
   webwidget_ = web_widget;
@@ -444,10 +414,6 @@
   GetWebWidget()->UpdateTextInputState();
 }
 
-bool RenderWidget::WillHandleMouseEvent(const blink::WebMouseEvent& event) {
-  return mouse_lock_dispatcher()->WillHandleMouseEvent(event);
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 // WebWidgetClient
 
@@ -661,33 +627,6 @@
   return viz::FrameSinkId(RenderThread::Get()->GetClientId(), routing_id());
 }
 
-bool RenderWidget::RequestPointerLock(
-    WebLocalFrame* requester_frame,
-    blink::WebWidgetClient::PointerLockCallback callback,
-    bool request_unadjusted_movement) {
-  return mouse_lock_dispatcher_->LockMouse(webwidget_mouse_lock_target_.get(),
-                                           requester_frame, std::move(callback),
-                                           request_unadjusted_movement);
-}
-
-bool RenderWidget::RequestPointerLockChange(
-    blink::WebLocalFrame* requester_frame,
-    blink::WebWidgetClient::PointerLockCallback callback,
-    bool request_unadjusted_movement) {
-  return mouse_lock_dispatcher_->ChangeMouseLock(
-      webwidget_mouse_lock_target_.get(), requester_frame, std::move(callback),
-      request_unadjusted_movement);
-}
-
-void RenderWidget::RequestPointerUnlock() {
-  mouse_lock_dispatcher_->UnlockMouse(webwidget_mouse_lock_target_.get());
-}
-
-bool RenderWidget::IsPointerLocked() {
-  return mouse_lock_dispatcher_->IsMouseLockedTo(
-      webwidget_mouse_lock_target_.get());
-}
-
 void RenderWidget::DidNavigate(ukm::SourceId source_id, const GURL& url) {
   // Update the URL and the document source id used to key UKM metrics in the
   // compositor. Note that the metrics for all frames are keyed to the main
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h
index 64be0d4e..03b3fb4 100644
--- a/content/renderer/render_widget.h
+++ b/content/renderer/render_widget.h
@@ -33,9 +33,7 @@
 #include "content/common/content_export.h"
 #include "content/common/renderer.mojom-forward.h"
 #include "content/public/common/drop_data.h"
-#include "content/renderer/mouse_lock_dispatcher.h"
 #include "content/renderer/render_widget_delegate.h"
-#include "content/renderer/render_widget_mouse_lock_dispatcher.h"
 #include "ipc/ipc_listener.h"
 #include "ipc/ipc_message.h"
 #include "ipc/ipc_sender.h"
@@ -63,8 +61,6 @@
 
 namespace blink {
 class WebFrameWidget;
-class WebLocalFrame;
-class WebMouseEvent;
 class WebPagePopup;
 }  // namespace blink
 
@@ -205,19 +201,9 @@
   void ClosePopupWidgetSoon() override;
   void Show(blink::WebNavigationPolicy) override;
   void SetWindowRect(const gfx::Rect&) override;
-  bool RequestPointerLock(blink::WebLocalFrame* requester_frame,
-                          blink::WebWidgetClient::PointerLockCallback callback,
-                          bool request_unadjusted_movement) override;
-  bool RequestPointerLockChange(
-      blink::WebLocalFrame* requester_frame,
-      blink::WebWidgetClient::PointerLockCallback callback,
-      bool request_unadjusted_movement) override;
-  void RequestPointerUnlock() override;
-  bool IsPointerLocked() override;
   viz::FrameSinkId GetFrameSinkId() override;
   void RecordTimeToFirstActivePaint(base::TimeDelta duration) override;
   void DidCommitCompositorFrame(base::TimeTicks commit_start_time) override;
-  bool WillHandleMouseEvent(const blink::WebMouseEvent& event) override;
   bool CanComposeInline() override;
   bool ShouldDispatchImeEventsToPepper() override;
   blink::WebTextInputType GetPepperTextInputType() override;
@@ -245,10 +231,6 @@
   // the new value will be sent to the browser process.
   void UpdateSelectionBounds();
 
-  MouseLockDispatcher* mouse_lock_dispatcher() const {
-    return mouse_lock_dispatcher_.get();
-  }
-
   void DidNavigate(ukm::SourceId source_id, const GURL& url);
 
   void SetActive(bool active);
@@ -373,12 +355,6 @@
   // The time spent in input handlers this frame. Used to throttle input acks.
   base::TimeDelta total_input_handling_time_this_frame_;
 
-  // Mouse Lock dispatcher attached to this view.
-  std::unique_ptr<RenderWidgetMouseLockDispatcher> mouse_lock_dispatcher_;
-
-  // Wraps the |webwidget_| as a MouseLockDispatcher::LockTarget interface.
-  std::unique_ptr<MouseLockDispatcher::LockTarget> webwidget_mouse_lock_target_;
-
   // Whether this widget is for a child local root frame. This excludes widgets
   // that are not for a frame (eg popups) and excludes the widget for the main
   // frame (which is attached to the RenderViewImpl).
diff --git a/content/renderer/render_widget_mouse_lock_dispatcher.cc b/content/renderer/render_widget_mouse_lock_dispatcher.cc
deleted file mode 100644
index 84ec17b..0000000
--- a/content/renderer/render_widget_mouse_lock_dispatcher.cc
+++ /dev/null
@@ -1,51 +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.
-
-#include "content/renderer/render_widget_mouse_lock_dispatcher.h"
-
-#include "content/renderer/render_view_impl.h"
-#include "third_party/blink/public/mojom/input/pointer_lock_context.mojom.h"
-#include "third_party/blink/public/web/web_frame.h"
-#include "third_party/blink/public/web/web_local_frame.h"
-#include "third_party/blink/public/web/web_view.h"
-#include "third_party/blink/public/web/web_widget.h"
-
-namespace content {
-
-RenderWidgetMouseLockDispatcher::RenderWidgetMouseLockDispatcher(
-    RenderWidget* render_widget)
-    : render_widget_(render_widget) {}
-
-RenderWidgetMouseLockDispatcher::~RenderWidgetMouseLockDispatcher() {}
-
-void RenderWidgetMouseLockDispatcher::SendLockMouseRequest(
-    blink::WebLocalFrame* requester_frame,
-    bool request_unadjusted_movement) {
-  bool has_transient_user_activation =
-      requester_frame ? requester_frame->HasTransientUserActivation() : false;
-  render_widget_->GetWebWidget()->RequestMouseLock(
-      has_transient_user_activation, request_unadjusted_movement,
-      base::BindOnce(&RenderWidgetMouseLockDispatcher::OnMouseLocked,
-                     weak_ptr_factory_.GetWeakPtr()));
-}
-
-void RenderWidgetMouseLockDispatcher::OnMouseLocked(
-    blink::mojom::PointerLockResult result,
-    blink::CrossVariantMojoRemote<blink::mojom::PointerLockContextInterfaceBase>
-        context) {
-  // Notify the base class.
-  MouseLockDispatcher::OnLockMouseACK(result, std::move(context));
-
-  // Mouse Lock removes the system cursor and provides all mouse motion as
-  // .movementX/Y values on events all sent to a fixed target. This requires
-  // content to specifically request the mode to be entered.
-  // Mouse Capture is implicitly given for the duration of a drag event, and
-  // sends all mouse events to the initial target of the drag.
-  // If Lock is entered it supersedes any in progress Capture.
-  if (result == blink::mojom::PointerLockResult::kSuccess &&
-      render_widget_->GetWebWidget())
-    render_widget_->GetWebWidget()->MouseCaptureLost();
-}
-
-}  // namespace content
diff --git a/content/renderer/render_widget_mouse_lock_dispatcher.h b/content/renderer/render_widget_mouse_lock_dispatcher.h
deleted file mode 100644
index dd50f10e..0000000
--- a/content/renderer/render_widget_mouse_lock_dispatcher.h
+++ /dev/null
@@ -1,47 +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.
-
-#ifndef CONTENT_RENDERER_RENDER_WIDGET_MOUSE_LOCK_DISPATCHER_H_
-#define CONTENT_RENDERER_RENDER_WIDGET_MOUSE_LOCK_DISPATCHER_H_
-
-#include "base/compiler_specific.h"
-#include "base/macros.h"
-#include "content/renderer/mouse_lock_dispatcher.h"
-
-namespace IPC {
-class Message;
-}
-
-namespace content {
-
-class RenderWidget;
-
-// RenderWidgetMouseLockDispatcher is owned by RenderWidget.
-class RenderWidgetMouseLockDispatcher : public MouseLockDispatcher {
- public:
-  explicit RenderWidgetMouseLockDispatcher(RenderWidget* render_widget);
-  ~RenderWidgetMouseLockDispatcher() override;
-
-  bool OnMessageReceived(const IPC::Message& message);
-
- private:
-  // MouseLockDispatcher implementation.
-  void SendLockMouseRequest(blink::WebLocalFrame* requester_frame,
-                            bool request_unadjusted_movement) override;
-
-  void OnMouseLocked(
-      blink::mojom::PointerLockResult result,
-      blink::CrossVariantMojoRemote<
-          blink::mojom::PointerLockContextInterfaceBase> context);
-
-  RenderWidget* render_widget_;
-
-  base::WeakPtrFactory<RenderWidgetMouseLockDispatcher> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(RenderWidgetMouseLockDispatcher);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_RENDERER_RENDER_WIDGET_MOUSE_LOCK_DISPATCHER_H_
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn
index 4e5161f..831caaf 100644
--- a/content/shell/BUILD.gn
+++ b/content/shell/BUILD.gn
@@ -408,6 +408,7 @@
     "$root_gen_dir/content/content_resources.pak",
     "$root_gen_dir/content/dev_ui_content_resources.pak",
     "$root_gen_dir/content/shell/shell_resources.pak",
+    "$root_gen_dir/content/test/web_ui_mojo_test_resources.pak",
     "$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak",
     "$root_gen_dir/net/net_resources.pak",
     "$root_gen_dir/third_party/blink/public/resources/blink_resources.pak",
@@ -428,6 +429,7 @@
     "//content/browser/resources/media:media_internals_resources",
     "//content/browser/tracing:resources",
     "//content/browser/webrtc/resources",
+    "//content/test:web_ui_mojo_test_resources",
     "//mojo/public/js:resources",
     "//net:net_resources",
     "//third_party/blink/public:devtools_inspector_resources",
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index c829929..84651b49 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -18,6 +18,9 @@
 import("//ppapi/buildflags/buildflags.gni")
 import("//testing/test.gni")
 import("//third_party/blink/public/public_features.gni")
+import("//third_party/closure_compiler/closure_args.gni")
+import("//third_party/closure_compiler/compile_js.gni")
+import("//tools/grit/grit_rule.gni")
 import("//tools/v8_context_snapshot/v8_context_snapshot.gni")
 import("//v8/gni/v8.gni")
 
@@ -778,7 +781,26 @@
 }
 
 mojom("web_ui_test_mojo_bindings") {
-  sources = [ "data/web_ui_test_mojo_bindings.mojom" ]
+  testonly = true
+  sources = [
+    "data/web_ui_test.test-mojom",
+    "data/web_ui_test_types.test-mojom",
+  ]
+  public_deps = [ "//url/mojom:url_mojom_gurl" ]
+  webui_module_path = "/content/test/data"
+}
+
+js_library("web_ui_mojo_test_js") {
+  sources = [ "data/web_ui_mojo_test.js" ]
+  deps = [ ":web_ui_test_mojo_bindings_webui_js" ]
+}
+
+# NOTE: Building this target serves as a compile test for type-checking of
+# WebUI JS that consumes generated Mojom JS bindings.
+js_type_check("web_ui_mojo_test_js_type_check") {
+  uses_js_modules = true
+  deps = [ ":web_ui_mojo_test_js" ]
+  closure_flags = mojom_js_args
 }
 
 mojom("mojo_web_test_bindings") {
@@ -1156,7 +1178,6 @@
     "../renderer/blink_platform_audio_hardware_browsertest.cc",
     "../renderer/gin_browsertest.cc",
     "../renderer/media/renderer_webmediaplayer_delegate_browsertest.cc",
-    "../renderer/mouse_lock_dispatcher_browsertest.cc",
     "../renderer/render_frame_impl_browsertest.cc",
     "../renderer/render_thread_impl_browsertest.cc",
     "../renderer/render_view_browsertest.cc",
@@ -1181,6 +1202,7 @@
   ]
 
   public_deps = [
+    ":web_ui_mojo_test_resources",
     "//content:content_resources",
     "//content:dev_ui_content_resources",
   ]
@@ -1190,6 +1212,7 @@
     ":content_test_mojo_bindings",
     ":test_interfaces",
     ":test_support",
+    ":web_ui_mojo_test_js_type_check",
     ":web_ui_test_mojo_bindings",
     "//base/test:test_support",
     "//build:chromecast_buildflags",
@@ -1305,7 +1328,6 @@
   data = []
 
   data_deps = [
-    ":web_ui_test_mojo_bindings_js_data_deps",
     "//content/shell:pak",
     "//testing/buildbot/filters:content_browsertests_filters",
     "//third_party/mesa_headers",
@@ -1621,6 +1643,22 @@
   }
 }
 
+grit("web_ui_mojo_test_resources") {
+  source = "web_ui_mojo_test_resources.grd"
+
+  outputs = [
+    "grit/web_ui_mojo_test_resources.h",
+    "grit/web_ui_mojo_test_resources_map.cc",
+    "grit/web_ui_mojo_test_resources_map.h",
+    "web_ui_mojo_test_resources.pak",
+  ]
+  grit_flags = [
+    "-E",
+    "root_gen_dir=" + rebase_path(root_gen_dir, root_build_dir),
+  ]
+  deps = [ ":web_ui_test_mojo_bindings_webui_js" ]
+}
+
 static_library("run_all_unittests") {
   testonly = true
   sources = [ "run_all_unittests.cc" ]
diff --git a/content/test/data/web_ui_mojo.html b/content/test/data/web_ui_mojo.html
deleted file mode 100644
index 1c7f02c..0000000
--- a/content/test/data/web_ui_mojo.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<html>
-<head>
-  <script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js"></script>
-  <script src="content/test/data/web_ui_test_mojo_bindings.mojom-lite.js"></script>
-  <script src="web_ui_mojo.js"></script>
-</head>
-<body>
-  x
-</body>
-</html>
diff --git a/content/test/data/web_ui_mojo.js b/content/test/data/web_ui_mojo.js
deleted file mode 100644
index fead22c9..0000000
--- a/content/test/data/web_ui_mojo.js
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-(async () => {
-  const browserTarget = content.mojom.BrowserTarget.getRemote();
-
-  await browserTarget.start();
-  browserTarget.stop();
-})();
diff --git a/content/test/data/web_ui_mojo_test.html b/content/test/data/web_ui_mojo_test.html
new file mode 100644
index 0000000..119c588
--- /dev/null
+++ b/content/test/data/web_ui_mojo_test.html
@@ -0,0 +1,8 @@
+<html>
+<head>
+  <script src="web_ui_mojo_test.js" type="module"></script>
+</head>
+<body>
+  x
+</body>
+</html>
diff --git a/content/test/data/web_ui_mojo_test.js b/content/test/data/web_ui_mojo_test.js
new file mode 100644
index 0000000..636dbb71
--- /dev/null
+++ b/content/test/data/web_ui_mojo_test.js
@@ -0,0 +1,46 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {WebUIMojoTestCache} from './content/test/data/web_ui_test.test-mojom-webui.js';
+
+/** @type {{send: function(*)}} */
+Window.prototype.domAutomationController;
+
+const TEST_DATA = [
+  { url: 'https://google.com/', contents: 'i am in fact feeling lucky' },
+  { url: 'https://youtube.com/', contents: 'probably cat videos?' },
+  { url: 'https://example.com/', contents: 'internets wow' },
+];
+
+async function doTest() {
+  const cache = WebUIMojoTestCache.getRemote();
+  for (const entry of TEST_DATA) {
+    cache.put({ url: entry.url }, entry.contents);
+  }
+
+  const {items} = await cache.getAll();
+  if (items.length != TEST_DATA.length) {
+    return false;
+  }
+
+  const entries = {};
+  for (const item of items) {
+    entries[item.url.url] = item.contents;
+  }
+
+  for (const entry of TEST_DATA) {
+    if (!(entry.url in entries)) {
+      return false;
+    }
+    if (entries[entry.url] != entry.contents) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+window.runTest = async function() {
+  window.domAutomationController.send(await doTest());
+}
diff --git a/content/test/data/web_ui_test.test-mojom b/content/test/data/web_ui_test.test-mojom
new file mode 100644
index 0000000..66520bf
--- /dev/null
+++ b/content/test/data/web_ui_test.test-mojom
@@ -0,0 +1,13 @@
+// Copyright 2020 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.
+
+module content.mojom;
+
+import "content/test/data/web_ui_test_types.test-mojom";
+import "url/mojom/url.mojom";
+
+interface WebUIMojoTestCache {
+  Put(url.mojom.Url url, string contents);
+  GetAll() => (array<CacheItem> items);
+};
diff --git a/content/test/data/web_ui_test_mojo_bindings.mojom b/content/test/data/web_ui_test_mojo_bindings.mojom
deleted file mode 100644
index c589382..0000000
--- a/content/test/data/web_ui_test_mojo_bindings.mojom
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-module content.mojom;
-
-interface BrowserTarget {
-  Start() => ();
-  Stop();
-};
diff --git a/content/test/data/web_ui_test_types.test-mojom b/content/test/data/web_ui_test_types.test-mojom
new file mode 100644
index 0000000..c4dfeb4
--- /dev/null
+++ b/content/test/data/web_ui_test_types.test-mojom
@@ -0,0 +1,16 @@
+// Copyright 2020 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.
+
+module content.mojom;
+
+import "url/mojom/url.mojom";
+
+// This struct is imported by web_ui_test.test-mojom and is used to provide
+// test coverage of non-shared WebUI mojom JS modules importing other
+// non-shared WebUI mojom JS modules.
+struct CacheItem {
+  url.mojom.Url url;
+  string contents;
+};
+
diff --git a/content/test/gpu/gpu_tests/gpu_helper.py b/content/test/gpu/gpu_tests/gpu_helper.py
index 086faa2b..16621aad 100644
--- a/content/test/gpu/gpu_tests/gpu_helper.py
+++ b/content/test/gpu/gpu_tests/gpu_helper.py
@@ -98,7 +98,7 @@
 
 
 def GetANGLERenderer(gpu_info):
-  retval = 'angle-no-backend'
+  retval = 'angle-disabled'
   if gpu_info and gpu_info.aux_attributes:
     gl_renderer = gpu_info.aux_attributes.get('gl_renderer')
     if gl_renderer and 'ANGLE' in gl_renderer:
@@ -139,17 +139,17 @@
 
 
 def GetSkiaRenderer(gpu_feature_status, extra_browser_args):
-  retval = 'no-skia-renderer'
+  retval = 'skia-renderer-disabled'
   skia_renderer_enabled = (
       gpu_feature_status
       and gpu_feature_status.get('skia_renderer') == 'enabled_on')
   if skia_renderer_enabled:
     if HasDawnSkiaRenderer(extra_browser_args):
-      retval = 'dawn-skia-renderer'
+      retval = 'skia-renderer-dawn'
     elif HasGlSkiaRenderer(extra_browser_args):
-      retval = 'gl-skia-renderer'
+      retval = 'skia-renderer-gl'
     elif HasVulkanSkiaRenderer(gpu_feature_status):
-      retval = 'vulkan-skia-renderer'
+      retval = 'skia-renderer-vulkan'
   return retval
 
 
diff --git a/content/test/gpu/gpu_tests/gpu_integration_test_unittest.py b/content/test/gpu/gpu_tests/gpu_integration_test_unittest.py
index 401b6cc..bb31d49 100644
--- a/content/test/gpu/gpu_tests/gpu_integration_test_unittest.py
+++ b/content/test/gpu/gpu_tests/gpu_integration_test_unittest.py
@@ -202,7 +202,7 @@
         _GetTagsToTest(browser),
         set([
             'win', 'win10', 'release', 'nvidia', 'nvidia-0x1cb3', 'angle-d3d9',
-            'no-passthrough', 'no-swiftshader-gl', 'no-skia-renderer'
+            'no-passthrough', 'no-swiftshader-gl', 'skia-renderer-disabled'
         ]))
 
   def testGenerateVendorTagUsingVendorString(self):
@@ -218,7 +218,7 @@
         set([
             'mac', 'mojave', 'release', 'imagination',
             'imagination-PowerVR-SGX-554', 'angle-opengles', 'passthrough',
-            'no-swiftshader-gl', 'no-skia-renderer'
+            'no-swiftshader-gl', 'skia-renderer-disabled'
         ]))
 
   def testGenerateVendorTagUsingDeviceString(self):
@@ -231,8 +231,8 @@
         _GetTagsToTest(browser),
         set([
             'mac', 'mojave', 'release', 'imagination',
-            'imagination-Triangle-Monster-3000', 'angle-no-backend',
-            'no-passthrough', 'no-swiftshader-gl', 'no-skia-renderer'
+            'imagination-Triangle-Monster-3000', 'angle-disabled',
+            'no-passthrough', 'no-swiftshader-gl', 'skia-renderer-disabled'
         ]))
 
   def testSimpleIntegrationTest(self):
diff --git a/content/test/gpu/gpu_tests/test_expectations/context_lost_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/context_lost_expectations.txt
index 005ec8d..fcfeaae 100644
--- a/content/test/gpu/gpu_tests/test_expectations/context_lost_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/context_lost_expectations.txt
@@ -30,17 +30,17 @@
 # Decoder
 # tags: [ passthrough no-passthrough ]
 # ANGLE Backend
-# tags: [ angle-no-backend
+# tags: [ angle-disabled
 #         angle-d3d9 angle-d3d11
 #         angle-metal
 #         angle-opengl angle-opengles
 #         angle-swiftshader
 #         angle-vulkan ]
 # Skia Renderer
-# tags: [ dawn-skia-renderer
-#         gl-skia-renderer
-#         no-skia-renderer
-#         vulkan-skia-renderer ]
+# tags: [ skia-renderer-dawn
+#         skia-renderer-disabled
+#         skia-renderer-gl
+#         skia-renderer-vulkan ]
 # SwiftShader
 # tags: [ swiftshader-gl no-swiftshader-gl ]
 # Driver
diff --git a/content/test/gpu/gpu_tests/test_expectations/depth_capture_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/depth_capture_expectations.txt
index 5e4fc6c..f4109b07 100644
--- a/content/test/gpu/gpu_tests/test_expectations/depth_capture_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/depth_capture_expectations.txt
@@ -30,17 +30,17 @@
 # Decoder
 # tags: [ passthrough no-passthrough ]
 # ANGLE Backend
-# tags: [ angle-no-backend
+# tags: [ angle-disabled
 #         angle-d3d9 angle-d3d11
 #         angle-metal
 #         angle-opengl angle-opengles
 #         angle-swiftshader
 #         angle-vulkan ]
 # Skia Renderer
-# tags: [ dawn-skia-renderer
-#         gl-skia-renderer
-#         no-skia-renderer
-#         vulkan-skia-renderer ]
+# tags: [ skia-renderer-dawn
+#         skia-renderer-disabled
+#         skia-renderer-gl
+#         skia-renderer-vulkan ]
 # SwiftShader
 # tags: [ swiftshader-gl no-swiftshader-gl ]
 # Driver
diff --git a/content/test/gpu/gpu_tests/test_expectations/gpu_process_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/gpu_process_expectations.txt
index fcd3cf9..04c7278f 100644
--- a/content/test/gpu/gpu_tests/test_expectations/gpu_process_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/gpu_process_expectations.txt
@@ -30,17 +30,17 @@
 # Decoder
 # tags: [ passthrough no-passthrough ]
 # ANGLE Backend
-# tags: [ angle-no-backend
+# tags: [ angle-disabled
 #         angle-d3d9 angle-d3d11
 #         angle-metal
 #         angle-opengl angle-opengles
 #         angle-swiftshader
 #         angle-vulkan ]
 # Skia Renderer
-# tags: [ dawn-skia-renderer
-#         gl-skia-renderer
-#         no-skia-renderer
-#         vulkan-skia-renderer ]
+# tags: [ skia-renderer-dawn
+#         skia-renderer-disabled
+#         skia-renderer-gl
+#         skia-renderer-vulkan ]
 # SwiftShader
 # tags: [ swiftshader-gl no-swiftshader-gl ]
 # Driver
diff --git a/content/test/gpu/gpu_tests/test_expectations/hardware_accelerated_feature_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/hardware_accelerated_feature_expectations.txt
index 8c5c75f..62e26ff 100644
--- a/content/test/gpu/gpu_tests/test_expectations/hardware_accelerated_feature_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/hardware_accelerated_feature_expectations.txt
@@ -30,17 +30,17 @@
 # Decoder
 # tags: [ passthrough no-passthrough ]
 # ANGLE Backend
-# tags: [ angle-no-backend
+# tags: [ angle-disabled
 #         angle-d3d9 angle-d3d11
 #         angle-metal
 #         angle-opengl angle-opengles
 #         angle-swiftshader
 #         angle-vulkan ]
 # Skia Renderer
-# tags: [ dawn-skia-renderer
-#         gl-skia-renderer
-#         no-skia-renderer
-#         vulkan-skia-renderer ]
+# tags: [ skia-renderer-dawn
+#         skia-renderer-disabled
+#         skia-renderer-gl
+#         skia-renderer-vulkan ]
 # SwiftShader
 # tags: [ swiftshader-gl no-swiftshader-gl ]
 # Driver
diff --git a/content/test/gpu/gpu_tests/test_expectations/info_collection_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/info_collection_expectations.txt
index 2e979b4d..000465c 100644
--- a/content/test/gpu/gpu_tests/test_expectations/info_collection_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/info_collection_expectations.txt
@@ -30,17 +30,17 @@
 # Decoder
 # tags: [ passthrough no-passthrough ]
 # ANGLE Backend
-# tags: [ angle-no-backend
+# tags: [ angle-disabled
 #         angle-d3d9 angle-d3d11
 #         angle-metal
 #         angle-opengl angle-opengles
 #         angle-swiftshader
 #         angle-vulkan ]
 # Skia Renderer
-# tags: [ dawn-skia-renderer
-#         gl-skia-renderer
-#         no-skia-renderer
-#         vulkan-skia-renderer ]
+# tags: [ skia-renderer-dawn
+#         skia-renderer-disabled
+#         skia-renderer-gl
+#         skia-renderer-vulkan ]
 # SwiftShader
 # tags: [ swiftshader-gl no-swiftshader-gl ]
 # Driver
diff --git a/content/test/gpu/gpu_tests/test_expectations/maps_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/maps_expectations.txt
index a6bffc8b..e3321bb 100644
--- a/content/test/gpu/gpu_tests/test_expectations/maps_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/maps_expectations.txt
@@ -30,17 +30,17 @@
 # Decoder
 # tags: [ passthrough no-passthrough ]
 # ANGLE Backend
-# tags: [ angle-no-backend
+# tags: [ angle-disabled
 #         angle-d3d9 angle-d3d11
 #         angle-metal
 #         angle-opengl angle-opengles
 #         angle-swiftshader
 #         angle-vulkan ]
 # Skia Renderer
-# tags: [ dawn-skia-renderer
-#         gl-skia-renderer
-#         no-skia-renderer
-#         vulkan-skia-renderer ]
+# tags: [ skia-renderer-dawn
+#         skia-renderer-disabled
+#         skia-renderer-gl
+#         skia-renderer-vulkan ]
 # SwiftShader
 # tags: [ swiftshader-gl no-swiftshader-gl ]
 # Driver
diff --git a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
index bdb5b52..7d856ec 100644
--- a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
@@ -30,17 +30,17 @@
 # Decoder
 # tags: [ passthrough no-passthrough ]
 # ANGLE Backend
-# tags: [ angle-no-backend
+# tags: [ angle-disabled
 #         angle-d3d9 angle-d3d11
 #         angle-metal
 #         angle-opengl angle-opengles
 #         angle-swiftshader
 #         angle-vulkan ]
 # Skia Renderer
-# tags: [ dawn-skia-renderer
-#         gl-skia-renderer
-#         no-skia-renderer
-#         vulkan-skia-renderer ]
+# tags: [ skia-renderer-dawn
+#         skia-renderer-disabled
+#         skia-renderer-gl
+#         skia-renderer-vulkan ]
 # SwiftShader
 # tags: [ swiftshader-gl no-swiftshader-gl ]
 # Driver
@@ -181,9 +181,9 @@
 crbug.com/744658 [ mac amd-0x6821 ] Pixel_CSS3DBlueBox_NoGpuProcess [ Failure ]
 
 # TODO(fserb): temporarily suppress this test.
-crbug.com/840394 [ linux no-skia-renderer ] Pixel_OffscreenCanvas2DResizeOnWorker [ RetryOnFailure ]
-crbug.com/840394 [ linux gl-skia-renderer ] Pixel_OffscreenCanvas2DResizeOnWorker [ RetryOnFailure ]
-crbug.com/840394 [ linux vulkan-skia-renderer ] Pixel_OffscreenCanvas2DResizeOnWorker [ RetryOnFailure ]
+crbug.com/840394 [ linux skia-renderer-disabled ] Pixel_OffscreenCanvas2DResizeOnWorker [ RetryOnFailure ]
+crbug.com/840394 [ linux skia-renderer-gl ] Pixel_OffscreenCanvas2DResizeOnWorker [ RetryOnFailure ]
+crbug.com/840394 [ linux skia-renderer-vulkan ] Pixel_OffscreenCanvas2DResizeOnWorker [ RetryOnFailure ]
 crbug.com/840394 [ mac ] Pixel_OffscreenCanvas2DResizeOnWorker [ RetryOnFailure ]
 
 # TODO(kbr): temporary suppression for new test.
@@ -249,32 +249,32 @@
 crbug.com/974380 [ mac ] Pixel_OffscreenCanvasUnaccelerated2DGPUCompositingWorker [ Skip ]
 
 # Skia Renderer, producing incorrect color in one quadrant
-crbug.com/1008450 [ android vulkan-skia-renderer ] Pixel_Video_BackdropFilter [ Skip ]
-crbug.com/1008450 [ android gl-skia-renderer ] Pixel_Video_MP4_Rounded_Corner [ Skip ]
-crbug.com/1008450 [ android vulkan-skia-renderer ] Pixel_Video_MP4_Rounded_Corner [ Skip ]
+crbug.com/1008450 [ android skia-renderer-vulkan ] Pixel_Video_BackdropFilter [ Skip ]
+crbug.com/1008450 [ android skia-renderer-gl ] Pixel_Video_MP4_Rounded_Corner [ Skip ]
+crbug.com/1008450 [ android skia-renderer-vulkan ] Pixel_Video_MP4_Rounded_Corner [ Skip ]
 
 # Produces blank images on Intel HD 630 w/ Mesa 19.0.2
-crbug.com/976861 [ linux intel-0x5912 no-skia-renderer ] Pixel_OffscreenCanvasTransferToImageBitmap [ Skip ]
-crbug.com/976861 [ linux intel-0x5912 gl-skia-renderer ] Pixel_OffscreenCanvasTransferToImageBitmap [ Skip ]
-crbug.com/976861 [ linux intel-0x5912 vulkan-skia-renderer ] Pixel_OffscreenCanvasTransferToImageBitmap [ Skip ]
+crbug.com/976861 [ linux intel-0x5912 skia-renderer-disabled ] Pixel_OffscreenCanvasTransferToImageBitmap [ Skip ]
+crbug.com/976861 [ linux intel-0x5912 skia-renderer-gl ] Pixel_OffscreenCanvasTransferToImageBitmap [ Skip ]
+crbug.com/976861 [ linux intel-0x5912 skia-renderer-vulkan ] Pixel_OffscreenCanvasTransferToImageBitmap [ Skip ]
 
 # Producing incorrect image on Win10 Intel HD 630 and UHD 630 w/ 26.20.100.6912
 # or later drivers.
-crbug.com/997313 [ win intel-0x5912 no-skia-renderer ] Pixel_WebGL_PremultipliedAlpha_False [ Failure ]
-crbug.com/997313 [ win intel-0x5912 gl-skia-renderer ] Pixel_WebGL_PremultipliedAlpha_False [ Failure ]
-crbug.com/997313 [ win intel-0x5912 vulkan-skia-renderer ] Pixel_WebGL_PremultipliedAlpha_False [ Failure ]
-crbug.com/997313 [ win intel-0x3e92 no-skia-renderer ] Pixel_WebGL_PremultipliedAlpha_False [ Failure ]
-crbug.com/997313 [ win intel-0x3e92 gl-skia-renderer ] Pixel_WebGL_PremultipliedAlpha_False [ Failure ]
-crbug.com/997313 [ win intel-0x3e92 vulkan-skia-renderer ] Pixel_WebGL_PremultipliedAlpha_False [ Failure ]
+crbug.com/997313 [ win intel-0x5912 skia-renderer-disabled ] Pixel_WebGL_PremultipliedAlpha_False [ Failure ]
+crbug.com/997313 [ win intel-0x5912 skia-renderer-gl ] Pixel_WebGL_PremultipliedAlpha_False [ Failure ]
+crbug.com/997313 [ win intel-0x5912 skia-renderer-vulkan ] Pixel_WebGL_PremultipliedAlpha_False [ Failure ]
+crbug.com/997313 [ win intel-0x3e92 skia-renderer-disabled ] Pixel_WebGL_PremultipliedAlpha_False [ Failure ]
+crbug.com/997313 [ win intel-0x3e92 skia-renderer-gl ] Pixel_WebGL_PremultipliedAlpha_False [ Failure ]
+crbug.com/997313 [ win intel-0x3e92 skia-renderer-vulkan ] Pixel_WebGL_PremultipliedAlpha_False [ Failure ]
 
 # Flakes on Nexus 9 or NVIDIA Shield TV
-crbug.com/1019462 [ android nvidia no-skia-renderer ] Pixel_Video_MP4_FourColors_Aspect_4x3 [ RetryOnFailure ]
-crbug.com/1019462 [ android nvidia no-skia-renderer ] Pixel_Video_MP4_FourColors_Rot_180 [ RetryOnFailure ]
-crbug.com/1019462 [ android nvidia no-skia-renderer ] Pixel_Video_MP4_FourColors_Rot_270 [ RetryOnFailure ]
-crbug.com/1019462 [ android nvidia no-skia-renderer ] Pixel_Video_MP4_FourColors_Rot_90 [ RetryOnFailure ]
-crbug.com/1019462 [ android nvidia no-skia-renderer ] Pixel_Video_MP4_Rounded_Corner [ RetryOnFailure ]
-crbug.com/1019462 [ android nvidia no-skia-renderer ] Pixel_Video_Context_Loss_VP9 [ RetryOnFailure ]
-crbug.com/1019462 [ android nvidia no-skia-renderer ] Pixel_WebGL2_BlitFramebuffer_Result_Displayed [ RetryOnFailure ]
+crbug.com/1019462 [ android nvidia skia-renderer-disabled ] Pixel_Video_MP4_FourColors_Aspect_4x3 [ RetryOnFailure ]
+crbug.com/1019462 [ android nvidia skia-renderer-disabled ] Pixel_Video_MP4_FourColors_Rot_180 [ RetryOnFailure ]
+crbug.com/1019462 [ android nvidia skia-renderer-disabled ] Pixel_Video_MP4_FourColors_Rot_270 [ RetryOnFailure ]
+crbug.com/1019462 [ android nvidia skia-renderer-disabled ] Pixel_Video_MP4_FourColors_Rot_90 [ RetryOnFailure ]
+crbug.com/1019462 [ android nvidia skia-renderer-disabled ] Pixel_Video_MP4_Rounded_Corner [ RetryOnFailure ]
+crbug.com/1019462 [ android nvidia skia-renderer-disabled ] Pixel_Video_Context_Loss_VP9 [ RetryOnFailure ]
+crbug.com/1019462 [ android nvidia skia-renderer-disabled ] Pixel_WebGL2_BlitFramebuffer_Result_Displayed [ RetryOnFailure ]
 
 # Skip dual gpu switching tests on Mac Nvidia because this
 # configuration has been forced to use only the low-power GPU due to
@@ -292,9 +292,9 @@
 crbug.com/1069339 [ mac intel-0xd26 ] Pixel_OffscreenCanvasIBRCWebGLHighPerfWorker [ RetryOnFailure ]
 
 # VP9 appears to not recover correctly after GPU process crashes on Windows.
-crbug.com/1033982 [ win nvidia no-skia-renderer ] Pixel_Video_Context_Loss_VP9 [ RetryOnFailure ]
-crbug.com/1033982 [ win nvidia gl-skia-renderer ] Pixel_Video_Context_Loss_VP9 [ RetryOnFailure ]
-crbug.com/1033982 [ win nvidia vulkan-skia-renderer ] Pixel_Video_Context_Loss_VP9 [ RetryOnFailure ]
+crbug.com/1033982 [ win nvidia skia-renderer-disabled ] Pixel_Video_Context_Loss_VP9 [ RetryOnFailure ]
+crbug.com/1033982 [ win nvidia skia-renderer-gl ] Pixel_Video_Context_Loss_VP9 [ RetryOnFailure ]
+crbug.com/1033982 [ win nvidia skia-renderer-vulkan ] Pixel_Video_Context_Loss_VP9 [ RetryOnFailure ]
 
 # HDR rendering with PQ color space appears to be broken on Windows RS2.
 # TODO(sunnyps): Revert this temporary suppression after ensuring pixel tests
@@ -303,112 +303,112 @@
 
 # SkiaRenderer Dawn doesn't support accelerated canvas, webgl, video, or
 # direct composition.
-crbug.com/1021566 [ linux dawn-skia-renderer ] Pixel_Canvas2DTabSwitch [ Skip ]
-crbug.com/1021566 [ linux dawn-skia-renderer ] Pixel_CanvasLowLatency2D [ Skip ]
-crbug.com/1021566 [ linux dawn-skia-renderer ] Pixel_CanvasLowLatency2DDrawImage [ Skip ]
-crbug.com/1021566 [ linux dawn-skia-renderer ] Pixel_CanvasLowLatency2DImageData [ Skip ]
-crbug.com/1021566 [ linux dawn-skia-renderer ] Pixel_CanvasLowLatencyWebGL [ Skip ]
-crbug.com/1021566 [ linux dawn-skia-renderer ] Pixel_CanvasLowLatencyWebGLAlphaFalse [ Skip ]
-crbug.com/1021566 [ linux dawn-skia-renderer ] Pixel_CanvasLowLatencyWebGLDrawImage [ Skip ]
-crbug.com/1021566 [ linux dawn-skia-renderer ] Pixel_CanvasLowLatencyWebGLRoundedCorners [ Skip ]
-crbug.com/1021566 [ linux dawn-skia-renderer ] Pixel_CanvasLowLatencyWebGLOccluded [ Skip ]
-crbug.com/1021566 [ linux dawn-skia-renderer ] Pixel_OffscreenCanvas2DResizeOnWorker [ Skip ]
-crbug.com/1021566 [ linux dawn-skia-renderer ] Pixel_OffscreenCanvasTransferBeforeStyleResize [ Skip ]
-crbug.com/1021566 [ linux dawn-skia-renderer ] Pixel_OffscreenCanvasWebGLPaintAfterResize [ Skip ]
-crbug.com/1021566 [ linux dawn-skia-renderer ] Pixel_ScissorTestWithPreserveDrawingBuffer [ Skip ]
-crbug.com/1021566 [ linux dawn-skia-renderer ] Pixel_Video_BackdropFilter [ Skip ]
-crbug.com/1021566 [ linux dawn-skia-renderer ] Pixel_Video_Context_Loss_MP4 [ Skip ]
-crbug.com/1021566 [ linux dawn-skia-renderer ] Pixel_Video_Context_Loss_VP9 [ Skip ]
-crbug.com/1021566 [ linux dawn-skia-renderer ] Pixel_Video_Media_Stream_Incompatible_Stride [ Skip ]
-crbug.com/1021566 [ linux dawn-skia-renderer ] Pixel_Video_MP4_Rounded_Corner [ Skip ]
-crbug.com/1021566 [ linux dawn-skia-renderer ] Pixel_WebGL2_BlitFramebuffer_Result_Displayed [ Skip ]
-crbug.com/1021566 [ linux dawn-skia-renderer ] Pixel_WebGL2_ClearBufferfv_Result_Displayed [ Skip ]
-crbug.com/1021566 [ linux dawn-skia-renderer ] Pixel_WebGLCopyImage [ Skip ]
-crbug.com/1021566 [ linux dawn-skia-renderer ] Pixel_WebGLReadPixelsTabSwitch [ Skip ]
-crbug.com/1021566 [ linux dawn-skia-renderer ] Pixel_WebGL_PremultipliedAlpha_False [ Skip ]
-crbug.com/1021566 [ linux dawn-skia-renderer ] Pixel_WebGLTransparentGreenTriangle_NoAlpha_ImplicitClear [ Skip ]
-crbug.com/1021566 [ win dawn-skia-renderer ] Pixel_Canvas2DTabSwitch [ Skip ]
-crbug.com/1021566 [ win dawn-skia-renderer ] Pixel_CanvasLowLatency2D [ Skip ]
-crbug.com/1021566 [ win dawn-skia-renderer ] Pixel_CanvasLowLatency2DDrawImage [ Skip ]
-crbug.com/1021566 [ win dawn-skia-renderer ] Pixel_CanvasLowLatency2DImageData [ Skip ]
-crbug.com/1021566 [ win dawn-skia-renderer ] Pixel_CanvasLowLatencyWebGL [ Skip ]
-crbug.com/1021566 [ win dawn-skia-renderer ] Pixel_CanvasLowLatencyWebGLAlphaFalse [ Skip ]
-crbug.com/1021566 [ win dawn-skia-renderer ] Pixel_CanvasLowLatencyWebGLDrawImage [ Skip ]
-crbug.com/1021566 [ win dawn-skia-renderer ] Pixel_CanvasLowLatencyWebGLRoundedCorners [ Skip ]
-crbug.com/1021566 [ win dawn-skia-renderer ] Pixel_CanvasLowLatencyWebGLOccluded [ Skip ]
-crbug.com/1021566 [ win dawn-skia-renderer ] Pixel_OffscreenCanvas2DResizeOnWorker [ Skip ]
-crbug.com/1021566 [ win dawn-skia-renderer ] Pixel_OffscreenCanvasTransferBeforeStyleResize [ Skip ]
-crbug.com/1021566 [ win dawn-skia-renderer ] Pixel_OffscreenCanvasWebGLPaintAfterResize [ Skip ]
-crbug.com/1021566 [ win dawn-skia-renderer ] Pixel_ScissorTestWithPreserveDrawingBuffer [ Skip ]
-crbug.com/1021566 [ win dawn-skia-renderer ] Pixel_Video_BackdropFilter [ Skip ]
-crbug.com/1021566 [ win dawn-skia-renderer ] Pixel_Video_Context_Loss_MP4 [ Skip ]
-crbug.com/1021566 [ win dawn-skia-renderer ] Pixel_Video_Context_Loss_VP9 [ Skip ]
-crbug.com/1021566 [ win dawn-skia-renderer ] Pixel_Video_Media_Stream_Incompatible_Stride [ Skip ]
-crbug.com/1021566 [ win dawn-skia-renderer ] Pixel_Video_MP4_DXVA [ Skip ]
-crbug.com/1021566 [ win dawn-skia-renderer ] Pixel_Video_MP4_Rounded_Corner [ Skip ]
-crbug.com/1021566 [ win dawn-skia-renderer ] Pixel_Video_VP9_DXVA [ Skip ]
-crbug.com/1021566 [ win dawn-skia-renderer ] Pixel_WebGL2_BlitFramebuffer_Result_Displayed [ Skip ]
-crbug.com/1021566 [ win dawn-skia-renderer ] Pixel_WebGL2_ClearBufferfv_Result_Displayed [ Skip ]
-crbug.com/1021566 [ win dawn-skia-renderer ] Pixel_WebGLCopyImage [ Skip ]
-crbug.com/1021566 [ win dawn-skia-renderer ] Pixel_WebGLReadPixelsTabSwitch [ Skip ]
-crbug.com/1021566 [ win dawn-skia-renderer ] Pixel_WebGL_PremultipliedAlpha_False [ Skip ]
-crbug.com/1021566 [ win dawn-skia-renderer ] Pixel_WebGLTransparentGreenTriangle_NoAlpha_ImplicitClear [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_2DCanvasWebGL [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_Canvas2DRedBox [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_Canvas2DRedBoxScrgbLinear [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_Canvas2DUntagged [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_DirectComposition_Underlay [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_DirectComposition_Underlay_DXVA [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_DirectComposition_Underlay_Fullsize [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_DirectComposition_Video_BackdropFilter [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_DirectComposition_Video_Disable_Overlays [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_DirectComposition_Video_MP4 [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_DirectComposition_Video_MP4_DXVA [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_DirectComposition_Video_MP4_FourColors_Aspect_4x3 [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_DirectComposition_Video_MP4_FourColors_Rot_180 [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_DirectComposition_Video_MP4_FourColors_Rot_270 [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_DirectComposition_Video_MP4_FourColors_Rot_90 [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_DirectComposition_Video_MP4_Fullsize [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_DirectComposition_Video_MP4_Rounded_Corner [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_DirectComposition_Video_MP4_NV12 [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_DirectComposition_Video_MP4_YUY2 [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_DirectComposition_Video_MP4_BGRA [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_DirectComposition_Video_MP4_VP_SCALING [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_DirectComposition_Video_VP9 [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_DirectComposition_Video_VP9_DXVA [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_DirectComposition_Video_VP9_Fullsize [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_DirectComposition_Video_VP9_I420A [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_DirectComposition_Video_VP9_NV12 [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_DirectComposition_Video_VP9_YUY2 [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_DirectComposition_Video_VP9_BGRA [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_DirectComposition_Video_VP9_VP_SCALING [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_OffscreenCanvasAccelerated2D [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_OffscreenCanvasAccelerated2DWorker [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_OffscreenCanvasIBRCWebGLMain [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_OffscreenCanvasIBRCWebGLWorker [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_OffscreenCanvasTransferAfterStyleResize [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_OffscreenCanvasTransferToImageBitmap [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_OffscreenCanvasTransferToImageBitmapWorker [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_OffscreenCanvasWebGLDefault [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_OffscreenCanvasWebGLDefaultWorker [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_OffscreenCanvasWebglResizeOnWorker [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_RepeatedWebGLTo2D [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_Video_MP4 [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_Video_MP4_FourColors_Aspect_4x3 [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_Video_MP4_FourColors_Rot_180 [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_Video_MP4_FourColors_Rot_270 [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_Video_MP4_FourColors_Rot_90 [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_Video_VP9 [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_WebGLGreenTriangle_AA_Alpha [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_WebGLGreenTriangle_AA_NoAlpha [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_WebGLGreenTriangle_NoAA_Alpha [ Skip ]
-crbug.com/1021566 [ dawn-skia-renderer ] Pixel_WebGLGreenTriangle_NoAA_NoAlpha [ Skip ]
+crbug.com/1021566 [ linux skia-renderer-dawn ] Pixel_Canvas2DTabSwitch [ Skip ]
+crbug.com/1021566 [ linux skia-renderer-dawn ] Pixel_CanvasLowLatency2D [ Skip ]
+crbug.com/1021566 [ linux skia-renderer-dawn ] Pixel_CanvasLowLatency2DDrawImage [ Skip ]
+crbug.com/1021566 [ linux skia-renderer-dawn ] Pixel_CanvasLowLatency2DImageData [ Skip ]
+crbug.com/1021566 [ linux skia-renderer-dawn ] Pixel_CanvasLowLatencyWebGL [ Skip ]
+crbug.com/1021566 [ linux skia-renderer-dawn ] Pixel_CanvasLowLatencyWebGLAlphaFalse [ Skip ]
+crbug.com/1021566 [ linux skia-renderer-dawn ] Pixel_CanvasLowLatencyWebGLDrawImage [ Skip ]
+crbug.com/1021566 [ linux skia-renderer-dawn ] Pixel_CanvasLowLatencyWebGLRoundedCorners [ Skip ]
+crbug.com/1021566 [ linux skia-renderer-dawn ] Pixel_CanvasLowLatencyWebGLOccluded [ Skip ]
+crbug.com/1021566 [ linux skia-renderer-dawn ] Pixel_OffscreenCanvas2DResizeOnWorker [ Skip ]
+crbug.com/1021566 [ linux skia-renderer-dawn ] Pixel_OffscreenCanvasTransferBeforeStyleResize [ Skip ]
+crbug.com/1021566 [ linux skia-renderer-dawn ] Pixel_OffscreenCanvasWebGLPaintAfterResize [ Skip ]
+crbug.com/1021566 [ linux skia-renderer-dawn ] Pixel_ScissorTestWithPreserveDrawingBuffer [ Skip ]
+crbug.com/1021566 [ linux skia-renderer-dawn ] Pixel_Video_BackdropFilter [ Skip ]
+crbug.com/1021566 [ linux skia-renderer-dawn ] Pixel_Video_Context_Loss_MP4 [ Skip ]
+crbug.com/1021566 [ linux skia-renderer-dawn ] Pixel_Video_Context_Loss_VP9 [ Skip ]
+crbug.com/1021566 [ linux skia-renderer-dawn ] Pixel_Video_Media_Stream_Incompatible_Stride [ Skip ]
+crbug.com/1021566 [ linux skia-renderer-dawn ] Pixel_Video_MP4_Rounded_Corner [ Skip ]
+crbug.com/1021566 [ linux skia-renderer-dawn ] Pixel_WebGL2_BlitFramebuffer_Result_Displayed [ Skip ]
+crbug.com/1021566 [ linux skia-renderer-dawn ] Pixel_WebGL2_ClearBufferfv_Result_Displayed [ Skip ]
+crbug.com/1021566 [ linux skia-renderer-dawn ] Pixel_WebGLCopyImage [ Skip ]
+crbug.com/1021566 [ linux skia-renderer-dawn ] Pixel_WebGLReadPixelsTabSwitch [ Skip ]
+crbug.com/1021566 [ linux skia-renderer-dawn ] Pixel_WebGL_PremultipliedAlpha_False [ Skip ]
+crbug.com/1021566 [ linux skia-renderer-dawn ] Pixel_WebGLTransparentGreenTriangle_NoAlpha_ImplicitClear [ Skip ]
+crbug.com/1021566 [ win skia-renderer-dawn ] Pixel_Canvas2DTabSwitch [ Skip ]
+crbug.com/1021566 [ win skia-renderer-dawn ] Pixel_CanvasLowLatency2D [ Skip ]
+crbug.com/1021566 [ win skia-renderer-dawn ] Pixel_CanvasLowLatency2DDrawImage [ Skip ]
+crbug.com/1021566 [ win skia-renderer-dawn ] Pixel_CanvasLowLatency2DImageData [ Skip ]
+crbug.com/1021566 [ win skia-renderer-dawn ] Pixel_CanvasLowLatencyWebGL [ Skip ]
+crbug.com/1021566 [ win skia-renderer-dawn ] Pixel_CanvasLowLatencyWebGLAlphaFalse [ Skip ]
+crbug.com/1021566 [ win skia-renderer-dawn ] Pixel_CanvasLowLatencyWebGLDrawImage [ Skip ]
+crbug.com/1021566 [ win skia-renderer-dawn ] Pixel_CanvasLowLatencyWebGLRoundedCorners [ Skip ]
+crbug.com/1021566 [ win skia-renderer-dawn ] Pixel_CanvasLowLatencyWebGLOccluded [ Skip ]
+crbug.com/1021566 [ win skia-renderer-dawn ] Pixel_OffscreenCanvas2DResizeOnWorker [ Skip ]
+crbug.com/1021566 [ win skia-renderer-dawn ] Pixel_OffscreenCanvasTransferBeforeStyleResize [ Skip ]
+crbug.com/1021566 [ win skia-renderer-dawn ] Pixel_OffscreenCanvasWebGLPaintAfterResize [ Skip ]
+crbug.com/1021566 [ win skia-renderer-dawn ] Pixel_ScissorTestWithPreserveDrawingBuffer [ Skip ]
+crbug.com/1021566 [ win skia-renderer-dawn ] Pixel_Video_BackdropFilter [ Skip ]
+crbug.com/1021566 [ win skia-renderer-dawn ] Pixel_Video_Context_Loss_MP4 [ Skip ]
+crbug.com/1021566 [ win skia-renderer-dawn ] Pixel_Video_Context_Loss_VP9 [ Skip ]
+crbug.com/1021566 [ win skia-renderer-dawn ] Pixel_Video_Media_Stream_Incompatible_Stride [ Skip ]
+crbug.com/1021566 [ win skia-renderer-dawn ] Pixel_Video_MP4_DXVA [ Skip ]
+crbug.com/1021566 [ win skia-renderer-dawn ] Pixel_Video_MP4_Rounded_Corner [ Skip ]
+crbug.com/1021566 [ win skia-renderer-dawn ] Pixel_Video_VP9_DXVA [ Skip ]
+crbug.com/1021566 [ win skia-renderer-dawn ] Pixel_WebGL2_BlitFramebuffer_Result_Displayed [ Skip ]
+crbug.com/1021566 [ win skia-renderer-dawn ] Pixel_WebGL2_ClearBufferfv_Result_Displayed [ Skip ]
+crbug.com/1021566 [ win skia-renderer-dawn ] Pixel_WebGLCopyImage [ Skip ]
+crbug.com/1021566 [ win skia-renderer-dawn ] Pixel_WebGLReadPixelsTabSwitch [ Skip ]
+crbug.com/1021566 [ win skia-renderer-dawn ] Pixel_WebGL_PremultipliedAlpha_False [ Skip ]
+crbug.com/1021566 [ win skia-renderer-dawn ] Pixel_WebGLTransparentGreenTriangle_NoAlpha_ImplicitClear [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_2DCanvasWebGL [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_Canvas2DRedBox [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_Canvas2DRedBoxScrgbLinear [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_Canvas2DUntagged [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_DirectComposition_Underlay [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_DirectComposition_Underlay_DXVA [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_DirectComposition_Underlay_Fullsize [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_DirectComposition_Video_BackdropFilter [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_DirectComposition_Video_Disable_Overlays [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_DirectComposition_Video_MP4 [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_DirectComposition_Video_MP4_DXVA [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_DirectComposition_Video_MP4_FourColors_Aspect_4x3 [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_DirectComposition_Video_MP4_FourColors_Rot_180 [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_DirectComposition_Video_MP4_FourColors_Rot_270 [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_DirectComposition_Video_MP4_FourColors_Rot_90 [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_DirectComposition_Video_MP4_Fullsize [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_DirectComposition_Video_MP4_Rounded_Corner [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_DirectComposition_Video_MP4_NV12 [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_DirectComposition_Video_MP4_YUY2 [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_DirectComposition_Video_MP4_BGRA [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_DirectComposition_Video_MP4_VP_SCALING [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_DirectComposition_Video_VP9 [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_DirectComposition_Video_VP9_DXVA [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_DirectComposition_Video_VP9_Fullsize [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_DirectComposition_Video_VP9_I420A [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_DirectComposition_Video_VP9_NV12 [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_DirectComposition_Video_VP9_YUY2 [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_DirectComposition_Video_VP9_BGRA [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_DirectComposition_Video_VP9_VP_SCALING [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_OffscreenCanvasAccelerated2D [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_OffscreenCanvasAccelerated2DWorker [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_OffscreenCanvasIBRCWebGLMain [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_OffscreenCanvasIBRCWebGLWorker [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_OffscreenCanvasTransferAfterStyleResize [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_OffscreenCanvasTransferToImageBitmap [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_OffscreenCanvasTransferToImageBitmapWorker [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_OffscreenCanvasWebGLDefault [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_OffscreenCanvasWebGLDefaultWorker [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_OffscreenCanvasWebglResizeOnWorker [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_RepeatedWebGLTo2D [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_Video_MP4 [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_Video_MP4_FourColors_Aspect_4x3 [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_Video_MP4_FourColors_Rot_180 [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_Video_MP4_FourColors_Rot_270 [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_Video_MP4_FourColors_Rot_90 [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_Video_VP9 [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_WebGLGreenTriangle_AA_Alpha [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_WebGLGreenTriangle_AA_NoAlpha [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_WebGLGreenTriangle_NoAA_Alpha [ Skip ]
+crbug.com/1021566 [ skia-renderer-dawn ] Pixel_WebGLGreenTriangle_NoAA_NoAlpha [ Skip ]
 
 # DirectComposition tests are not expected to work properly on Windows 7.
 crbug.com/1086758 [ win7 ] Pixel_DirectComposition* [ Skip ]
 
 # 3D box is shaded incorrectly using SkiaRenderer Dawn on Windows.
-crbug.com/1082769 [ win dawn-skia-renderer ] Pixel_CSS3DBlueBox [ Failure ]
+crbug.com/1082769 [ win skia-renderer-dawn ] Pixel_CSS3DBlueBox [ Failure ]
 
 # Flakes on gpu-fyi-try-chromeos-kevin and Fuchsia x64, produces notably different image.
 crbug.com/1086687 [ chromeos chromeos-board-kevin ] Pixel_PrecisionRoundedCorner [ Skip ]
@@ -421,7 +421,7 @@
 crbug.com/1086690 [ chromeos ] Pixel_WebGLSadCanvas [ Skip ]
 
 # Likely produces a Dawn validation errors that makes rendering skipped.
-crbug.com/1097735 [ dawn-skia-renderer ] Pixel_PaintWorkletTransform [ Failure ]
+crbug.com/1097735 [ skia-renderer-dawn ] Pixel_PaintWorkletTransform [ Failure ]
 
 # Cannot use file in Chromium checkout for fake video capture device on Android
 # or ChromeOS.
diff --git a/content/test/gpu/gpu_tests/test_expectations/power_measurement_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/power_measurement_expectations.txt
index 208e430e..2cfada5 100644
--- a/content/test/gpu/gpu_tests/test_expectations/power_measurement_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/power_measurement_expectations.txt
@@ -30,17 +30,17 @@
 # Decoder
 # tags: [ passthrough no-passthrough ]
 # ANGLE Backend
-# tags: [ angle-no-backend
+# tags: [ angle-disabled
 #         angle-d3d9 angle-d3d11
 #         angle-metal
 #         angle-opengl angle-opengles
 #         angle-swiftshader
 #         angle-vulkan ]
 # Skia Renderer
-# tags: [ dawn-skia-renderer
-#         gl-skia-renderer
-#         no-skia-renderer
-#         vulkan-skia-renderer ]
+# tags: [ skia-renderer-dawn
+#         skia-renderer-disabled
+#         skia-renderer-gl
+#         skia-renderer-vulkan ]
 # SwiftShader
 # tags: [ swiftshader-gl no-swiftshader-gl ]
 # Driver
diff --git a/content/test/gpu/gpu_tests/test_expectations/screenshot_sync_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/screenshot_sync_expectations.txt
index d5d51fcb..912067d 100644
--- a/content/test/gpu/gpu_tests/test_expectations/screenshot_sync_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/screenshot_sync_expectations.txt
@@ -30,17 +30,17 @@
 # Decoder
 # tags: [ passthrough no-passthrough ]
 # ANGLE Backend
-# tags: [ angle-no-backend
+# tags: [ angle-disabled
 #         angle-d3d9 angle-d3d11
 #         angle-metal
 #         angle-opengl angle-opengles
 #         angle-swiftshader
 #         angle-vulkan ]
 # Skia Renderer
-# tags: [ dawn-skia-renderer
-#         gl-skia-renderer
-#         no-skia-renderer
-#         vulkan-skia-renderer ]
+# tags: [ skia-renderer-dawn
+#         skia-renderer-disabled
+#         skia-renderer-gl
+#         skia-renderer-vulkan ]
 # SwiftShader
 # tags: [ swiftshader-gl no-swiftshader-gl ]
 # Driver
@@ -70,7 +70,7 @@
 # Flakily getting a WebSocketException on Windows w/ Intel UHD 630
 crbug.com/986939 [ win intel-0x3e92 ] ScreenshotSync_GPURasterWithCanvas [ RetryOnFailure ]
 
-crbug.com/1006045 [ android android-nexus-5x gl-skia-renderer ] ScreenshotSync_GPURasterWithCanvas [ Failure ]
-crbug.com/1006045 [ android android-nexus-5x gl-skia-renderer ] ScreenshotSync_GPURasterWithDivs [ Failure ]
-crbug.com/1006045 [ android android-nexus-5x gl-skia-renderer ] ScreenshotSync_SWRasterWithCanvas [ Failure ]
-crbug.com/1006045 [ android android-nexus-5x gl-skia-renderer ] ScreenshotSync_SWRasterWithDivs [ Failure ]
+crbug.com/1006045 [ android android-nexus-5x skia-renderer-gl ] ScreenshotSync_GPURasterWithCanvas [ Failure ]
+crbug.com/1006045 [ android android-nexus-5x skia-renderer-gl ] ScreenshotSync_GPURasterWithDivs [ Failure ]
+crbug.com/1006045 [ android android-nexus-5x skia-renderer-gl ] ScreenshotSync_SWRasterWithCanvas [ Failure ]
+crbug.com/1006045 [ android android-nexus-5x skia-renderer-gl ] ScreenshotSync_SWRasterWithDivs [ Failure ]
diff --git a/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt
index f978cd4..552e142 100644
--- a/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt
@@ -30,17 +30,17 @@
 # Decoder
 # tags: [ passthrough no-passthrough ]
 # ANGLE Backend
-# tags: [ angle-no-backend
+# tags: [ angle-disabled
 #         angle-d3d9 angle-d3d11
 #         angle-metal
 #         angle-opengl angle-opengles
 #         angle-swiftshader
 #         angle-vulkan ]
 # Skia Renderer
-# tags: [ dawn-skia-renderer
-#         gl-skia-renderer
-#         no-skia-renderer
-#         vulkan-skia-renderer ]
+# tags: [ skia-renderer-dawn
+#         skia-renderer-disabled
+#         skia-renderer-gl
+#         skia-renderer-vulkan ]
 # SwiftShader
 # tags: [ swiftshader-gl no-swiftshader-gl ]
 # Driver
@@ -134,8 +134,8 @@
 crbug.com/1079393 [ win10 intel-0x3e92 ] OverlayModeTraceTest_DirectComposition_Video_VP9_YUY2 [ Failure ]
 
 # VP scaling tests are also flaky.
-crbug.com/1136971 [ win10 intel-0x3e92 ] OverlayModeTraceTest_DirectComposition_Video_MP4_VP_SCALING [ RetryOnFailure ]
-crbug.com/1136971 [ win10 intel-0x3e92 ] OverlayModeTraceTest_DirectComposition_Video_VP9_VP_SCALING [ RetryOnFailure ]
+crbug.com/1136971 [ win10 intel-0x3e92 ] OverlayModeTraceTest_DirectComposition_Video_MP4_VP_SCALING [ Skip ]
+crbug.com/1136971 [ win10 intel-0x3e92 ] OverlayModeTraceTest_DirectComposition_Video_VP9_VP_SCALING [ Skip ]
 
 # Zero copy also needs scaling to work.
 crbug.com/1079393 [ win10 intel-0x3e92 ] VideoPathTraceTest_DirectComposition_Underlay [ Failure ]
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
index e161b34..997e774 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -30,17 +30,17 @@
 # Decoder
 # tags: [ passthrough no-passthrough ]
 # ANGLE Backend
-# tags: [ angle-no-backend
+# tags: [ angle-disabled
 #         angle-d3d9 angle-d3d11
 #         angle-metal
 #         angle-opengl angle-opengles
 #         angle-swiftshader
 #         angle-vulkan ]
 # Skia Renderer
-# tags: [ dawn-skia-renderer
-#         gl-skia-renderer
-#         no-skia-renderer
-#         vulkan-skia-renderer ]
+# tags: [ skia-renderer-dawn
+#         skia-renderer-disabled
+#         skia-renderer-gl
+#         skia-renderer-vulkan ]
 # SwiftShader
 # tags: [ swiftshader-gl no-swiftshader-gl ]
 # Driver
@@ -157,7 +157,7 @@
 crbug.com/979444 [ linux ] conformance/textures/misc/texture-corner-case-videos.html [ RetryOnFailure ]
 crbug.com/979444 [ mac no-asan no-passthrough ] conformance/textures/misc/texture-corner-case-videos.html [ RetryOnFailure ]
 crbug.com/979444 [ win ] conformance/textures/misc/texture-corner-case-videos.html [ RetryOnFailure ]
-crbug.com/979444 [ android angle-no-backend ] conformance/textures/misc/texture-corner-case-videos.html [ RetryOnFailure ]
+crbug.com/979444 [ android angle-disabled ] conformance/textures/misc/texture-corner-case-videos.html [ RetryOnFailure ]
 
 # Nvidia bugs fixed in latest driver
 # TODO(http://crbug.com/887241): Upgrade the drivers on the bots.
@@ -165,6 +165,11 @@
 crbug.com/798117 [ linux nvidia ] conformance/glsl/bugs/assign-to-swizzled-twice-in-function.html [ Failure ]
 crbug.com/792210 [ nvidia ] conformance/glsl/bugs/in-parameter-passed-as-inout-argument-and-global.html [ Failure ]
 
+# Fails everywhere
+crbug.com/1004581 [ win ] conformance/rendering/multisample-corruption.html [ RetryOnFailure ]
+crbug.com/1004581 [ linux ] conformance/rendering/multisample-corruption.html [ RetryOnFailure ]
+crbug.com/1004581 [ mac ] conformance/rendering/multisample-corruption.html [ RetryOnFailure ]
+
 ####################
 # Win failures     #
 ####################
@@ -377,7 +382,7 @@
 crbug.com/angleproject/4417 [ mac no-passthrough ] conformance2/rendering/framebuffer-render-to-layer.html [ Failure ]
 
 # Flakes heavily on many OpenGL configurations
-crbug.com/832238 [ mac angle-no-backend ] conformance2/transform_feedback/too-small-buffers.html [ Failure ]
+crbug.com/832238 [ mac angle-disabled ] conformance2/transform_feedback/too-small-buffers.html [ Failure ]
 
 # Regressions in 10.12.4.
 crbug.com/705865 [ sierra intel ] conformance2/textures/misc/tex-base-level-bug.html [ Failure ]
@@ -426,7 +431,7 @@
 crbug.com/483282 [ mac nvidia-0xfe9 no-passthrough ] conformance2/glsl3/loops-with-side-effects.html [ Failure ]
 crbug.com/981122 [ mac nvidia-0xfe9 ] conformance2/rendering/framebuffer-completeness-draw-framebuffer.html [ RetryOnFailure ]
 crbug.com/996344 [ mac nvidia-0xfe9 ] conformance2/textures/misc/tex-base-level-bug.html [ Failure ]
-crbug.com/483282 [ angle-no-backend mac nvidia-0xfe9 ] conformance2/textures/misc/tex-input-validation.html [ Failure ]
+crbug.com/483282 [ angle-disabled mac nvidia-0xfe9 ] conformance2/textures/misc/tex-input-validation.html [ Failure ]
 crbug.com/996344 [ mac nvidia-0xfe9 no-passthrough ] conformance2/textures/misc/tex-mipmap-levels.html [ Failure ]
 crbug.com/682834 [ mac nvidia-0xfe9 ] conformance2/textures/image_bitmap_from_video/tex-2d-rgba16f-rgba-half_float.html [ RetryOnFailure ]
 crbug.com/784817 [ mac nvidia-0xfe9 ] conformance/glsl/bugs/init-array-with-loop.html [ Failure ]
@@ -860,8 +865,8 @@
 crbug.com/483282 [ linux amd ] deqp/functional/gles3/framebufferblit/conversion_07.html [ Failure ]
 crbug.com/658832 [ linux amd ] deqp/functional/gles3/framebufferblit/default_framebuffer_00.html [ Failure ]
 crbug.com/483282 [ linux amd ] conformance2/glsl3/vector-dynamic-indexing.html [ Failure ]
-crbug.com/483282 [ angle-no-backend linux amd ] conformance2/reading/read-pixels-pack-parameters.html [ Failure ]
-crbug.com/483282 [ angle-no-backend linux amd ] conformance2/textures/misc/tex-unpack-params.html [ Failure ]
+crbug.com/483282 [ angle-disabled linux amd ] conformance2/reading/read-pixels-pack-parameters.html [ Failure ]
+crbug.com/483282 [ angle-disabled linux amd ] conformance2/textures/misc/tex-unpack-params.html [ Failure ]
 crbug.com/662644 [ linux amd ] conformance2/rendering/clipping-wide-points.html [ Failure ]
 
 # TODO(kbr): re-enable after next conformance roll. crbug.com/736499
@@ -873,10 +878,10 @@
 # Uniform buffer related failures
 crbug.com/483282 [ linux amd ] deqp/functional/gles3/uniformbuffers/random.html [ Failure ]
 crbug.com/angleproject/5014 [ linux amd ] conformance2/uniforms/uniform-blocks-with-arrays.html [ Failure ]
-crbug.com/809595 [ angle-no-backend linux amd ] conformance2/uniforms/simple-buffer-change.html [ Failure ]
+crbug.com/809595 [ angle-disabled linux amd ] conformance2/uniforms/simple-buffer-change.html [ Failure ]
 
 # Linux AMD R7 240
-crbug.com/696345 [ angle-no-backend linux amd-0x6613 ] conformance2/transform_feedback/switching-objects.html [ Failure ]
+crbug.com/696345 [ angle-disabled linux amd-0x6613 ] conformance2/transform_feedback/switching-objects.html [ Failure ]
 crbug.com/913301 [ linux amd-0x6613 ] conformance2/textures/misc/generate-mipmap-with-large-base-level.html [ Failure ]
 crbug.com/809237 [ linux amd-0x6613 ] conformance2/uniforms/incompatible-texture-type-for-sampler.html [ Skip ]
 crbug.com/1018028 [ linux amd-0x6613 ] conformance/rendering/bind-framebuffer-flush-bug.html [ Failure ]
@@ -978,7 +983,7 @@
 
 # This test is failing on Android Pixel 2 and 3 (Qualcomm)
 # Seems to be an OpenGL ES bug.
-crbug.com/695742 [ android qualcomm angle-no-backend ] deqp/functional/gles3/multisample.html [ RetryOnFailure ]
+crbug.com/695742 [ android qualcomm angle-disabled ] deqp/functional/gles3/multisample.html [ RetryOnFailure ]
 
 # This test is flaky but can fail three times in a row so it must be
 # marked as Fail instead of Flaky.
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
index 2a179da..66761e6f 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
@@ -30,17 +30,17 @@
 # Decoder
 # tags: [ passthrough no-passthrough ]
 # ANGLE Backend
-# tags: [ angle-no-backend
+# tags: [ angle-disabled
 #         angle-d3d9 angle-d3d11
 #         angle-metal
 #         angle-opengl angle-opengles
 #         angle-swiftshader
 #         angle-vulkan ]
 # Skia Renderer
-# tags: [ dawn-skia-renderer
-#         gl-skia-renderer
-#         no-skia-renderer
-#         vulkan-skia-renderer ]
+# tags: [ skia-renderer-dawn
+#         skia-renderer-disabled
+#         skia-renderer-gl
+#         skia-renderer-vulkan ]
 # SwiftShader
 # tags: [ swiftshader-gl no-swiftshader-gl ]
 # Driver
@@ -91,14 +91,14 @@
 crbug.com/776222 [ android ] WebglExtension_WEBGL_video_texture [ Skip ]
 
 # Extensions not available with SwiftShader
-crbug.com/1099955 [ swiftshader-gl angle-no-backend linux ] WebglExtension_EXT_disjoint_timer_query [ Skip ]
-crbug.com/1099955 [ swiftshader-gl angle-no-backend mac   ] WebglExtension_EXT_disjoint_timer_query [ Skip ]
-crbug.com/1099955 [ swiftshader-gl angle-no-backend win   ] WebglExtension_EXT_disjoint_timer_query [ Skip ]
-crbug.com/1099955 [ swiftshader-gl angle-no-backend linux ] WebglExtension_EXT_shader_texture_lod [ Skip ]
-crbug.com/1099955 [ swiftshader-gl angle-no-backend mac   ] WebglExtension_EXT_shader_texture_lod [ Skip ]
-crbug.com/1099955 [ swiftshader-gl angle-no-backend win   ] WebglExtension_EXT_shader_texture_lod [ Skip ]
-crbug.com/1099955 [ swiftshader-gl angle-no-backend linux ] WebglExtension_EXT_texture_compression_bptc [ Skip ]
-crbug.com/1099955 [ swiftshader-gl angle-no-backend win   ] WebglExtension_EXT_texture_compression_bptc [ Skip ]
+crbug.com/1099955 [ swiftshader-gl angle-disabled linux ] WebglExtension_EXT_disjoint_timer_query [ Skip ]
+crbug.com/1099955 [ swiftshader-gl angle-disabled mac   ] WebglExtension_EXT_disjoint_timer_query [ Skip ]
+crbug.com/1099955 [ swiftshader-gl angle-disabled win   ] WebglExtension_EXT_disjoint_timer_query [ Skip ]
+crbug.com/1099955 [ swiftshader-gl angle-disabled linux ] WebglExtension_EXT_shader_texture_lod [ Skip ]
+crbug.com/1099955 [ swiftshader-gl angle-disabled mac   ] WebglExtension_EXT_shader_texture_lod [ Skip ]
+crbug.com/1099955 [ swiftshader-gl angle-disabled win   ] WebglExtension_EXT_shader_texture_lod [ Skip ]
+crbug.com/1099955 [ swiftshader-gl angle-disabled linux ] WebglExtension_EXT_texture_compression_bptc [ Skip ]
+crbug.com/1099955 [ swiftshader-gl angle-disabled win   ] WebglExtension_EXT_texture_compression_bptc [ Skip ]
 crbug.com/1099955 [ angle-swiftshader no-swiftshader-gl linux ] WebglExtension_EXT_disjoint_timer_query [ Skip ]
 crbug.com/1099955 [ angle-swiftshader no-swiftshader-gl mac   ] WebglExtension_EXT_disjoint_timer_query [ Skip ]
 crbug.com/1099955 [ angle-swiftshader no-swiftshader-gl win   ] WebglExtension_EXT_disjoint_timer_query [ Skip ]
@@ -165,6 +165,10 @@
 crbug.com/1018028 [ win angle-vulkan nvidia ] conformance/rendering/bind-framebuffer-flush-bug.html [ Failure ]
 crbug.com/1110111 [ win nvidia ] conformance/rendering/point-no-attributes.html [ RetryOnFailure ]
 
+crbug.com/1004581 [ win ] conformance/rendering/multisample-corruption.html [ RetryOnFailure ]
+crbug.com/1004581 [ linux ] conformance/rendering/multisample-corruption.html [ RetryOnFailure ]
+crbug.com/1004581 [ mac ] conformance/rendering/multisample-corruption.html [ RetryOnFailure ]
+
 # Skipping new tests
 crbug.com/angleproject/5038 conformance/extensions/ext-color-buffer-half-float.html [ Skip ]
 
@@ -391,7 +395,6 @@
 crbug.com/angleproject/2926 [ win amd angle-vulkan passthrough ] deqp/data/gles2/shaders/linkage.html [ Failure ]
 crbug.com/974347 [ win amd angle-vulkan passthrough ] conformance/textures/image/tex-2d-luminance-luminance-unsigned_byte.html [ Failure ]
 crbug.com/974347 [ win amd angle-vulkan passthrough ] conformance/textures/image/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html [ Failure ]
-crbug.com/1004581 [ win amd angle-vulkan passthrough ] conformance/rendering/multisample-corruption.html [ Failure ]
 crbug.com/1010942 [ win amd angle-vulkan passthrough ] conformance/glsl/samplers/glsl-function-texture2dproj.html [ Failure ]
 crbug.com/angleproject/4286 [ win amd angle-vulkan passthrough ] conformance/rendering/out-of-bounds-array-buffers.html [ Failure ]
 
@@ -417,9 +420,9 @@
 crbug.com/886970 [ mac intel-0xa2e angle-opengl ] conformance/rendering/canvas-alpha-bug.html [ Failure ]
 crbug.com/782317 [ mac intel angle-opengl ] conformance/rendering/rendering-stencil-large-viewport.html [ Failure ]
 crbug.com/1018028 [ mac intel angle-opengl ] conformance/rendering/bind-framebuffer-flush-bug.html [ Failure ]
-crbug.com/886970 [ mac intel-0xa2e angle-no-backend ] conformance/rendering/canvas-alpha-bug.html [ Failure ]
-crbug.com/782317 [ mac intel angle-no-backend ] conformance/rendering/rendering-stencil-large-viewport.html [ Failure ]
-crbug.com/1018028 [ mac intel angle-no-backend ] conformance/rendering/bind-framebuffer-flush-bug.html [ Failure ]
+crbug.com/886970 [ mac intel-0xa2e angle-disabled ] conformance/rendering/canvas-alpha-bug.html [ Failure ]
+crbug.com/782317 [ mac intel angle-disabled ] conformance/rendering/rendering-stencil-large-viewport.html [ Failure ]
+crbug.com/1018028 [ mac intel angle-disabled ] conformance/rendering/bind-framebuffer-flush-bug.html [ Failure ]
 crbug.com/1092734 [ mac passthrough intel angle-opengl ] conformance/textures/webgl_canvas/tex-2d-rgba-rgba* [ Failure ]
 
 # Mac Retina NVidia failures
@@ -549,14 +552,14 @@
 crbug.com/352645 [ android android-webview-instrumentation ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_byte.html [ Skip ]
 crbug.com/352645 [ android android-webview-instrumentation ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html [ Skip ]
 crbug.com/352645 [ android android-webview-instrumentation ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html [ Skip ]
-crbug.com/352645 [ android android-webview-instrumentation angle-no-backend ] conformance/textures/misc/texture-npot-video.html [ Skip ]
+crbug.com/352645 [ android android-webview-instrumentation angle-disabled ] conformance/textures/misc/texture-npot-video.html [ Skip ]
 
 # These video tests appear to be flaky.
 crbug.com/834933 [ android android-chromium ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_4_4_4_4.html [ RetryOnFailure ]
 crbug.com/907512 [ android android-chromium ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html [ RetryOnFailure ]
 crbug.com/733599 [ android ] conformance/textures/video/tex-2d-alpha-alpha-unsigned_byte.html [ RetryOnFailure ]
-crbug.com/733599 [ android angle-no-backend ] conformance/textures/video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html [ RetryOnFailure ]
-crbug.com/733599 [ android angle-no-backend ] conformance/textures/video/tex-2d-luminance-luminance-unsigned_byte.html [ RetryOnFailure ]
+crbug.com/733599 [ android angle-disabled ] conformance/textures/video/tex-2d-luminance_alpha-luminance_alpha-unsigned_byte.html [ RetryOnFailure ]
+crbug.com/733599 [ android angle-disabled ] conformance/textures/video/tex-2d-luminance-luminance-unsigned_byte.html [ RetryOnFailure ]
 crbug.com/834933 [ android android-chromium ] conformance/textures/video/tex-2d-rgb-rgb-unsigned_byte.html [ RetryOnFailure ]
 crbug.com/834933 [ android android-chromium ] conformance/textures/video/tex-2d-rgba-rgba-unsigned_byte.html [ RetryOnFailure ]
 crbug.com/891456 [ android ] conformance/textures/image_bitmap_from_video/tex-2d-rgba-rgba-unsigned_short_5_5_5_1.html [ RetryOnFailure ]
@@ -641,7 +644,7 @@
 
 # Nexus 6 (Adreno 420) and 6P (Adreno 430)
 crbug.com/499555 [ android qualcomm-adreno-(tm)-420 ] conformance/context/context-attributes-alpha-depth-stencil-antialias.html [ Failure ]
-crbug.com/611945 [ android angle-no-backend qualcomm-adreno-(tm)-420 ] conformance/context/context-size-change.html [ Failure ]
+crbug.com/611945 [ android angle-disabled qualcomm-adreno-(tm)-420 ] conformance/context/context-size-change.html [ Failure ]
 crbug.com/499555 [ android qualcomm-adreno-(tm)-420 ] conformance/context/premultiplyalpha-test.html [ Failure ]
 crbug.com/611945 [ android qualcomm-adreno-(tm)-420 ] conformance/glsl/bugs/gl-fragcoord-multisampling-bug.html [ Failure ]
 crbug.com/611945 [ android qualcomm-adreno-(tm)-420 ] conformance/glsl/bugs/qualcomm-crash.html [ Failure ]
@@ -730,7 +733,7 @@
 
 crbug.com/1081973 [ chromeos ] conformance/textures/misc/compressed-tex-image.html [ Failure ]
 
-crbug.com/1136106 [ chromeos-board-amd64-generic ] conformance/glsl/constructors/glsl-construct-bvec3.html [ RetryOnFailure ]
+crbug.com/1136106 [ chromeos-board-amd64-generic ] conformance/glsl/constructors/glsl-construct-bvec3.html [ Failure ]
 
 # ChromeOS: AMD
 crbug.com/995652 [ chromeos amd ] conformance/uniforms/out-of-bounds-uniform-array-access.html [ Skip ]
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py b/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py
index e31c9b2..73df0f8 100644
--- a/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py
+++ b/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py
@@ -226,7 +226,7 @@
     # Verify that Chrome's GL backend matches if a specific one was requested
     if self._gl_backend:
       if (self._gl_backend == 'angle'
-          and gpu_helper.GetANGLERenderer(gpu_info) == 'angle-no-backend'):
+          and gpu_helper.GetANGLERenderer(gpu_info) == 'angle-disabled'):
         self.fail('requested GL backend (' + self._gl_backend + ')' +
                   ' had no effect on the browser: ' +
                   _GetGPUInfoErrorString(gpu_info))
diff --git a/content/test/gpu/validate_tag_consistency.py b/content/test/gpu/validate_tag_consistency.py
index 3118103..83ad3d0 100755
--- a/content/test/gpu/validate_tag_consistency.py
+++ b/content/test/gpu/validate_tag_consistency.py
@@ -41,17 +41,17 @@
 # Decoder
 # tags: [ passthrough no-passthrough ]
 # ANGLE Backend
-# tags: [ angle-no-backend
+# tags: [ angle-disabled
 #         angle-d3d9 angle-d3d11
 #         angle-metal
 #         angle-opengl angle-opengles
 #         angle-swiftshader
 #         angle-vulkan ]
 # Skia Renderer
-# tags: [ dawn-skia-renderer
-#         gl-skia-renderer
-#         no-skia-renderer
-#         vulkan-skia-renderer ]
+# tags: [ skia-renderer-dawn
+#         skia-renderer-disabled
+#         skia-renderer-gl
+#         skia-renderer-vulkan ]
 # SwiftShader
 # tags: [ swiftshader-gl no-swiftshader-gl ]
 # Driver
diff --git a/content/test/web_ui_mojo_test_resources.grd b/content/test/web_ui_mojo_test_resources.grd
new file mode 100644
index 0000000..32464e4
--- /dev/null
+++ b/content/test/web_ui_mojo_test_resources.grd
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+This file specifies resources for content_browsertests.
+-->
+<grit latest_public_release="0" current_release="1" output_all_resource_defines="false">
+  <outputs>
+    <output filename="grit/web_ui_mojo_test_resources.h" type="rc_header">
+      <emit emit_type='prepend'></emit>
+    </output>
+    <output filename="grit/web_ui_mojo_test_resources_map.cc" type="resource_file_map_source" />
+    <output filename="grit/web_ui_mojo_test_resources_map.h" type="resource_map_header" />
+    <output filename="web_ui_mojo_test_resources.pak" type="data_package" />
+  </outputs>
+  <translations />
+  <release seq="1">
+    <includes>
+      <include name="IDR_WEB_UI_MOJO_HTML" file="data/web_ui_mojo_test.html" type="BINDATA" />
+      <include name="IDR_WEB_UI_MOJO_JS" file="data/web_ui_mojo_test.js" type="BINDATA" resource_path="web_ui_mojo_test.js" />
+      <include name="IDR_WEB_UI_MOJO_NATIVE_HTML" file="data/web_ui_mojo_native.html" type="BINDATA" resource_path="web_ui_mojo_native.html" />
+      <include name="IDR_WEB_UI_MOJO_NATIVE_JS" file="data/web_ui_mojo_native.js" type="BINDATA" resource_path="web_ui_mojo_native.js" />
+      <include name="IDR_WEB_UI_TEST_MOJOM_JS" file="${root_gen_dir}/mojom-webui/content/test/data/web_ui_test.test-mojom-webui.js" use_base_dir="false" type="BINDATA" resource_path="content/test/data/web_ui_test.test-mojom-webui.js" />
+      <include name="IDR_WEB_UI_TEST_TYPES_MOJOM_JS" file="${root_gen_dir}/mojom-webui/content/test/data/web_ui_test_types.test-mojom-webui.js" use_base_dir="false" type="BINDATA" resource_path="content/test/data/web_ui_test_types.test-mojom-webui.js" />
+    </includes>
+  </release>
+</grit>
diff --git a/content/web_test/renderer/event_sender.cc b/content/web_test/renderer/event_sender.cc
index 45f6c47..d91aebf 100644
--- a/content/web_test/renderer/event_sender.cc
+++ b/content/web_test/renderer/event_sender.cc
@@ -1266,9 +1266,6 @@
   current_drag_data_ = base::nullopt;
   current_drag_effect_ = blink::kDragOperationNone;
   current_drag_effects_allowed_ = blink::kDragOperationNone;
-  if (widget() && current_pointer_state_[kRawMousePointerId].pressed_button_ !=
-                      WebMouseEvent::Button::kNoButton)
-    widget()->MouseCaptureLost();
   current_pointer_state_.clear();
   is_drag_mode_ = true;
   force_layout_on_events_ = true;
diff --git a/content/web_test/renderer/test_runner.cc b/content/web_test/renderer/test_runner.cc
index 7270a493a..3cf443f 100644
--- a/content/web_test/renderer/test_runner.cc
+++ b/content/web_test/renderer/test_runner.cc
@@ -2308,6 +2308,7 @@
       web_widget_test_proxy->GetWebFrameWidget();
 
   web_widget->SetDeviceScaleFactorForTesting(0);
+  web_widget->ReleaseMouseLockAndPointerCaptureForTesting();
 
   // These things are only modified/valid for the main frame's widget.
   if (web_widget_test_proxy->delegate()) {
diff --git a/device/vr/BUILD.gn b/device/vr/BUILD.gn
index 2acafc7d..c86426b 100644
--- a/device/vr/BUILD.gn
+++ b/device/vr/BUILD.gn
@@ -229,10 +229,9 @@
         "openxr/openxr_api_wrapper.h",
         "openxr/openxr_controller.cc",
         "openxr/openxr_controller.h",
+        "openxr/openxr_defs.h",
         "openxr/openxr_device.cc",
         "openxr/openxr_device.h",
-        "openxr/openxr_extension_helper.cc",
-        "openxr/openxr_extension_helper.h",
         "openxr/openxr_input_helper.cc",
         "openxr/openxr_input_helper.h",
         "openxr/openxr_interaction_profiles.h",
@@ -322,8 +321,7 @@
     include_dirs = [ "//third_party/openxr/src/include" ]
 
     sources = [
-      "openxr/openxr_extension_helper.cc",
-      "openxr/openxr_extension_helper.h",
+      "openxr/openxr_defs.h",
       "openxr/openxr_util.cc",
       "openxr/openxr_util.h",
       "openxr/test/fake_openxr_impl_api.cc",
diff --git a/device/vr/android/arcore/arcore_gl.cc b/device/vr/android/arcore/arcore_gl.cc
index 39aa45466..fdc6791c 100644
--- a/device/vr/android/arcore/arcore_gl.cc
+++ b/device/vr/android/arcore/arcore_gl.cc
@@ -485,6 +485,9 @@
 
   frame_data->pose = std::move(pose);
   frame_data->time_delta = now - base::TimeTicks();
+  if (rendering_time_ratio_ > 0) {
+    frame_data->rendering_time_ratio = rendering_time_ratio_;
+  }
 
   fps_meter_.AddFrame(now);
   TRACE_COUNTER1("gpu", "WebXR FPS", fps_meter_.GetFPS());
@@ -720,6 +723,21 @@
 
   average_render_time_.AddSample(completion_time - frame->time_copied);
 
+  // Save a GPU load estimate for use in GetFrameData. This is somewhat
+  // arbitrary, use the most recent rendering time divided by the nominal frame
+  // time. If this is greater than 1.0, it's not possible to hit the target
+  // framerate and the application should reduce its workload.
+  // (Intentionally not using averages here since the blink side is expected
+  // to do its own smoothing when using this data.)
+  base::TimeDelta copied_to_completion = completion_time - frame->time_copied;
+  base::TimeDelta arcore_frametime = EstimatedArCoreFrameTime();
+  DCHECK(!arcore_frametime.is_zero());
+  rendering_time_ratio_ = copied_to_completion / arcore_frametime;
+  DVLOG(3) << __func__
+           << ": rendering time ratio (%)=" << rendering_time_ratio_ * 100;
+  TRACE_COUNTER1("xr", "WebXR rendering time ratio (%)",
+                 rendering_time_ratio_ * 100);
+
   // Add Animating/Processing/Rendering async annotations to event traces.
 
   // Trace IDs need to be unique. Since frame->index is an 8-bit wrapping value,
diff --git a/device/vr/android/arcore/arcore_gl.h b/device/vr/android/arcore/arcore_gl.h
index 0c4cb87..8447cc11 100644
--- a/device/vr/android/arcore/arcore_gl.h
+++ b/device/vr/android/arcore/arcore_gl.h
@@ -265,6 +265,8 @@
   device::SlidingTimeDeltaAverage average_process_time_;
   device::SlidingTimeDeltaAverage average_render_time_;
 
+  float rendering_time_ratio_ = 0.0f;
+
   FPSMeter fps_meter_;
 
   mojo::Receiver<mojom::XRFrameDataProvider> frame_data_receiver_{this};
diff --git a/device/vr/openxr/openxr_api_wrapper.cc b/device/vr/openxr/openxr_api_wrapper.cc
index c531483..1b48d1e 100644
--- a/device/vr/openxr/openxr_api_wrapper.cc
+++ b/device/vr/openxr/openxr_api_wrapper.cc
@@ -271,8 +271,7 @@
 // objects that may have been created before the failure.
 XrResult OpenXrApiWrapper::InitSession(
     const Microsoft::WRL::ComPtr<ID3D11Device>& d3d_device,
-    std::unique_ptr<OpenXRInputHelper>* input_helper,
-    const OpenXrExtensionHelper& extension_helper) {
+    std::unique_ptr<OpenXRInputHelper>* input_helper) {
   DCHECK(d3d_device.Get());
   DCHECK(IsInitialized());
 
@@ -287,13 +286,14 @@
   CreateSpace(XR_REFERENCE_SPACE_TYPE_STAGE, &stage_space_);
   UpdateStageBounds();
 
-  if (extension_helper.ExtensionEnumeration()->ExtensionSupported(
+  OpenXrExtensionHelper extension_helper;
+  if (extension_helper.ExtensionSupported(
           XR_MSFT_UNBOUNDED_REFERENCE_SPACE_EXTENSION_NAME)) {
     RETURN_IF_XR_FAILED(
         CreateSpace(XR_REFERENCE_SPACE_TYPE_UNBOUNDED_MSFT, &unbounded_space_));
   }
 
-  RETURN_IF_XR_FAILED(CreateGamepadHelper(input_helper, extension_helper));
+  RETURN_IF_XR_FAILED(CreateGamepadHelper(input_helper));
 
   // Since the objects in these arrays are used on every frame,
   // we don't want to create and destroy these objects every frame,
@@ -395,13 +395,12 @@
 }
 
 XrResult OpenXrApiWrapper::CreateGamepadHelper(
-    std::unique_ptr<OpenXRInputHelper>* input_helper,
-    const OpenXrExtensionHelper& extension_helper) {
+    std::unique_ptr<OpenXRInputHelper>* input_helper) {
   DCHECK(HasSession());
   DCHECK(HasSpace(XR_REFERENCE_SPACE_TYPE_LOCAL));
 
-  return OpenXRInputHelper::CreateOpenXRInputHelper(
-      instance_, extension_helper, session_, local_space_, input_helper);
+  return OpenXRInputHelper::CreateOpenXRInputHelper(instance_, session_,
+                                                    local_space_, input_helper);
 }
 
 XrResult OpenXrApiWrapper::BeginSession() {
@@ -621,20 +620,13 @@
   *right = head_from_eye_views_[1];
 }
 
-XrResult OpenXrApiWrapper::GetLuid(
-    LUID* luid,
-    const OpenXrExtensionHelper& extension_helper) const {
+XrResult OpenXrApiWrapper::GetLuid(LUID* luid) const {
   DCHECK(IsInitialized());
 
-  if (extension_helper.ExtensionMethods().xrGetD3D11GraphicsRequirementsKHR ==
-      nullptr)
-    return XR_ERROR_FUNCTION_UNSUPPORTED;
-
   XrGraphicsRequirementsD3D11KHR graphics_requirements = {
       XR_TYPE_GRAPHICS_REQUIREMENTS_D3D11_KHR};
-  RETURN_IF_XR_FAILED(
-      extension_helper.ExtensionMethods().xrGetD3D11GraphicsRequirementsKHR(
-          instance_, system_, &graphics_requirements));
+  RETURN_IF_XR_FAILED(xrGetD3D11GraphicsRequirementsKHR(
+      instance_, system_, &graphics_requirements));
 
   luid->LowPart = graphics_requirements.adapterLuid.LowPart;
   luid->HighPart = graphics_requirements.adapterLuid.HighPart;
diff --git a/device/vr/openxr/openxr_api_wrapper.h b/device/vr/openxr/openxr_api_wrapper.h
index dc2a966f..e55d8e5 100644
--- a/device/vr/openxr/openxr_api_wrapper.h
+++ b/device/vr/openxr/openxr_api_wrapper.h
@@ -47,8 +47,7 @@
   bool UpdateAndGetSessionEnded();
 
   XrResult InitSession(const Microsoft::WRL::ComPtr<ID3D11Device>& d3d_device,
-                       std::unique_ptr<OpenXRInputHelper>* input_helper,
-                       const OpenXrExtensionHelper& extension_helper);
+                       std::unique_ptr<OpenXRInputHelper>* input_helper);
 
   XrResult BeginFrame(Microsoft::WRL::ComPtr<ID3D11Texture2D>* texture);
   XrResult EndFrame();
@@ -61,8 +60,7 @@
 
   gfx::Size GetViewSize() const;
   XrTime GetPredictedDisplayTime() const;
-  XrResult GetLuid(LUID* luid,
-                   const OpenXrExtensionHelper& extension_helper) const;
+  XrResult GetLuid(LUID* luid) const;
   bool GetStageParameters(XrExtent2Df* stage_bounds,
                           gfx::Transform* local_from_stage);
   void RegisterInteractionProfileChangeCallback(
@@ -91,8 +89,8 @@
       const Microsoft::WRL::ComPtr<ID3D11Device>& d3d_device);
   XrResult CreateSwapchain();
   XrResult CreateSpace(XrReferenceSpaceType type, XrSpace* space);
-  XrResult CreateGamepadHelper(std::unique_ptr<OpenXRInputHelper>* input_helper,
-                               const OpenXrExtensionHelper& extension_helper);
+  XrResult CreateGamepadHelper(
+      std::unique_ptr<OpenXRInputHelper>* input_helper);
 
   XrResult BeginSession();
   XrResult UpdateProjectionLayers();
diff --git a/device/vr/openxr/openxr_controller.cc b/device/vr/openxr/openxr_controller.cc
index 87bce0f..65c920c 100644
--- a/device/vr/openxr/openxr_controller.cc
+++ b/device/vr/openxr/openxr_controller.cc
@@ -143,9 +143,8 @@
     const bool extension_required =
         interaction_profile.required_extension != nullptr;
     if (extension_required) {
-      const bool extension_enabled =
-          extension_helper.ExtensionEnumeration()->ExtensionSupported(
-              interaction_profile.required_extension);
+      const bool extension_enabled = extension_helper.ExtensionSupported(
+          interaction_profile.required_extension);
       if (!extension_enabled) {
         continue;
       }
diff --git a/device/vr/openxr/openxr_defs.h b/device/vr/openxr/openxr_defs.h
new file mode 100644
index 0000000..54ddb8b
--- /dev/null
+++ b/device/vr/openxr/openxr_defs.h
@@ -0,0 +1,19 @@
+// 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 DEVICE_VR_OPENXR_OPENXR_DEFS_H_
+#define DEVICE_VR_OPENXR_OPENXR_DEFS_H_
+
+namespace device {
+constexpr char kWin32AppcontainerCompatibleExtensionName[] =
+    "XR_EXT_win32_appcontainer_compatible";
+
+constexpr char kExtSamsungOdysseyControllerExtensionName[] =
+    "XR_EXT_samsung_odyssey_controller";
+constexpr char kExtHPMixedRealityControllerExtensionName[] =
+    "XR_EXT_hp_mixed_reality_controller";
+
+}  // namespace device
+
+#endif  // DEVICE_VR_OPENXR_OPENXR_DEFS_H_
diff --git a/device/vr/openxr/openxr_device.cc b/device/vr/openxr/openxr_device.cc
index 5bb76c97..3282dc89 100644
--- a/device/vr/openxr/openxr_device.cc
+++ b/device/vr/openxr/openxr_device.cc
@@ -58,13 +58,12 @@
 OpenXrDevice::OpenXrDevice(OpenXrStatics* openxr_statics)
     : VRDeviceBase(device::mojom::XRDeviceId::OPENXR_DEVICE_ID),
       instance_(openxr_statics->GetXrInstance()),
-      extension_helper_(instance_, openxr_statics->GetExtensionEnumeration()),
       weak_ptr_factory_(this) {
   mojom::VRDisplayInfoPtr display_info = CreateFakeVRDisplayInfo();
   SetVRDisplayInfo(std::move(display_info));
   SetArBlendModeSupported(IsArBlendModeSupported(openxr_statics));
 #if defined(OS_WIN)
-  SetLuid(openxr_statics->GetLuid(extension_helper_));
+  SetLuid(openxr_statics->GetLuid());
 #endif
 }
 
@@ -87,7 +86,7 @@
     auto on_info_changed = base::BindRepeating(&OpenXrDevice::SetVRDisplayInfo,
                                                weak_ptr_factory_.GetWeakPtr());
     render_loop_ = std::make_unique<OpenXrRenderLoop>(
-        std::move(on_info_changed), instance_, extension_helper_);
+        std::move(on_info_changed), instance_);
   }
 }
 
diff --git a/device/vr/openxr/openxr_device.h b/device/vr/openxr/openxr_device.h
index 150703c..1ee325d 100644
--- a/device/vr/openxr/openxr_device.h
+++ b/device/vr/openxr/openxr_device.h
@@ -8,7 +8,6 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "device/vr/openxr/openxr_util.h"
 #include "device/vr/public/mojom/vr_service.mojom.h"
 #include "device/vr/vr_device_base.h"
 #include "device/vr/vr_export.h"
@@ -54,7 +53,6 @@
   bool IsArBlendModeSupported(OpenXrStatics* openxr_statics);
 
   XrInstance instance_;
-  OpenXrExtensionHelper extension_helper_;
   std::unique_ptr<OpenXrRenderLoop> render_loop_;
 
   mojo::Receiver<mojom::XRSessionController> exclusive_controller_receiver_{
diff --git a/device/vr/openxr/openxr_extension_helper.cc b/device/vr/openxr/openxr_extension_helper.cc
deleted file mode 100644
index 892cf3d..0000000
--- a/device/vr/openxr/openxr_extension_helper.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "device/vr/openxr/openxr_extension_helper.h"
-
-namespace device {
-
-OpenXrExtensionEnumeration::OpenXrExtensionEnumeration() {
-  uint32_t extension_count;
-  if (XR_SUCCEEDED(xrEnumerateInstanceExtensionProperties(
-          nullptr, 0, &extension_count, nullptr))) {
-    extension_properties_.resize(extension_count,
-                                 {XR_TYPE_EXTENSION_PROPERTIES});
-    xrEnumerateInstanceExtensionProperties(nullptr, extension_count,
-                                           &extension_count,
-                                           extension_properties_.data());
-  }
-}
-
-OpenXrExtensionEnumeration::~OpenXrExtensionEnumeration() = default;
-
-bool OpenXrExtensionEnumeration::ExtensionSupported(
-    const char* extension_name) const {
-  return std::find_if(
-             extension_properties_.begin(), extension_properties_.end(),
-             [&extension_name](const XrExtensionProperties& properties) {
-               return strcmp(properties.extensionName, extension_name) == 0;
-             }) != extension_properties_.end();
-}
-
-OpenXrExtensionHelper::~OpenXrExtensionHelper() = default;
-
-OpenXrExtensionHelper::OpenXrExtensionHelper(
-    XrInstance instance,
-    const OpenXrExtensionEnumeration* const extension_enumeration)
-    : extension_enumeration_(extension_enumeration) {
-  // Failure results in a nullptr
-  (void)xrGetInstanceProcAddr(
-      instance, "xrGetD3D11GraphicsRequirementsKHR",
-      reinterpret_cast<PFN_xrVoidFunction*>(
-          const_cast<PFN_xrGetD3D11GraphicsRequirementsKHR*>(
-              &extension_methods_.xrGetD3D11GraphicsRequirementsKHR)));
-}
-
-}  // namespace device
diff --git a/device/vr/openxr/openxr_extension_helper.h b/device/vr/openxr/openxr_extension_helper.h
deleted file mode 100644
index 1523d37..0000000
--- a/device/vr/openxr/openxr_extension_helper.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef DEVICE_VR_OPENXR_OPENXR_EXTENSION_HELPER_H_
-#define DEVICE_VR_OPENXR_OPENXR_EXTENSION_HELPER_H_
-
-#include <d3d11.h>
-#include <vector>
-
-#include "base/logging.h"
-#include "third_party/openxr/src/include/openxr/openxr.h"
-#include "third_party/openxr/src/include/openxr/openxr_platform.h"
-
-namespace device {
-struct OpenXrExtensionMethods {
-  PFN_xrGetD3D11GraphicsRequirementsKHR xrGetD3D11GraphicsRequirementsKHR{
-      nullptr};
-};
-
-class OpenXrExtensionEnumeration {
- public:
-  OpenXrExtensionEnumeration();
-  ~OpenXrExtensionEnumeration();
-
-  bool ExtensionSupported(const char* extension_name) const;
-
- private:
-  std::vector<XrExtensionProperties> extension_properties_;
-};
-
-class OpenXrExtensionHelper {
- public:
-  OpenXrExtensionHelper(
-      XrInstance instance,
-      const OpenXrExtensionEnumeration* const extension_enumeration);
-  ~OpenXrExtensionHelper();
-
-  const OpenXrExtensionEnumeration* ExtensionEnumeration() const {
-    return extension_enumeration_;
-  }
-
-  const OpenXrExtensionMethods& ExtensionMethods() const {
-    return extension_methods_;
-  }
-
- private:
-  const OpenXrExtensionMethods extension_methods_;
-  const OpenXrExtensionEnumeration* const extension_enumeration_;
-};
-
-}  // namespace device
-
-#endif  // DEVICE_VR_OPENXR_OPENXR_EXTENSION_HELPER_H_
diff --git a/device/vr/openxr/openxr_input_helper.cc b/device/vr/openxr/openxr_input_helper.cc
index 6ea52a6..668faad 100644
--- a/device/vr/openxr/openxr_input_helper.cc
+++ b/device/vr/openxr/openxr_input_helper.cc
@@ -96,14 +96,13 @@
 
 XrResult OpenXRInputHelper::CreateOpenXRInputHelper(
     XrInstance instance,
-    const OpenXrExtensionHelper& extension_helper,
     XrSession session,
     XrSpace local_space,
     std::unique_ptr<OpenXRInputHelper>* helper) {
   std::unique_ptr<OpenXRInputHelper> new_helper =
       std::make_unique<OpenXRInputHelper>(session, local_space);
 
-  RETURN_IF_XR_FAILED(new_helper->Initialize(instance, extension_helper));
+  RETURN_IF_XR_FAILED(new_helper->Initialize(instance));
   *helper = std::move(new_helper);
   return XR_SUCCESS;
 }
@@ -115,9 +114,7 @@
 
 OpenXRInputHelper::~OpenXRInputHelper() = default;
 
-XrResult OpenXRInputHelper::Initialize(
-    XrInstance instance,
-    const OpenXrExtensionHelper& extension_helper) {
+XrResult OpenXRInputHelper::Initialize(XrInstance instance) {
   RETURN_IF_XR_FAILED(path_helper_->Initialize(instance));
 
   // This map is used to store bindings for different kinds of interaction
@@ -125,6 +122,7 @@
   // on availability.
   std::map<XrPath, std::vector<XrActionSuggestedBinding>> bindings;
 
+  OpenXrExtensionHelper extension_helper;
   for (size_t i = 0; i < controller_states_.size(); i++) {
     RETURN_IF_XR_FAILED(controller_states_[i].controller.Initialize(
         static_cast<OpenXrHandednessType>(i), instance, session_,
diff --git a/device/vr/openxr/openxr_input_helper.h b/device/vr/openxr/openxr_input_helper.h
index cf8b16c..1480abe0 100644
--- a/device/vr/openxr/openxr_input_helper.h
+++ b/device/vr/openxr/openxr_input_helper.h
@@ -13,7 +13,6 @@
 
 #include "device/vr/openxr/openxr_controller.h"
 #include "device/vr/openxr/openxr_interaction_profiles.h"
-#include "device/vr/openxr/openxr_util.h"
 
 namespace device {
 
@@ -21,7 +20,6 @@
  public:
   static XrResult CreateOpenXRInputHelper(
       XrInstance instance,
-      const OpenXrExtensionHelper& extension_helper,
       XrSession session,
       XrSpace local_space,
       std::unique_ptr<OpenXRInputHelper>* helper);
@@ -40,8 +38,7 @@
  private:
   base::Optional<Gamepad> GetWebXRGamepad(const OpenXrController& controller);
 
-  XrResult Initialize(XrInstance instance,
-                      const OpenXrExtensionHelper& extension_helper);
+  XrResult Initialize(XrInstance instance);
 
   XrResult SyncActions(XrTime predicted_display_time);
 
diff --git a/device/vr/openxr/openxr_interaction_profiles.h b/device/vr/openxr/openxr_interaction_profiles.h
index 6eb2f98..9c32aa9 100644
--- a/device/vr/openxr/openxr_interaction_profiles.h
+++ b/device/vr/openxr/openxr_interaction_profiles.h
@@ -7,6 +7,7 @@
 
 #include "base/stl_util.h"
 #include "device/gamepad/public/cpp/gamepad.h"
+#include "device/vr/openxr/openxr_defs.h"
 #include "third_party/openxr/src/include/openxr/openxr.h"
 
 namespace device {
@@ -27,8 +28,7 @@
   kHTCVive = 4,
   kSamsungOdyssey = 5,
   kHPReverbG2 = 6,
-  kHandSelect = 7,
-  kCount = 8,
+  kCount = 7,
 };
 
 enum class OpenXrButtonType {
@@ -94,7 +94,6 @@
 // Valve index controller.
 // HTC vive controller
 // HP Reverb G2 controller
-// MSFT Hand Interaction
 // Declare OpenXR input profile bindings for other runtimes when they become
 // available.
 constexpr const char* kMicrosoftMotionInputProfiles[] = {
@@ -118,9 +117,6 @@
 constexpr const char* kHPReverbG2InputProfiles[] = {
     "hp-mixed-reality", "oculus-touch", "generic-trigger-squeeze"};
 
-constexpr const char* kGenericHandSelectInputProfile[] = {
-    "generic-hand-select"};
-
 constexpr OpenXrButtonPathMap kMicrosoftMotionControllerButtonPathMaps[] = {
     {OpenXrButtonType::kTrigger,
      {
@@ -278,12 +274,6 @@
      1},
 };
 
-constexpr OpenXrButtonPathMap kGenericHandSelectButtonPathMaps[] = {
-    {OpenXrButtonType::kTrigger,
-     {{OpenXrButtonActionType::kValue, "/input/select/value"}},
-     1},
-};
-
 constexpr OpenXrAxisPathMap kMicrosoftMotionControllerAxisPathMaps[] = {
     {OpenXrAxisType::kTrackpad, "/input/trackpad"},
     {OpenXrAxisType::kThumbstick, "/input/thumbstick"},
@@ -380,7 +370,7 @@
 constexpr OpenXrControllerInteractionProfile kSamsungOdysseyInteractionProfile =
     {OpenXrInteractionProfileType::kSamsungOdyssey,
      "/interaction_profiles/samsung/odyssey_controller",
-     XR_EXT_SAMSUNG_ODYSSEY_CONTROLLER_EXTENSION_NAME,
+     kExtSamsungOdysseyControllerExtensionName,
      GamepadMapping::kXrStandard,
      kSamsungOdysseyInputProfiles,
      base::size(kSamsungOdysseyInputProfiles),
@@ -394,7 +384,7 @@
 constexpr OpenXrControllerInteractionProfile kHPReverbG2InteractionProfile = {
     OpenXrInteractionProfileType::kHPReverbG2,
     "/interaction_profiles/hp/mixed_reality_controller",
-    XR_EXT_HP_MIXED_REALITY_CONTROLLER_EXTENSION_NAME,
+    kExtHPMixedRealityControllerExtensionName,
     GamepadMapping::kXrStandard,
     kHPReverbG2InputProfiles,
     base::size(kHPReverbG2InputProfiles),
@@ -406,30 +396,11 @@
     base::size(kHPReverbG2ControllerAxisPathMaps)};
 
 constexpr OpenXrControllerInteractionProfile
-    kHandInteractionMSFTInteractionProfile = {
-        OpenXrInteractionProfileType::kHandSelect,
-        "/interaction_profiles/microsoft/hand_interaction",
-        XR_MSFT_HAND_INTERACTION_EXTENSION_NAME,
-        GamepadMapping::kNone,
-        kGenericHandSelectInputProfile,
-        base::size(kGenericHandSelectInputProfile),
-        kGenericHandSelectButtonPathMaps,
-        base::size(kGenericHandSelectButtonPathMaps),
-        kGenericHandSelectButtonPathMaps,
-        base::size(kGenericHandSelectButtonPathMaps),
-        nullptr,
-        0};
-
-constexpr OpenXrControllerInteractionProfile
     kOpenXrControllerInteractionProfiles[] = {
-        kMicrosoftMotionInteractionProfile,
-        kKHRSimpleInteractionProfile,
-        kOculusTouchInteractionProfile,
-        kValveIndexInteractionProfile,
-        kHTCViveInteractionProfile,
-        kSamsungOdysseyInteractionProfile,
-        kHPReverbG2InteractionProfile,
-        kHandInteractionMSFTInteractionProfile};
+        kMicrosoftMotionInteractionProfile, kKHRSimpleInteractionProfile,
+        kOculusTouchInteractionProfile,     kValveIndexInteractionProfile,
+        kHTCViveInteractionProfile,         kSamsungOdysseyInteractionProfile,
+        kHPReverbG2InteractionProfile};
 
 }  // namespace device
 
diff --git a/device/vr/openxr/openxr_render_loop.cc b/device/vr/openxr/openxr_render_loop.cc
index 2fe46de..831404a 100644
--- a/device/vr/openxr/openxr_render_loop.cc
+++ b/device/vr/openxr/openxr_render_loop.cc
@@ -17,11 +17,9 @@
 OpenXrRenderLoop::OpenXrRenderLoop(
     base::RepeatingCallback<void(mojom::VRDisplayInfoPtr)>
         on_display_info_changed,
-    XrInstance instance,
-    const OpenXrExtensionHelper& extension_helper)
+    XrInstance instance)
     : XRCompositorCommon(),
       instance_(instance),
-      extension_helper_(extension_helper),
       on_display_info_changed_(std::move(on_display_info_changed)) {
   DCHECK(instance_ != XR_NULL_HANDLE);
 }
@@ -93,11 +91,11 @@
 
   texture_helper_.SetUseBGRA(true);
   LUID luid;
-  if (XR_FAILED(openxr->GetLuid(&luid, extension_helper_)) ||
+  if (XR_FAILED(openxr->GetLuid(&luid)) ||
       !texture_helper_.SetAdapterLUID(luid) ||
       !texture_helper_.EnsureInitialized() ||
-      XR_FAILED(openxr->InitSession(texture_helper_.GetDevice(), &input_helper_,
-                                    extension_helper_))) {
+      XR_FAILED(
+          openxr->InitSession(texture_helper_.GetDevice(), &input_helper_))) {
     texture_helper_.Reset();
     return false;
   }
diff --git a/device/vr/openxr/openxr_render_loop.h b/device/vr/openxr/openxr_render_loop.h
index a4b0619..f3b5eb9 100644
--- a/device/vr/openxr/openxr_render_loop.h
+++ b/device/vr/openxr/openxr_render_loop.h
@@ -10,7 +10,6 @@
 
 #include "base/callback.h"
 #include "base/macros.h"
-#include "device/vr/openxr/openxr_util.h"
 #include "device/vr/windows/compositor_base.h"
 #include "third_party/openxr/src/include/openxr/openxr.h"
 
@@ -25,8 +24,7 @@
  public:
   OpenXrRenderLoop(base::RepeatingCallback<void(mojom::VRDisplayInfoPtr)>
                        on_display_info_changed,
-                   XrInstance instance,
-                   const OpenXrExtensionHelper& extension_helper_);
+                   XrInstance instance);
   ~OpenXrRenderLoop() override;
 
  private:
@@ -55,7 +53,6 @@
 
   // Owned by OpenXrStatics
   XrInstance instance_;
-  const OpenXrExtensionHelper& extension_helper_;
 
   std::unique_ptr<OpenXrApiWrapper> openxr_;
   std::unique_ptr<OpenXRInputHelper> input_helper_;
diff --git a/device/vr/openxr/openxr_statics.cc b/device/vr/openxr/openxr_statics.cc
index 5ecc088..cd38089 100644
--- a/device/vr/openxr/openxr_statics.cc
+++ b/device/vr/openxr/openxr_statics.cc
@@ -17,8 +17,7 @@
 }
 
 XrInstance OpenXrStatics::GetXrInstance() {
-  if (instance_ == XR_NULL_HANDLE &&
-      XR_FAILED(CreateInstance(&instance_, extension_enumeration_))) {
+  if (instance_ == XR_NULL_HANDLE && XR_FAILED(CreateInstance(&instance_))) {
     return XR_NULL_HANDLE;
   }
   return instance_;
@@ -40,7 +39,7 @@
 #if defined(OS_WIN)
 // Returns the LUID of the adapter the OpenXR runtime is on. Returns {0, 0} if
 // the LUID could not be determined.
-LUID OpenXrStatics::GetLuid(const OpenXrExtensionHelper& extension_helper) {
+LUID OpenXrStatics::GetLuid() {
   if (GetXrInstance() == XR_NULL_HANDLE)
     return {0, 0};
 
@@ -48,15 +47,10 @@
   if (XR_FAILED(GetSystem(instance_, &system)))
     return {0, 0};
 
-  if (extension_helper.ExtensionMethods().xrGetD3D11GraphicsRequirementsKHR ==
-      nullptr)
-    return {0, 0};
-
   XrGraphicsRequirementsD3D11KHR graphics_requirements = {
       XR_TYPE_GRAPHICS_REQUIREMENTS_D3D11_KHR};
-  if (XR_FAILED(
-          extension_helper.ExtensionMethods().xrGetD3D11GraphicsRequirementsKHR(
-              instance_, system, &graphics_requirements)))
+  if (XR_FAILED(xrGetD3D11GraphicsRequirementsKHR(instance_, system,
+                                                  &graphics_requirements)))
     return {0, 0};
 
   return graphics_requirements.adapterLuid;
diff --git a/device/vr/openxr/openxr_statics.h b/device/vr/openxr/openxr_statics.h
index 252824c..417f0cd 100644
--- a/device/vr/openxr/openxr_statics.h
+++ b/device/vr/openxr/openxr_statics.h
@@ -9,7 +9,6 @@
 #include <memory>
 
 #include "build/build_config.h"
-#include "device/vr/openxr/openxr_util.h"
 #include "device/vr/vr_export.h"
 #include "third_party/openxr/src/include/openxr/openxr.h"
 #include "third_party/openxr/src/include/openxr/openxr_platform.h"
@@ -23,22 +22,17 @@
   OpenXrStatics();
   ~OpenXrStatics();
 
-  const OpenXrExtensionEnumeration* GetExtensionEnumeration() const {
-    return &extension_enumeration_;
-  }
-
   XrInstance GetXrInstance();
 
   bool IsHardwareAvailable();
   bool IsApiAvailable();
 
 #if defined(OS_WIN)
-  LUID GetLuid(const OpenXrExtensionHelper& extension_helper);
+  LUID GetLuid();
 #endif
 
  private:
   XrInstance instance_;
-  OpenXrExtensionEnumeration extension_enumeration_;
 };
 
 }  // namespace device
diff --git a/device/vr/openxr/openxr_util.cc b/device/vr/openxr/openxr_util.cc
index e938f7353..e5fcbf1 100644
--- a/device/vr/openxr/openxr_util.cc
+++ b/device/vr/openxr/openxr_util.cc
@@ -3,8 +3,11 @@
 // found in the LICENSE file.
 
 #include "device/vr/openxr/openxr_util.h"
+#include "device/vr/openxr/openxr_defs.h"
 
+#include <d3d11.h>
 #include <string>
+#include <vector>
 
 #include "base/check_op.h"
 #include "base/stl_util.h"
@@ -12,6 +15,7 @@
 #include "base/win/scoped_handle.h"
 #include "build/build_config.h"
 #include "components/version_info/version_info.h"
+#include "third_party/openxr/src/include/openxr/openxr_platform.h"
 
 namespace device {
 
@@ -52,9 +56,30 @@
 }
 #endif
 
-XrResult CreateInstance(
-    XrInstance* instance,
-    const OpenXrExtensionEnumeration& extension_enumeration) {
+OpenXrExtensionHelper::OpenXrExtensionHelper() {
+  uint32_t extension_count;
+  if (XR_SUCCEEDED(xrEnumerateInstanceExtensionProperties(
+          nullptr, 0, &extension_count, nullptr))) {
+    extension_properties_.resize(extension_count,
+                                 {XR_TYPE_EXTENSION_PROPERTIES});
+    xrEnumerateInstanceExtensionProperties(nullptr, extension_count,
+                                           &extension_count,
+                                           extension_properties_.data());
+  }
+}
+
+OpenXrExtensionHelper::~OpenXrExtensionHelper() = default;
+
+bool OpenXrExtensionHelper::ExtensionSupported(
+    const char* extension_name) const {
+  return std::find_if(
+             extension_properties_.begin(), extension_properties_.end(),
+             [&extension_name](const XrExtensionProperties& properties) {
+               return strcmp(properties.extensionName, extension_name) == 0;
+             }) != extension_properties_.end();
+}
+
+XrResult CreateInstance(XrInstance* instance) {
   XrInstanceCreateInfo instance_create_info = {XR_TYPE_INSTANCE_CREATE_INFO};
 
   std::string application_name = version_info::GetProductName() + " " +
@@ -96,14 +121,15 @@
     // Add the win32 app container compatible extension to our list of
     // extensions. If this runtime does not support execution in an app
     // container environment, one of xrCreateInstance or xrGetSystem will fail.
-    extensions.push_back(XR_EXT_WIN32_APPCONTAINER_COMPATIBLE_EXTENSION_NAME);
+    extensions.push_back(kWin32AppcontainerCompatibleExtensionName);
   }
 
   // XR_MSFT_UNBOUNDED_REFERENCE_SPACE_EXTENSION_NAME, is required for optional
   // functionality (unbounded reference spaces) and thus only requested if it is
   // available.
+  OpenXrExtensionHelper extension_helper;
   const bool unboundedSpaceExtensionSupported =
-      extension_enumeration.ExtensionSupported(
+      extension_helper.ExtensionSupported(
           XR_MSFT_UNBOUNDED_REFERENCE_SPACE_EXTENSION_NAME);
   if (unboundedSpaceExtensionSupported) {
     extensions.push_back(XR_MSFT_UNBOUNDED_REFERENCE_SPACE_EXTENSION_NAME);
@@ -112,24 +138,17 @@
   // Input extensions. These enable interaction profiles not defined in the core
   // spec
   const bool samsungInteractionProfileExtensionSupported =
-      extension_enumeration.ExtensionSupported(
-          XR_EXT_SAMSUNG_ODYSSEY_CONTROLLER_EXTENSION_NAME);
+      extension_helper.ExtensionSupported(
+          kExtSamsungOdysseyControllerExtensionName);
   if (samsungInteractionProfileExtensionSupported) {
-    extensions.push_back(XR_EXT_SAMSUNG_ODYSSEY_CONTROLLER_EXTENSION_NAME);
+    extensions.push_back(kExtSamsungOdysseyControllerExtensionName);
   }
 
   const bool hpControllerExtensionSupported =
-      extension_enumeration.ExtensionSupported(
-          XR_EXT_HP_MIXED_REALITY_CONTROLLER_EXTENSION_NAME);
+      extension_helper.ExtensionSupported(
+          kExtHPMixedRealityControllerExtensionName);
   if (hpControllerExtensionSupported) {
-    extensions.push_back(XR_EXT_HP_MIXED_REALITY_CONTROLLER_EXTENSION_NAME);
-  }
-
-  const bool handInteractionExtensionSupported =
-      extension_enumeration.ExtensionSupported(
-          XR_MSFT_HAND_INTERACTION_EXTENSION_NAME);
-  if (handInteractionExtensionSupported) {
-    extensions.push_back(XR_MSFT_HAND_INTERACTION_EXTENSION_NAME);
+    extensions.push_back(kExtHPMixedRealityControllerExtensionName);
   }
 
   instance_create_info.enabledExtensionCount =
diff --git a/device/vr/openxr/openxr_util.h b/device/vr/openxr/openxr_util.h
index a2f4232..dd3ec51 100644
--- a/device/vr/openxr/openxr_util.h
+++ b/device/vr/openxr/openxr_util.h
@@ -5,15 +5,23 @@
 #ifndef DEVICE_VR_OPENXR_OPENXR_UTIL_H_
 #define DEVICE_VR_OPENXR_OPENXR_UTIL_H_
 
-#include <d3d11.h>
 #include <vector>
 
 #include "base/logging.h"
-#include "device/vr/openxr/openxr_extension_helper.h"
 #include "third_party/openxr/src/include/openxr/openxr.h"
-#include "third_party/openxr/src/include/openxr/openxr_platform.h"
 
 namespace device {
+class OpenXrExtensionHelper {
+ public:
+  OpenXrExtensionHelper();
+  ~OpenXrExtensionHelper();
+
+  bool ExtensionSupported(const char* extension_name) const;
+
+ private:
+  std::vector<XrExtensionProperties> extension_properties_;
+};
+
 // These macros aren't common in Chromium and generally discouraged, so define
 // all OpenXR helper macros here so they can be kept track of. This file
 // should not be included outside of device/vr/openxr.
@@ -50,9 +58,7 @@
 
 XrResult GetSystem(XrInstance instance, XrSystemId* system);
 
-XrResult CreateInstance(
-    XrInstance* instance,
-    const OpenXrExtensionEnumeration& extension_enumeration);
+XrResult CreateInstance(XrInstance* instance);
 
 std::vector<XrEnvironmentBlendMode> GetSupportedBlendModes(XrInstance instance,
                                                            XrSystemId system);
diff --git a/device/vr/openxr/test/fake_openxr_impl_api.cc b/device/vr/openxr/test/fake_openxr_impl_api.cc
index 61d0ce6..b371b80 100644
--- a/device/vr/openxr/test/fake_openxr_impl_api.cc
+++ b/device/vr/openxr/test/fake_openxr_impl_api.cc
@@ -16,8 +16,6 @@
 OpenXrTestHelper g_test_helper;
 }  // namespace
 
-// Extension methods
-
 // Mock implementations of openxr runtime.dll APIs.
 // Please add new APIs in alphabetical order.
 
@@ -905,100 +903,3 @@
 
   return XR_SUCCESS;
 }
-
-// Getter for extension methods. Casts the correct function dynamically based on
-// the method name provided.
-// Please add new OpenXR APIs below in alphabetical order.
-XrResult XRAPI_PTR xrGetInstanceProcAddr(XrInstance instance,
-                                         const char* name,
-                                         PFN_xrVoidFunction* function) {
-  if (strcmp(name, "xrAcquireSwapchainImage") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrAcquireSwapchainImage);
-  } else if (strcmp(name, "xrAttachSessionActionSets") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrAttachSessionActionSets);
-  } else if (strcmp(name, "xrBeginFrame") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrBeginFrame);
-  } else if (strcmp(name, "xrBeginSession") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrBeginSession);
-  } else if (strcmp(name, "xrCreateAction") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrCreateAction);
-  } else if (strcmp(name, "xrCreateActionSet") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrCreateActionSet);
-  } else if (strcmp(name, "xrCreateActionSpace") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrCreateActionSpace);
-  } else if (strcmp(name, "xrCreateInstance") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrCreateInstance);
-  } else if (strcmp(name, "xrCreateReferenceSpace") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrCreateReferenceSpace);
-  } else if (strcmp(name, "xrCreateSession") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrCreateSession);
-  } else if (strcmp(name, "xrCreateSwapchain") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrCreateSwapchain);
-  } else if (strcmp(name, "xrDestroyActionSet") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrDestroyActionSet);
-  } else if (strcmp(name, "xrDestroyInstance") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrDestroyInstance);
-  } else if (strcmp(name, "xrDestroySpace") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrDestroySpace);
-  } else if (strcmp(name, "xrEndFrame") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrEndFrame);
-  } else if (strcmp(name, "xrEndSession") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrEndSession);
-  } else if (strcmp(name, "xrEnumerateEnvironmentBlendModes") == 0) {
-    *function =
-        reinterpret_cast<PFN_xrVoidFunction>(xrEnumerateEnvironmentBlendModes);
-  } else if (strcmp(name, "xrEnumerateInstanceExtensionProperties") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(
-        xrEnumerateInstanceExtensionProperties);
-  } else if (strcmp(name, "xrEnumerateSwapchainImages") == 0) {
-    *function =
-        reinterpret_cast<PFN_xrVoidFunction>(xrEnumerateSwapchainImages);
-  } else if (strcmp(name, "xrEnumerateViewConfigurationViews") == 0) {
-    *function =
-        reinterpret_cast<PFN_xrVoidFunction>(xrEnumerateViewConfigurationViews);
-  } else if (strcmp(name, "xrGetD3D11GraphicsRequirementsKHR") == 0) {
-    *function =
-        reinterpret_cast<PFN_xrVoidFunction>(xrGetD3D11GraphicsRequirementsKHR);
-  } else if (strcmp(name, "xrGetActionStateFloat") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrGetActionStateFloat);
-  } else if (strcmp(name, "xrGetActionStateBoolean") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrGetActionStateBoolean);
-  } else if (strcmp(name, "xrGetActionStateVector2f") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrGetActionStateVector2f);
-  } else if (strcmp(name, "xrGetActionStatePose") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrGetActionStatePose);
-  } else if (strcmp(name, "xrGetCurrentInteractionProfile") == 0) {
-    *function =
-        reinterpret_cast<PFN_xrVoidFunction>(xrGetCurrentInteractionProfile);
-  } else if (strcmp(name, "xrGetReferenceSpaceBoundsRect") == 0) {
-    *function =
-        reinterpret_cast<PFN_xrVoidFunction>(xrGetReferenceSpaceBoundsRect);
-  } else if (strcmp(name, "xrGetSystem") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrGetSystem);
-  } else if (strcmp(name, "xrLocateSpace") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrLocateSpace);
-  } else if (strcmp(name, "xrLocateViews") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrLocateViews);
-  } else if (strcmp(name, "xrPollEvent") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrPollEvent);
-  } else if (strcmp(name, "xrReleaseSwapchainImage") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrReleaseSwapchainImage);
-  } else if (strcmp(name, "xrSuggestInteractionProfileBindings") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(
-        xrSuggestInteractionProfileBindings);
-  } else if (strcmp(name, "xrStringToPath") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrStringToPath);
-  } else if (strcmp(name, "xrPathToString") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrPathToString);
-  } else if (strcmp(name, "xrSyncActions") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrSyncActions);
-  } else if (strcmp(name, "xrWaitFrame") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrWaitFrame);
-  } else if (strcmp(name, "xrWaitSwapchainImage") == 0) {
-    *function = reinterpret_cast<PFN_xrVoidFunction>(xrWaitSwapchainImage);
-  } else {
-    return XR_ERROR_FUNCTION_UNSUPPORTED;
-  }
-
-  return XR_SUCCESS;
-}
\ No newline at end of file
diff --git a/device/vr/openxr/test/openxr_negotiate.h b/device/vr/openxr/test/openxr_negotiate.h
index b8d2cec..0d3e15e 100644
--- a/device/vr/openxr/test/openxr_negotiate.h
+++ b/device/vr/openxr/test/openxr_negotiate.h
@@ -17,19 +17,110 @@
 // only be used to call the fake OpenXR APIs defined in
 // fake_openxr_impl_api.cc.
 
-XrResult XRAPI_PTR xrGetInstanceProcAddr(XrInstance instance,
-                                         const char* name,
-                                         PFN_xrVoidFunction* function);
+// Please add new OpenXR APIs below in alphabetical order.
+XrResult XRAPI_PTR GetInstanceProcAddress(XrInstance instance,
+                                          const char* name,
+                                          PFN_xrVoidFunction* function) {
+  if (strcmp(name, "xrAcquireSwapchainImage") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrAcquireSwapchainImage);
+  } else if (strcmp(name, "xrAttachSessionActionSets") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrAttachSessionActionSets);
+  } else if (strcmp(name, "xrBeginFrame") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrBeginFrame);
+  } else if (strcmp(name, "xrBeginSession") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrBeginSession);
+  } else if (strcmp(name, "xrCreateAction") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrCreateAction);
+  } else if (strcmp(name, "xrCreateActionSet") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrCreateActionSet);
+  } else if (strcmp(name, "xrCreateActionSpace") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrCreateActionSpace);
+  } else if (strcmp(name, "xrCreateInstance") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrCreateInstance);
+  } else if (strcmp(name, "xrCreateReferenceSpace") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrCreateReferenceSpace);
+  } else if (strcmp(name, "xrCreateSession") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrCreateSession);
+  } else if (strcmp(name, "xrCreateSwapchain") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrCreateSwapchain);
+  } else if (strcmp(name, "xrDestroyActionSet") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrDestroyActionSet);
+  } else if (strcmp(name, "xrDestroyInstance") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrDestroyInstance);
+  } else if (strcmp(name, "xrDestroySpace") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrDestroySpace);
+  } else if (strcmp(name, "xrEndFrame") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrEndFrame);
+  } else if (strcmp(name, "xrEndSession") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrEndSession);
+  } else if (strcmp(name, "xrEnumerateEnvironmentBlendModes") == 0) {
+    *function =
+        reinterpret_cast<PFN_xrVoidFunction>(xrEnumerateEnvironmentBlendModes);
+  } else if (strcmp(name, "xrEnumerateInstanceExtensionProperties") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(
+        xrEnumerateInstanceExtensionProperties);
+  } else if (strcmp(name, "xrEnumerateSwapchainImages") == 0) {
+    *function =
+        reinterpret_cast<PFN_xrVoidFunction>(xrEnumerateSwapchainImages);
+  } else if (strcmp(name, "xrEnumerateViewConfigurationViews") == 0) {
+    *function =
+        reinterpret_cast<PFN_xrVoidFunction>(xrEnumerateViewConfigurationViews);
+  } else if (strcmp(name, "xrGetD3D11GraphicsRequirementsKHR") == 0) {
+    *function =
+        reinterpret_cast<PFN_xrVoidFunction>(xrGetD3D11GraphicsRequirementsKHR);
+  } else if (strcmp(name, "xrGetActionStateFloat") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrGetActionStateFloat);
+  } else if (strcmp(name, "xrGetActionStateBoolean") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrGetActionStateBoolean);
+  } else if (strcmp(name, "xrGetActionStateVector2f") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrGetActionStateVector2f);
+  } else if (strcmp(name, "xrGetActionStatePose") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrGetActionStatePose);
+  } else if (strcmp(name, "xrGetCurrentInteractionProfile") == 0) {
+    *function =
+        reinterpret_cast<PFN_xrVoidFunction>(xrGetCurrentInteractionProfile);
+  } else if (strcmp(name, "xrGetReferenceSpaceBoundsRect") == 0) {
+    *function =
+        reinterpret_cast<PFN_xrVoidFunction>(xrGetReferenceSpaceBoundsRect);
+  } else if (strcmp(name, "xrGetSystem") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrGetSystem);
+  } else if (strcmp(name, "xrLocateSpace") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrLocateSpace);
+  } else if (strcmp(name, "xrLocateViews") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrLocateViews);
+  } else if (strcmp(name, "xrPollEvent") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrPollEvent);
+  } else if (strcmp(name, "xrReleaseSwapchainImage") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrReleaseSwapchainImage);
+  } else if (strcmp(name, "xrSuggestInteractionProfileBindings") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(
+        xrSuggestInteractionProfileBindings);
+  } else if (strcmp(name, "xrStringToPath") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrStringToPath);
+  } else if (strcmp(name, "xrPathToString") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrPathToString);
+  } else if (strcmp(name, "xrSyncActions") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrSyncActions);
+  } else if (strcmp(name, "xrWaitFrame") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrWaitFrame);
+  } else if (strcmp(name, "xrWaitSwapchainImage") == 0) {
+    *function = reinterpret_cast<PFN_xrVoidFunction>(xrWaitSwapchainImage);
+  } else {
+    return XR_ERROR_FUNCTION_UNSUPPORTED;
+  }
+
+  return XR_SUCCESS;
+}
 
 // The single exported function in fake OpenXR Runtime DLL which the OpenXR
-// loader calls for negotiation. xrGetInstanceProcAddr is returned to the
+// loader calls for negotiation. GetInstanceProcAddress is returned to the
 // loader, which is then used by the loader to call OpenXR APIs.
 XrResult __stdcall xrNegotiateLoaderRuntimeInterface(
     const XrNegotiateLoaderInfo* loaderInfo,
     XrNegotiateRuntimeRequest* runtimeRequest) {
   runtimeRequest->runtimeInterfaceVersion = 1;
-  runtimeRequest->runtimeApiVersion = XR_CURRENT_API_VERSION;
-  runtimeRequest->getInstanceProcAddr = xrGetInstanceProcAddr;
+  runtimeRequest->runtimeApiVersion = XR_MAKE_VERSION(1, 0, 1);
+  runtimeRequest->getInstanceProcAddr = GetInstanceProcAddress;
 
   return XR_SUCCESS;
 }
diff --git a/device/vr/openxr/test/openxr_test_helper.h b/device/vr/openxr/test/openxr_test_helper.h
index b1b3c6aeb..2974a4e 100644
--- a/device/vr/openxr/test/openxr_test_helper.h
+++ b/device/vr/openxr/test/openxr_test_helper.h
@@ -17,6 +17,7 @@
 #include "base/optional.h"
 #include "base/stl_util.h"
 #include "base/synchronization/lock.h"
+#include "device/vr/openxr/openxr_defs.h"
 #include "device/vr/test/test_hook.h"
 #include "third_party/openxr/src/include/openxr/openxr.h"
 #include "third_party/openxr/src/include/openxr/openxr_platform.h"
@@ -129,7 +130,7 @@
   // Properties of the mock OpenXR runtime that do not change are created
   static constexpr const char* const kExtensions[] = {
       XR_KHR_D3D11_ENABLE_EXTENSION_NAME,
-      XR_EXT_WIN32_APPCONTAINER_COMPATIBLE_EXTENSION_NAME};
+      device::kWin32AppcontainerCompatibleExtensionName};
   static constexpr uint32_t kDimension = 128;
   static constexpr uint32_t kSwapCount = 1;
   static constexpr uint32_t kMinSwapchainBuffering = 3;
diff --git a/device/vr/public/mojom/vr_service.mojom b/device/vr/public/mojom/vr_service.mojom
index 555cc537..6798684 100644
--- a/device/vr/public/mojom/vr_service.mojom
+++ b/device/vr/public/mojom/vr_service.mojom
@@ -687,6 +687,14 @@
   // Hit test subscription results. Only present if the session supports
   // environment integration.
   XRHitTestSubscriptionResultsData? hit_test_subscription_results;
+
+  // If nonzero, an estimate of how much of the available render time budget
+  // was used for GPU rendering for the most recent measured frame. A value
+  // above 1.0 means that the application is dropping frames due to GPU load,
+  // and a value well below 1.0 means that GPU utilization is low. This is
+  // intended to be used as input for renderer-side adaptive viewport sizing.
+  // A value of zero means the ratio is unknown and must not be used.
+  float rendering_time_ratio;
 };
 
 // Used primarily in logging to indicate why a session was rejecting to aid
diff --git a/docs/images/vscode_python_connection_dialog.png b/docs/images/vscode_python_connection_dialog.png
new file mode 100644
index 0000000..48c0895
--- /dev/null
+++ b/docs/images/vscode_python_connection_dialog.png
Binary files differ
diff --git a/docs/vscode.md b/docs/vscode.md
index 7ddc819..523473f 100644
--- a/docs/vscode.md
+++ b/docs/vscode.md
@@ -25,6 +25,7 @@
     well, even though startup times can be fairly high (~40 seconds with
     gdb on Linux, much lower on Windows). You can step through code, inspect
     variables, view call stacks for multiple threads etc.
+    *   For more information on debugging Python code, see [here](vscode_python.md).
 *   Opening files and searching solution-wide works well now after having
     problems in earlier versions.
 *   Building works well. Build tools are easy to integrate. Warnings and errors
diff --git a/docs/vscode_python.md b/docs/vscode_python.md
new file mode 100644
index 0000000..f640e7a
--- /dev/null
+++ b/docs/vscode_python.md
@@ -0,0 +1,82 @@
+# Debugging Chromium Python With The VSCode Debugger
+
+## Before You Begin
+
+1. Patch in [this CL](https://chromium-review.googlesource.com/c/chromium/src/+/2466896).
+2. Run gclient sync.
+
+## Via SSH
+
+SSH is useful if you’re modifying and debugging code on another device, such as
+the desktop sitting at your office desk. To do so:
+
+1. Set up VSCode to work with normal development by following the instructions
+   in the Remote Visual Studio Code section
+   [here](https://docs.google.com/document/d/1ZlG8VQxudxvDs-EtpQvaPVcAPfSMdYlXr42s_487wLo/edit#bookmark=id.j10hyv6nlkws).
+2. Open the Connection Dialog of Chrome’s SSH plugin: ![open
+   dialog](images/vscode_python_connection_dialog.png)
+3. Create a new connection and set the username, hostname, port, and SSH relay
+   server options as you normally would. Then, set SSH arguments to "-2 -L
+   50371:localhost:50371"
+
+    a. You can replace 50371 with a different value, so long as it's consistent
+    with step 7b.
+
+4. Open a connection, and set this window aside.
+5. In VSCode, open the code you want to set a breakpoint in, and add the
+   following:
+
+```
+import debugpy
+
+# Your code here!
+debugpy.listen(50371)
+print("Wait for attach...")
+debugpy.wait_for_attach()
+debugpy.brerakpoint()
+```
+
+Note: The port passed to debugpy.listen() should match the port configured in (3).
+
+6. Click on the Debug tab
+7. Click Run. A dialog will appear asking you to set up a debug configuration.
+   Do so, and select “Remote Debug”.
+
+    a. Leave the hostname as-is
+
+    b. Set the port to 50371
+
+8. Run your program on the remote machine. It should stop executing at “Wait for
+   attach”.
+9. Start the debugger in VSCode. It should attach!
+
+## Locally
+
+1. On the debug tab, on the drop-down next to the play button, select “Add
+   Config”
+2. Add the following to the configurations array in “launch”:
+
+```
+{
+    "name":"Python: Local",
+    "type":"python",
+    "request":"attach",
+    "processId":"${command:pickProcess}"
+}
+```
+
+3. Add the following to your program:
+
+```
+import debugpy
+
+# Your code here!
+
+print("Wait for attach...")
+debugpy.wait_for_attach()
+debugpy.brerakpoint()
+```
+
+4. Start your program.
+5. Start the debugger. A dialog box will pop up asking you to select your
+   running program.
diff --git a/extensions/browser/url_loader_factory_manager.cc b/extensions/browser/url_loader_factory_manager.cc
index e5a3574..b0a5d8a 100644
--- a/extensions/browser/url_loader_factory_manager.cc
+++ b/extensions/browser/url_loader_factory_manager.cc
@@ -34,7 +34,6 @@
 #include "extensions/common/switches.h"
 #include "extensions/common/user_script.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
-#include "services/network/public/cpp/features.h"
 #include "services/network/public/mojom/network_context.mojom.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
 #include "url/gurl.h"
@@ -46,11 +45,6 @@
 
 namespace {
 
-bool ShouldAllowlistAlsoApplyToOorCors() {
-  return base::FeatureList::IsEnabled(
-      network::features::kCorbAllowlistAlsoAppliesToOorCors);
-}
-
 enum class FactoryUser {
   kContentScript,
   kExtensionProcess,
@@ -150,12 +144,6 @@
 
   switch (factory_user) {
     case FactoryUser::kContentScript:
-      // If |extensions_features::kCorbAllowlistAlsoAppliesToOorCors| is
-      // disabled, then go back to the legacy CORS behavior for all extensions.
-      if (!ShouldAllowlistAlsoApplyToOorCors())
-        return true;
-
-      // Otherwise, make an |extension|-specific decision.
       return DoContentScriptsDependOnRelaxedCorbOrCors(extension);
     case FactoryUser::kExtensionProcess:
       return false;
diff --git a/extensions/common/api/messaging/message.h b/extensions/common/api/messaging/message.h
index 3f34e66..c3ff586 100644
--- a/extensions/common/api/messaging/message.h
+++ b/extensions/common/api/messaging/message.h
@@ -10,13 +10,20 @@
 // A message consists of both the data itself as well as a user gesture state.
 struct Message {
   std::string data;
-  bool user_gesture;
+  bool user_gesture = false;
+  bool from_privileged_context = false;
 
-  Message() : data(), user_gesture(false) {}
-  Message(const std::string& data, bool user_gesture)
-      : data(data), user_gesture(user_gesture) {}
+  Message() = default;
+  Message(const std::string& data,
+          bool user_gesture,
+          bool from_privileged_context = false)
+      : data(data),
+        user_gesture(user_gesture),
+        from_privileged_context(from_privileged_context) {}
 
   bool operator==(const Message& other) const {
+    // Skipping the equality check for |from_privileged_context| here
+    // because this field is used only for histograms.
     return data == other.data && user_gesture == other.user_gesture;
   }
 };
diff --git a/extensions/renderer/messaging_util.cc b/extensions/renderer/messaging_util.cc
index 91b5b271..f6bf874 100644
--- a/extensions/renderer/messaging_util.cc
+++ b/extensions/renderer/messaging_util.cc
@@ -81,14 +81,18 @@
   ScriptContext* script_context = GetScriptContextFromV8Context(context);
   blink::WebLocalFrame* web_frame =
       script_context ? script_context->web_frame() : nullptr;
-  return MessageFromJSONString(isolate, stringified, error_out, web_frame);
+  bool privileged_context =
+      script_context && script_context->context_type() ==
+                            extensions::Feature::BLESSED_EXTENSION_CONTEXT;
+  return MessageFromJSONString(isolate, stringified, error_out, web_frame,
+                               privileged_context);
 }
 
-std::unique_ptr<Message> MessageFromJSONString(
-    v8::Isolate* isolate,
-    v8::Local<v8::String> json,
-    std::string* error_out,
-    blink::WebLocalFrame* web_frame) {
+std::unique_ptr<Message> MessageFromJSONString(v8::Isolate* isolate,
+                                               v8::Local<v8::String> json,
+                                               std::string* error_out,
+                                               blink::WebLocalFrame* web_frame,
+                                               bool privileged_context) {
   std::string message;
   message = gin::V8ToString(isolate, json);
   // JSON.stringify can fail to produce a string value in one of two ways: it
@@ -122,7 +126,8 @@
 
   bool has_transient_user_activation =
       web_frame ? web_frame->HasTransientUserActivation() : false;
-  return std::make_unique<Message>(message, has_transient_user_activation);
+  return std::make_unique<Message>(message, has_transient_user_activation,
+                                   privileged_context);
 }
 
 v8::Local<v8::Value> MessageToV8(v8::Local<v8::Context> context,
diff --git a/extensions/renderer/messaging_util.h b/extensions/renderer/messaging_util.h
index 35cbbc0..7a381b4 100644
--- a/extensions/renderer/messaging_util.h
+++ b/extensions/renderer/messaging_util.h
@@ -44,7 +44,8 @@
 std::unique_ptr<Message> MessageFromJSONString(v8::Isolate* isolate,
                                                v8::Local<v8::String> json,
                                                std::string* error,
-                                               blink::WebLocalFrame* web_frame);
+                                               blink::WebLocalFrame* web_frame,
+                                               bool privileged_context);
 
 // Converts a message to a v8 value. This is expected not to fail, since it
 // should only be used for messages that have been validated.
diff --git a/extensions/renderer/native_renderer_messaging_service.cc b/extensions/renderer/native_renderer_messaging_service.cc
index 4fab856..6d78a71 100644
--- a/extensions/renderer/native_renderer_messaging_service.cc
+++ b/extensions/renderer/native_renderer_messaging_service.cc
@@ -20,6 +20,7 @@
 #include "extensions/common/api/messaging/messaging_endpoint.h"
 #include "extensions/common/api/messaging/port_id.h"
 #include "extensions/common/extension_messages.h"
+#include "extensions/common/features/feature.h"
 #include "extensions/common/manifest_handlers/externally_connectable.h"
 #include "extensions/renderer/api_activity_logger.h"
 #include "extensions/renderer/bindings/api_binding_util.h"
@@ -41,6 +42,8 @@
 #include "third_party/blink/public/web/web_scoped_window_focus_allowed_indicator.h"
 #include "v8/include/v8.h"
 
+using blink::mojom::UserActivationNotificationType;
+
 namespace extensions {
 
 namespace {
@@ -317,9 +320,26 @@
   std::unique_ptr<blink::WebScopedWindowFocusAllowedIndicator>
       allow_window_focus;
   if (message.user_gesture && script_context->web_frame()) {
-    // TODO(mustaq): Split this further for trusted/untrusted cases.
-    script_context->web_frame()->NotifyUserActivation(
-        blink::mojom::UserActivationNotificationType::kExtensionMessaging);
+    bool sender_is_privileged = message.from_privileged_context;
+    bool receiver_is_privileged =
+        script_context->context_type() ==
+        extensions::Feature::BLESSED_EXTENSION_CONTEXT;
+    UserActivationNotificationType notification_type;
+    if (sender_is_privileged && receiver_is_privileged) {
+      notification_type =
+          UserActivationNotificationType::kExtensionMessagingBothPrivileged;
+    } else if (sender_is_privileged && !receiver_is_privileged) {
+      notification_type =
+          UserActivationNotificationType::kExtensionMessagingSenderPrivileged;
+    } else if (!sender_is_privileged && receiver_is_privileged) {
+      notification_type =
+          UserActivationNotificationType::kExtensionMessagingReceiverPrivileged;
+    } else /* !sender_is_privileged && !receiver_is_privileged */ {
+      notification_type =
+          UserActivationNotificationType::kExtensionMessagingNeitherPrivileged;
+    }
+
+    script_context->web_frame()->NotifyUserActivation(notification_type);
 
     blink::WebDocument document = script_context->web_frame()->GetDocument();
     allow_window_focus =
diff --git a/gpu/command_buffer/service/external_vk_image_backing.cc b/gpu/command_buffer/service/external_vk_image_backing.cc
index a5f0412..904692df 100644
--- a/gpu/command_buffer/service/external_vk_image_backing.cc
+++ b/gpu/command_buffer/service/external_vk_image_backing.cc
@@ -227,12 +227,6 @@
         VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
   }
 
-  if (usage & SHARED_IMAGE_USAGE_DISPLAY) {
-    // Skia currently requires all VkImages it uses to support transfers
-    vk_usage |=
-        VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
-  }
-
   auto* vulkan_implementation =
       context_state->vk_context_provider()->GetVulkanImplementation();
   VkImageCreateFlags vk_flags = 0;
diff --git a/gpu/command_buffer/service/external_vk_image_factory_unittest.cc b/gpu/command_buffer/service/external_vk_image_factory_unittest.cc
index 36587be2..f682f81 100644
--- a/gpu/command_buffer/service/external_vk_image_factory_unittest.cc
+++ b/gpu/command_buffer/service/external_vk_image_factory_unittest.cc
@@ -208,7 +208,6 @@
     auto sk_image = SkImage::MakeFromTexture(
         context_state_->gr_context(), backend_texture, kTopLeft_GrSurfaceOrigin,
         kRGBA_8888_SkColorType, kOpaque_SkAlphaType, nullptr);
-    EXPECT_TRUE(sk_image);
 
     const SkImageInfo dst_info =
         SkImageInfo::Make(size.width(), size.height(), kRGBA_8888_SkColorType,
@@ -386,4 +385,4 @@
 #endif  // BUILDFLAG(USE_DAWN)
 
 }  // anonymous namespace
-}  // namespace gpu
+}  // namespace gpu
\ No newline at end of file
diff --git a/gpu/command_buffer/service/skia_utils.cc b/gpu/command_buffer/service/skia_utils.cc
index 58455e4..c8f00902 100644
--- a/gpu/command_buffer/service/skia_utils.cc
+++ b/gpu/command_buffer/service/skia_utils.cc
@@ -219,8 +219,6 @@
   image_info.fImageTiling = image->image_tiling();
   image_info.fImageLayout = image->image_layout();
   image_info.fFormat = image->format();
-  image_info.fImageUsageFlags = image->usage();
-  image_info.fSampleCount = 1;
   image_info.fLevelCount = 1;
   image_info.fCurrentQueueFamily = image->queue_family_index();
   image_info.fProtected = is_protected ? GrProtected::kYes : GrProtected::kNo;
diff --git a/gpu/vulkan/demo/vulkan_demo.cc b/gpu/vulkan/demo/vulkan_demo.cc
index cef0156..c2fe838 100644
--- a/gpu/vulkan/demo/vulkan_demo.cc
+++ b/gpu/vulkan/demo/vulkan_demo.cc
@@ -120,8 +120,6 @@
     vk_image_info.fImageLayout = scoped_write_->image_layout();
     vk_image_info.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
     vk_image_info.fFormat = VK_FORMAT_B8G8R8A8_UNORM;
-    vk_image_info.fImageUsageFlags = scoped_write_->image_usage();
-    vk_image_info.fSampleCount = 1;
     vk_image_info.fLevelCount = 1;
     const auto& size = vulkan_surface_->image_size();
     GrBackendRenderTarget render_target(size.width(), size.height(), 0,
diff --git a/gpu/vulkan/vulkan_swap_chain.cc b/gpu/vulkan/vulkan_swap_chain.cc
index 1fdfc3de..198fd0f 100644
--- a/gpu/vulkan/vulkan_swap_chain.cc
+++ b/gpu/vulkan/vulkan_swap_chain.cc
@@ -234,8 +234,6 @@
          base::TaskShutdownBehavior::BLOCK_SHUTDOWN, base::MayBlock()});
   }
 
-  image_usage_ = image_usage_flags;
-
   return true;
 }
 
@@ -292,7 +290,6 @@
 bool VulkanSwapChain::BeginWriteCurrentImage(VkImage* image,
                                              uint32_t* image_index,
                                              VkImageLayout* image_layout,
-                                             VkImageUsageFlags* image_usage,
                                              VkSemaphore* begin_semaphore,
                                              VkSemaphore* end_semaphore) {
   base::AutoLock auto_lock(lock_);
@@ -300,7 +297,6 @@
   DCHECK(image);
   DCHECK(image_index);
   DCHECK(image_layout);
-  DCHECK(image_usage);
   DCHECK(begin_semaphore);
   DCHECK(end_semaphore);
   DCHECK(!is_writing_);
@@ -331,7 +327,6 @@
   *image = current_image_data.image;
   *image_index = *acquired_image_;
   *image_layout = current_image_data.image_layout;
-  *image_usage = image_usage_;
   *begin_semaphore = current_image_data.acquire_semaphore;
   *end_semaphore = current_image_data.present_semaphore;
   is_writing_ = true;
@@ -573,7 +568,7 @@
 VulkanSwapChain::ScopedWrite::ScopedWrite(VulkanSwapChain* swap_chain)
     : swap_chain_(swap_chain) {
   success_ = swap_chain_->BeginWriteCurrentImage(
-      &image_, &image_index_, &image_layout_, &image_usage_, &begin_semaphore_,
+      &image_, &image_index_, &image_layout_, &begin_semaphore_,
       &end_semaphore_);
   if (LIKELY(success_)) {
     DCHECK(begin_semaphore_ != VK_NULL_HANDLE);
@@ -595,4 +590,4 @@
   }
 }
 
-}  // namespace gpu
+}  // namespace gpu
\ No newline at end of file
diff --git a/gpu/vulkan/vulkan_swap_chain.h b/gpu/vulkan/vulkan_swap_chain.h
index b4ecf51..5f94fca1 100644
--- a/gpu/vulkan/vulkan_swap_chain.h
+++ b/gpu/vulkan/vulkan_swap_chain.h
@@ -42,7 +42,6 @@
     VkImage image() const { return image_; }
     uint32_t image_index() const { return image_index_; }
     VkImageLayout image_layout() const { return image_layout_; }
-    VkImageUsageFlags image_usage() const { return image_usage_; }
     VkSemaphore begin_semaphore() const { return begin_semaphore_; }
     VkSemaphore end_semaphore() const { return end_semaphore_; }
 
@@ -52,7 +51,6 @@
     VkImage image_ = VK_NULL_HANDLE;
     uint32_t image_index_ = 0;
     VkImageLayout image_layout_ = VK_IMAGE_LAYOUT_UNDEFINED;
-    VkImageUsageFlags image_usage_ = 0;
     VkSemaphore begin_semaphore_ = VK_NULL_HANDLE;
     VkSemaphore end_semaphore_ = VK_NULL_HANDLE;
 
@@ -136,7 +134,6 @@
   bool BeginWriteCurrentImage(VkImage* image,
                               uint32_t* image_index,
                               VkImageLayout* layout,
-                              VkImageUsageFlags* usage,
                               VkSemaphore* begin_semaphore,
                               VkSemaphore* end_semaphore);
   void EndWriteCurrentImage();
@@ -166,8 +163,6 @@
   // Images in the swap chain.
   std::vector<ImageData> images_ GUARDED_BY(lock_);
 
-  VkImageUsageFlags image_usage_ = 0;
-
   // True if BeginWriteCurrentImage() is called, but EndWriteCurrentImage() is
   // not.
   bool is_writing_ GUARDED_BY(lock_) = false;
@@ -209,4 +204,4 @@
 
 }  // namespace gpu
 
-#endif  // GPU_VULKAN_VULKAN_SWAP_CHAIN_H_
+#endif  // GPU_VULKAN_VULKAN_SWAP_CHAIN_H_
\ No newline at end of file
diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg
index be7ee5d..3ed66c2 100644
--- a/infra/config/generated/cr-buildbucket.cfg
+++ b/infra/config/generated/cr-buildbucket.cfg
@@ -39,7 +39,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -72,7 +72,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -105,7 +105,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -138,7 +138,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -171,7 +171,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -204,7 +204,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -237,7 +237,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -270,7 +270,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -303,7 +303,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -336,7 +336,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -379,7 +379,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -422,7 +422,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -465,7 +465,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -508,7 +508,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -551,7 +551,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -594,7 +594,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -637,7 +637,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -680,7 +680,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -723,7 +723,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -766,7 +766,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -809,7 +809,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -852,7 +852,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -895,7 +895,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -938,7 +938,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -981,7 +981,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1024,7 +1024,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1057,7 +1057,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1090,7 +1090,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1123,7 +1123,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1156,7 +1156,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1189,7 +1189,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1222,7 +1222,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1255,7 +1255,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1288,7 +1288,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1321,7 +1321,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1354,7 +1354,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1387,7 +1387,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1420,7 +1420,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1453,7 +1453,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1486,7 +1486,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1519,7 +1519,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1562,7 +1562,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1605,7 +1605,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1638,7 +1638,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1671,7 +1671,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1704,7 +1704,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1737,7 +1737,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1770,7 +1770,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1803,7 +1803,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1836,7 +1836,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1869,7 +1869,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1900,7 +1900,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1931,7 +1931,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1964,7 +1964,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -1997,7 +1997,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2030,7 +2030,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2063,7 +2063,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2096,7 +2096,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2129,7 +2129,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2162,7 +2162,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2195,7 +2195,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2228,7 +2228,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2261,7 +2261,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2294,7 +2294,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2327,7 +2327,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2360,7 +2360,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2393,7 +2393,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2426,7 +2426,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2459,7 +2459,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2492,7 +2492,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2525,7 +2525,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2558,7 +2558,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2591,7 +2591,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2624,7 +2624,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2657,7 +2657,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2690,7 +2690,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2723,7 +2723,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2756,7 +2756,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2799,7 +2799,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2842,7 +2842,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2885,7 +2885,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2926,7 +2926,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -2967,7 +2967,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -3008,7 +3008,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -3051,7 +3051,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -3094,7 +3094,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -3137,7 +3137,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -3180,7 +3180,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -3223,7 +3223,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -3266,7 +3266,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -3309,7 +3309,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -3352,7 +3352,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -3395,7 +3395,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -3438,7 +3438,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -3481,7 +3481,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -3524,7 +3524,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -3565,7 +3565,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -3606,7 +3606,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -3649,7 +3649,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -3692,7 +3692,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -3735,7 +3735,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -3768,7 +3768,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -3801,7 +3801,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -3834,7 +3834,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -3867,7 +3867,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -3899,7 +3899,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -3932,7 +3932,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -3965,7 +3965,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -3998,7 +3998,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4031,7 +4031,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4064,7 +4064,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4097,7 +4097,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4129,7 +4129,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4161,7 +4161,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4194,7 +4194,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4227,7 +4227,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4260,7 +4260,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4293,7 +4293,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4326,7 +4326,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4359,7 +4359,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4392,7 +4392,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4425,7 +4425,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4458,7 +4458,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4491,7 +4491,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4524,7 +4524,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4557,7 +4557,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4590,7 +4590,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4633,7 +4633,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4676,7 +4676,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4719,7 +4719,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4762,7 +4762,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4805,7 +4805,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4848,7 +4848,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4891,7 +4891,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4934,7 +4934,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -4977,7 +4977,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5020,7 +5020,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5063,7 +5063,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5106,7 +5106,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5149,7 +5149,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5192,7 +5192,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5235,7 +5235,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5268,7 +5268,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5301,7 +5301,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5334,7 +5334,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5367,7 +5367,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5400,7 +5400,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5443,7 +5443,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5476,7 +5476,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5509,7 +5509,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5542,7 +5542,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5579,7 +5579,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5616,7 +5616,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5653,7 +5653,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5686,7 +5686,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5719,7 +5719,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5752,7 +5752,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5785,7 +5785,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5817,7 +5817,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5849,7 +5849,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5880,7 +5880,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5912,7 +5912,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5943,7 +5943,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -5974,7 +5974,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -6008,7 +6008,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -6041,7 +6041,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -6084,7 +6084,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -6127,7 +6127,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -6170,7 +6170,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -6213,7 +6213,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -6254,7 +6254,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -6297,7 +6297,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -6340,7 +6340,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -6383,7 +6383,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -6426,7 +6426,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -6469,7 +6469,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -6510,7 +6510,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -6553,7 +6553,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -6596,7 +6596,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -6639,7 +6639,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -6682,7 +6682,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -6725,7 +6725,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -6768,7 +6768,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -6813,7 +6813,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -6848,7 +6848,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -6881,7 +6881,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -6914,7 +6914,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -6947,7 +6947,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -6980,7 +6980,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7013,7 +7013,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7046,7 +7046,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7079,7 +7079,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7112,7 +7112,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7145,7 +7145,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7178,7 +7178,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7211,7 +7211,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7244,7 +7244,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7277,7 +7277,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7309,7 +7309,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7342,7 +7342,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7375,7 +7375,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7408,7 +7408,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7445,7 +7445,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7478,7 +7478,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7511,7 +7511,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7544,7 +7544,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7577,7 +7577,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7610,7 +7610,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7643,7 +7643,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7676,7 +7676,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7709,7 +7709,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7742,7 +7742,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7775,7 +7775,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7808,7 +7808,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7841,7 +7841,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7873,7 +7873,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7906,7 +7906,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7939,7 +7939,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -7972,7 +7972,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8005,7 +8005,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8038,7 +8038,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8071,7 +8071,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8104,7 +8104,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8137,7 +8137,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8170,7 +8170,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8203,7 +8203,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8236,7 +8236,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8269,7 +8269,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8302,7 +8302,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8335,7 +8335,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8368,7 +8368,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8401,7 +8401,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8437,7 +8437,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8473,7 +8473,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8506,7 +8506,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8539,7 +8539,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8572,7 +8572,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8609,7 +8609,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8642,7 +8642,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8675,7 +8675,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8708,7 +8708,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8740,7 +8740,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8776,7 +8776,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8808,7 +8808,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8840,7 +8840,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8872,7 +8872,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8904,7 +8904,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8936,7 +8936,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -8968,7 +8968,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -9001,7 +9001,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -9034,7 +9034,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -9077,7 +9077,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -9120,7 +9120,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -9163,7 +9163,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -9206,7 +9206,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -9249,7 +9249,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -9292,7 +9292,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -9335,7 +9335,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -9378,7 +9378,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -9421,7 +9421,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -9464,7 +9464,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -9507,7 +9507,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -9550,7 +9550,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -9593,7 +9593,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -9636,7 +9636,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -9678,7 +9678,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -9710,7 +9710,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -9746,7 +9746,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -9782,7 +9782,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -9815,7 +9815,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -9858,7 +9858,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -9900,7 +9900,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -9933,7 +9933,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -9976,7 +9976,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10019,7 +10019,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10062,7 +10062,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10105,7 +10105,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10148,7 +10148,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10190,7 +10190,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10222,7 +10222,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10254,7 +10254,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10287,7 +10287,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10320,7 +10320,7 @@
       service_account: "chromium-cipd-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10353,7 +10353,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10386,7 +10386,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10419,7 +10419,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10452,7 +10452,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10485,7 +10485,7 @@
       service_account: "chromium-cipd-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10518,7 +10518,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10551,7 +10551,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10588,7 +10588,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10625,7 +10625,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10658,7 +10658,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10691,7 +10691,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10724,7 +10724,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10757,7 +10757,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10790,7 +10790,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10823,7 +10823,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10856,7 +10856,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10889,7 +10889,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10919,7 +10919,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10952,7 +10952,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -10985,7 +10985,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11018,7 +11018,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11051,7 +11051,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11084,7 +11084,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11117,7 +11117,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11150,7 +11150,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11183,7 +11183,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11216,7 +11216,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11249,7 +11249,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11282,7 +11282,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11315,7 +11315,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11348,7 +11348,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11381,7 +11381,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11414,7 +11414,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11447,7 +11447,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11480,7 +11480,7 @@
       service_account: "chromium-cipd-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11513,7 +11513,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11546,7 +11546,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11579,7 +11579,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11612,7 +11612,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11645,7 +11645,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11682,7 +11682,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11715,7 +11715,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11748,7 +11748,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11781,7 +11781,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11814,7 +11814,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11847,7 +11847,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11884,7 +11884,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11921,7 +11921,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11958,7 +11958,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -11995,7 +11995,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12028,7 +12028,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12061,7 +12061,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12094,7 +12094,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12133,7 +12133,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12168,7 +12168,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12203,7 +12203,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12243,7 +12243,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12282,7 +12282,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12321,7 +12321,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12356,7 +12356,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12395,7 +12395,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12430,7 +12430,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12469,7 +12469,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12508,7 +12508,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12547,7 +12547,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12586,7 +12586,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12625,7 +12625,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12664,7 +12664,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12701,7 +12701,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12734,7 +12734,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12767,7 +12767,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12804,7 +12804,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12837,7 +12837,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12874,7 +12874,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12911,7 +12911,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12948,7 +12948,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -12984,7 +12984,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13020,7 +13020,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13057,7 +13057,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13094,7 +13094,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13131,7 +13131,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13164,7 +13164,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13201,7 +13201,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13234,7 +13234,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13271,7 +13271,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13308,7 +13308,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13345,7 +13345,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13382,7 +13382,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13415,7 +13415,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13452,7 +13452,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13489,7 +13489,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13522,7 +13522,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13559,7 +13559,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13592,7 +13592,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13624,7 +13624,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13657,7 +13657,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13694,7 +13694,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13727,7 +13727,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13760,7 +13760,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13793,7 +13793,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13826,7 +13826,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13859,7 +13859,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13892,7 +13892,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13925,7 +13925,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13958,7 +13958,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -13995,7 +13995,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14028,7 +14028,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14066,7 +14066,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14104,7 +14104,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14142,7 +14142,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14174,7 +14174,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14206,7 +14206,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14237,7 +14237,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14270,7 +14270,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14307,7 +14307,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14343,7 +14343,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14375,7 +14375,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14406,7 +14406,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14441,7 +14441,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14478,7 +14478,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14509,7 +14509,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14545,7 +14545,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14582,7 +14582,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14619,7 +14619,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14656,7 +14656,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14693,7 +14693,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14730,7 +14730,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14767,7 +14767,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14800,7 +14800,7 @@
       service_account: "component-mapping-updater@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14837,7 +14837,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14869,7 +14869,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14901,7 +14901,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14934,7 +14934,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14966,7 +14966,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -14998,7 +14998,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15030,7 +15030,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15066,7 +15066,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15102,7 +15102,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15137,7 +15137,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15170,7 +15170,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15203,7 +15203,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15236,7 +15236,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15269,7 +15269,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15302,7 +15302,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15335,7 +15335,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15368,7 +15368,7 @@
       service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15405,7 +15405,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15442,7 +15442,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15478,7 +15478,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15510,7 +15510,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15542,7 +15542,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15578,7 +15578,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15610,7 +15610,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15647,7 +15647,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15701,7 +15701,7 @@
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15739,7 +15739,7 @@
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15777,7 +15777,7 @@
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15815,7 +15815,7 @@
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15853,7 +15853,7 @@
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15891,7 +15891,7 @@
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15944,7 +15944,7 @@
       service_account: "findit-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -15972,7 +15972,7 @@
       service_account: "findit-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16001,7 +16001,7 @@
       service_account: "findit-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16043,7 +16043,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16069,7 +16069,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16095,7 +16095,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16121,7 +16121,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16147,7 +16147,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16173,7 +16173,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16199,7 +16199,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16225,7 +16225,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16251,7 +16251,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16277,7 +16277,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16303,7 +16303,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16329,7 +16329,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16355,7 +16355,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16381,7 +16381,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16407,7 +16407,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16433,7 +16433,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16459,7 +16459,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16485,7 +16485,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16515,7 +16515,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16541,7 +16541,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16568,7 +16568,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16595,7 +16595,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16622,7 +16622,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16649,7 +16649,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16675,7 +16675,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16701,7 +16701,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16727,7 +16727,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16753,7 +16753,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16779,7 +16779,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16805,7 +16805,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16831,7 +16831,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16857,7 +16857,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16883,7 +16883,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16909,7 +16909,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16935,7 +16935,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16961,7 +16961,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -16987,7 +16987,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17013,7 +17013,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17039,7 +17039,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17065,7 +17065,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17091,7 +17091,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17117,7 +17117,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17144,7 +17144,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17171,7 +17171,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17198,7 +17198,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17225,7 +17225,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17252,7 +17252,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17279,7 +17279,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17306,7 +17306,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17333,7 +17333,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17360,7 +17360,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17387,7 +17387,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17413,7 +17413,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17439,7 +17439,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17468,7 +17468,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17497,7 +17497,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17526,7 +17526,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17555,7 +17555,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17582,7 +17582,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17609,7 +17609,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17636,7 +17636,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17663,7 +17663,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17690,7 +17690,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17717,7 +17717,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17744,7 +17744,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17771,7 +17771,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17797,7 +17797,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17823,7 +17823,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17849,7 +17849,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17875,7 +17875,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17901,7 +17901,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17927,7 +17927,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17953,7 +17953,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -17979,7 +17979,7 @@
       service_account: "goma-release-testing@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -18062,7 +18062,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -18103,7 +18103,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -18144,7 +18144,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -18185,7 +18185,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -18226,7 +18226,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -18267,7 +18267,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -18308,7 +18308,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -18349,7 +18349,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -18390,7 +18390,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -18431,7 +18431,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -18472,7 +18472,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -18513,7 +18513,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -18554,7 +18554,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -18595,7 +18595,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -18636,7 +18636,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -18677,7 +18677,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -18718,7 +18718,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -18759,7 +18759,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -18800,7 +18800,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -18841,7 +18841,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -18882,7 +18882,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -18923,7 +18923,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -18964,7 +18964,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -19005,7 +19005,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -19046,7 +19046,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -19087,7 +19087,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -19128,7 +19128,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -19169,7 +19169,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -19209,7 +19209,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -19249,7 +19249,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -19289,7 +19289,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -19329,7 +19329,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -19369,7 +19369,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -19409,7 +19409,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -19450,7 +19450,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -19491,7 +19491,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -19532,7 +19532,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -19573,7 +19573,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -19614,7 +19614,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -19655,7 +19655,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -19696,7 +19696,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -19737,7 +19737,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -19778,7 +19778,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -19819,7 +19819,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -19860,7 +19860,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -19900,7 +19900,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -19941,7 +19941,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -19982,7 +19982,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -20023,7 +20023,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -20064,7 +20064,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -20105,7 +20105,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -20146,7 +20146,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -20187,7 +20187,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -20228,7 +20228,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -20269,7 +20269,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -20310,7 +20310,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -20351,7 +20351,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -20392,7 +20392,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -20431,7 +20431,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -20470,7 +20470,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -20509,7 +20509,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -20548,7 +20548,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -20587,7 +20587,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -20626,7 +20626,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -20666,7 +20666,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -20707,7 +20707,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -20748,7 +20748,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -20789,7 +20789,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -20830,7 +20830,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -20871,7 +20871,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -20912,7 +20912,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -20953,7 +20953,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -20994,7 +20994,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -21035,7 +21035,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -21076,7 +21076,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -21116,7 +21116,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -21156,7 +21156,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -21196,7 +21196,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -21236,7 +21236,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -21276,7 +21276,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -21316,7 +21316,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -21356,7 +21356,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -21396,7 +21396,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -21436,7 +21436,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -21476,7 +21476,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -21516,7 +21516,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -21556,7 +21556,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -21596,7 +21596,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -21636,7 +21636,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -21676,7 +21676,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -21716,7 +21716,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -21756,7 +21756,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -21796,7 +21796,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -21836,7 +21836,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -21876,7 +21876,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -21916,7 +21916,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -21956,7 +21956,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -21996,7 +21996,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -22036,7 +22036,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -22076,7 +22076,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -22116,7 +22116,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -22156,7 +22156,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -22195,7 +22195,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -22234,7 +22234,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -22273,7 +22273,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -22312,7 +22312,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -22351,7 +22351,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -22390,7 +22390,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -22429,7 +22429,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -22468,7 +22468,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -22507,7 +22507,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -22546,7 +22546,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -22585,7 +22585,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -22624,7 +22624,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -22663,7 +22663,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -22702,7 +22702,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -22742,7 +22742,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -22782,7 +22782,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -22822,7 +22822,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -22862,7 +22862,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -22902,7 +22902,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -22942,7 +22942,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -22982,7 +22982,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -23022,7 +23022,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -23062,7 +23062,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -23102,7 +23102,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -23142,7 +23142,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -23182,7 +23182,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -23222,7 +23222,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -23262,7 +23262,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -23302,7 +23302,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -23342,7 +23342,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -23382,7 +23382,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -23422,7 +23422,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -23462,7 +23462,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -23502,7 +23502,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -23541,7 +23541,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -23580,7 +23580,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -23620,7 +23620,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -23663,7 +23663,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -23706,7 +23706,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -23749,7 +23749,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -23792,7 +23792,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -23835,7 +23835,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -23878,7 +23878,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -23921,7 +23921,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -23964,7 +23964,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -24007,7 +24007,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -24050,7 +24050,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -24093,7 +24093,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -24136,7 +24136,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -24177,7 +24177,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -24218,7 +24218,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -24258,7 +24258,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -24299,7 +24299,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -24340,7 +24340,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -24381,7 +24381,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -24422,7 +24422,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -24463,7 +24463,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -24504,7 +24504,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -24545,7 +24545,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -24586,7 +24586,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -24627,7 +24627,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -24668,7 +24668,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -24709,7 +24709,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -24750,7 +24750,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -24791,7 +24791,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -24830,7 +24830,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -24871,7 +24871,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -24912,7 +24912,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -24953,7 +24953,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -24994,7 +24994,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -25035,7 +25035,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -25076,7 +25076,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -25117,7 +25117,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -25158,7 +25158,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -25199,7 +25199,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -25240,7 +25240,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -25281,7 +25281,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -25322,7 +25322,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -25362,7 +25362,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -25403,7 +25403,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -25444,7 +25444,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -25485,7 +25485,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -25526,7 +25526,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -25567,7 +25567,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -25608,7 +25608,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -25649,7 +25649,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -25690,7 +25690,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -25731,7 +25731,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -25772,7 +25772,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -25813,7 +25813,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -25854,7 +25854,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -25895,7 +25895,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -25936,7 +25936,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -25976,7 +25976,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -26016,7 +26016,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -26057,7 +26057,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -26098,7 +26098,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -26139,7 +26139,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -26180,7 +26180,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -26221,7 +26221,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -26262,7 +26262,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -26303,7 +26303,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -26344,7 +26344,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -26385,7 +26385,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -26430,7 +26430,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -26471,7 +26471,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -26516,7 +26516,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -26557,7 +26557,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -26598,7 +26598,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -26639,7 +26639,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -26680,7 +26680,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -26721,7 +26721,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -26762,7 +26762,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -26803,7 +26803,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -26843,7 +26843,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -26884,7 +26884,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -26925,7 +26925,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -26964,7 +26964,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -27004,7 +27004,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -27043,7 +27043,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -27082,7 +27082,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -27122,7 +27122,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -27162,7 +27162,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -27201,7 +27201,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -27241,7 +27241,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -27281,7 +27281,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -27321,7 +27321,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -27361,7 +27361,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -27401,7 +27401,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -27441,7 +27441,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -27481,7 +27481,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -27521,7 +27521,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -27561,7 +27561,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -27601,7 +27601,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -27641,7 +27641,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -27681,7 +27681,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -27721,7 +27721,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -27761,7 +27761,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -27801,7 +27801,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -27841,7 +27841,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -27880,7 +27880,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -27920,7 +27920,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -27961,7 +27961,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -28002,7 +28002,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -28043,7 +28043,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -28083,7 +28083,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -28123,7 +28123,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -28163,7 +28163,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -28203,7 +28203,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -28244,7 +28244,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -28285,7 +28285,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -28326,7 +28326,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -28365,7 +28365,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -28405,7 +28405,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -28446,7 +28446,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -28487,7 +28487,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -28528,7 +28528,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -28569,7 +28569,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -28610,7 +28610,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -28651,7 +28651,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -28692,7 +28692,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -28733,7 +28733,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -28774,7 +28774,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -28814,7 +28814,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -28855,7 +28855,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -28896,7 +28896,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -28936,7 +28936,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -28977,7 +28977,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29018,7 +29018,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29059,7 +29059,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29100,7 +29100,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29141,7 +29141,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29182,7 +29182,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29223,7 +29223,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29264,7 +29264,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29305,7 +29305,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29346,7 +29346,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29386,7 +29386,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29427,7 +29427,7 @@
       }
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29473,7 +29473,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29497,7 +29497,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29521,7 +29521,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29545,7 +29545,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29570,7 +29570,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29594,7 +29594,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29618,7 +29618,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29642,7 +29642,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29666,7 +29666,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29690,7 +29690,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29730,7 +29730,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29754,7 +29754,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29778,7 +29778,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29802,7 +29802,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29826,7 +29826,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29850,7 +29850,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29874,7 +29874,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29898,7 +29898,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29927,7 +29927,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29956,7 +29956,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -29984,7 +29984,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -30008,7 +30008,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -30032,7 +30032,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -30056,7 +30056,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -30080,7 +30080,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -30104,7 +30104,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -30132,7 +30132,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
@@ -30160,7 +30160,7 @@
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
       experiments {
         key: "luci.use_realms"
-        value: 30
+        value: 100
       }
       resultdb {
         enable: true
diff --git a/infra/config/main.star b/infra/config/main.star
index fb316210..6dbd2f11 100755
--- a/infra/config/main.star
+++ b/infra/config/main.star
@@ -118,8 +118,8 @@
     ],
 )
 
-# Launch a portion of Swarming tasks in "realms-aware mode", crbug.com/1136313.
-luci.builder.defaults.experiments.set({"luci.use_realms": 30})
+# Launch Swarming tasks in "realms-aware mode", crbug.com/1136313.
+luci.builder.defaults.experiments.set({"luci.use_realms": 100})
 
 exec("//swarming.star")
 
diff --git a/ios/chrome/browser/DIR_METADATA b/ios/chrome/browser/DIR_METADATA
new file mode 100644
index 0000000..eb25a3b5
--- /dev/null
+++ b/ios/chrome/browser/DIR_METADATA
@@ -0,0 +1,11 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "UI>Browser>Mobile"
+}
\ No newline at end of file
diff --git a/ios/chrome/browser/OWNERS b/ios/chrome/browser/OWNERS
index 6baf1e3..76661f5 100644
--- a/ios/chrome/browser/OWNERS
+++ b/ios/chrome/browser/OWNERS
@@ -1,4 +1,2 @@
 per-file ios_chrome_io_thread*=mmenke@chromium.org
 per-file ios_chrome_io_thread*=rsleevi@chromium.org
-
-# COMPONENT: UI>Browser>Mobile
diff --git a/ios/chrome/browser/browser_state_metrics/DIR_METADATA b/ios/chrome/browser/browser_state_metrics/DIR_METADATA
new file mode 100644
index 0000000..80bb3818
--- /dev/null
+++ b/ios/chrome/browser/browser_state_metrics/DIR_METADATA
@@ -0,0 +1,11 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "UI>Browser>Profiles"
+}
\ No newline at end of file
diff --git a/ios/chrome/browser/browser_state_metrics/OWNERS b/ios/chrome/browser/browser_state_metrics/OWNERS
index cb78e3d..c0741e9 100644
--- a/ios/chrome/browser/browser_state_metrics/OWNERS
+++ b/ios/chrome/browser/browser_state_metrics/OWNERS
@@ -1,3 +1 @@
 file://chrome/browser/profiles/OWNERS
-
-# COMPONENT: UI>Browser>Profiles
diff --git a/ios/chrome/browser/component_updater/DIR_METADATA b/ios/chrome/browser/component_updater/DIR_METADATA
new file mode 100644
index 0000000..65f2ffa
--- /dev/null
+++ b/ios/chrome/browser/component_updater/DIR_METADATA
@@ -0,0 +1,12 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "Internals>Installer>Components"
+}
+team_email: "chrome-updates-dev@chromium.org"
\ No newline at end of file
diff --git a/ios/chrome/browser/component_updater/OWNERS b/ios/chrome/browser/component_updater/OWNERS
index 343cf42..a0a881f 100644
--- a/ios/chrome/browser/component_updater/OWNERS
+++ b/ios/chrome/browser/component_updater/OWNERS
@@ -1,4 +1 @@
 file://chrome/browser/component_updater/OWNERS
-
-# COMPONENT: Internals>Installer>Components
-# TEAM: chrome-updates-dev@chromium.org
diff --git a/ios/chrome/browser/first_run/DIR_METADATA b/ios/chrome/browser/first_run/DIR_METADATA
new file mode 100644
index 0000000..0feb00a68
--- /dev/null
+++ b/ios/chrome/browser/first_run/DIR_METADATA
@@ -0,0 +1,11 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "UI>Browser>FirstRun"
+}
\ No newline at end of file
diff --git a/ios/chrome/browser/first_run/OWNERS b/ios/chrome/browser/first_run/OWNERS
index 9d605186..56e768f 100644
--- a/ios/chrome/browser/first_run/OWNERS
+++ b/ios/chrome/browser/first_run/OWNERS
@@ -1,3 +1 @@
 file://components/signin/ios/OWNERS
-
-# COMPONENT: UI>Browser>FirstRun
diff --git a/ios/chrome/browser/gcm/DIR_METADATA b/ios/chrome/browser/gcm/DIR_METADATA
new file mode 100644
index 0000000..a6b11371
--- /dev/null
+++ b/ios/chrome/browser/gcm/DIR_METADATA
@@ -0,0 +1,11 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "Services>CloudMessaging"
+}
\ No newline at end of file
diff --git a/ios/chrome/browser/gcm/OWNERS b/ios/chrome/browser/gcm/OWNERS
index 1362b96..a20f0e3 100644
--- a/ios/chrome/browser/gcm/OWNERS
+++ b/ios/chrome/browser/gcm/OWNERS
@@ -1,3 +1 @@
 file://chrome/browser/gcm/OWNERS
-
-# COMPONENT: Services>CloudMessaging
diff --git a/ios/chrome/browser/invalidation/DIR_METADATA b/ios/chrome/browser/invalidation/DIR_METADATA
new file mode 100644
index 0000000..e8efb5d
--- /dev/null
+++ b/ios/chrome/browser/invalidation/DIR_METADATA
@@ -0,0 +1,11 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "Services>Invalidation"
+}
\ No newline at end of file
diff --git a/ios/chrome/browser/invalidation/OWNERS b/ios/chrome/browser/invalidation/OWNERS
index 4132bc86..b9e8309 100644
--- a/ios/chrome/browser/invalidation/OWNERS
+++ b/ios/chrome/browser/invalidation/OWNERS
@@ -1,3 +1 @@
 file://components/invalidation/OWNERS
-
-# COMPONENT: Services>Invalidation
diff --git a/ios/chrome/browser/omaha/DIR_METADATA b/ios/chrome/browser/omaha/DIR_METADATA
new file mode 100644
index 0000000..2700701
--- /dev/null
+++ b/ios/chrome/browser/omaha/DIR_METADATA
@@ -0,0 +1,12 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "Internals>Installer"
+}
+team_email: "chrome-updates-dev@chromium.org"
\ No newline at end of file
diff --git a/ios/chrome/browser/omaha/OWNERS b/ios/chrome/browser/omaha/OWNERS
index 5499bd0..f81596f5 100644
--- a/ios/chrome/browser/omaha/OWNERS
+++ b/ios/chrome/browser/omaha/OWNERS
@@ -2,7 +2,3 @@
 
 # For iOS / obj-C specific issues:
 rohitrao@chromium.org
-
-# COMPONENT: Internals>Installer
-# TEAM: chrome-updates-dev@chromium.org
-# OS: iOS
diff --git a/ios/chrome/browser/policy/DIR_METADATA b/ios/chrome/browser/policy/DIR_METADATA
new file mode 100644
index 0000000..17fbea7
--- /dev/null
+++ b/ios/chrome/browser/policy/DIR_METADATA
@@ -0,0 +1,11 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "Enterprise>CloudPolicy"
+}
\ No newline at end of file
diff --git a/ios/chrome/browser/policy/OWNERS b/ios/chrome/browser/policy/OWNERS
index b0fda53e..df7a0e7 100644
--- a/ios/chrome/browser/policy/OWNERS
+++ b/ios/chrome/browser/policy/OWNERS
@@ -1,5 +1,3 @@
 michaeldo@chromium.org
 rohitrao@chromium.org
 file://components/policy/OWNERS
-
-# COMPONENT: Enterprise>CloudPolicy
diff --git a/ios/chrome/browser/policy_url_blocking/DIR_METADATA b/ios/chrome/browser/policy_url_blocking/DIR_METADATA
new file mode 100644
index 0000000..62508236
--- /dev/null
+++ b/ios/chrome/browser/policy_url_blocking/DIR_METADATA
@@ -0,0 +1,11 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "Enterprise>iOS"
+}
\ No newline at end of file
diff --git a/ios/chrome/browser/policy_url_blocking/OWNERS b/ios/chrome/browser/policy_url_blocking/OWNERS
index 006f27d..5100b76 100644
--- a/ios/chrome/browser/policy_url_blocking/OWNERS
+++ b/ios/chrome/browser/policy_url_blocking/OWNERS
@@ -1,4 +1,2 @@
 michaeldo@chromium.org
 rohitrao@chromium.org
-
-# COMPONENT: Enterprise>iOS
diff --git a/ios/chrome/browser/safe_browsing/DIR_METADATA b/ios/chrome/browser/safe_browsing/DIR_METADATA
new file mode 100644
index 0000000..ca03f3cc
--- /dev/null
+++ b/ios/chrome/browser/safe_browsing/DIR_METADATA
@@ -0,0 +1,11 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "UI>Browser>Navigation"
+}
\ No newline at end of file
diff --git a/ios/chrome/browser/safe_browsing/OWNERS b/ios/chrome/browser/safe_browsing/OWNERS
index 400c135..0e69fc8 100644
--- a/ios/chrome/browser/safe_browsing/OWNERS
+++ b/ios/chrome/browser/safe_browsing/OWNERS
@@ -1,3 +1 @@
 ajuma@chromium.org
-
-# COMPONENT: UI>Browser>Navigation
diff --git a/ios/chrome/browser/signin/DIR_METADATA b/ios/chrome/browser/signin/DIR_METADATA
new file mode 100644
index 0000000..3f72231
--- /dev/null
+++ b/ios/chrome/browser/signin/DIR_METADATA
@@ -0,0 +1,11 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "Services>SignIn"
+}
\ No newline at end of file
diff --git a/ios/chrome/browser/signin/OWNERS b/ios/chrome/browser/signin/OWNERS
index 6b7400f7..56e768f 100644
--- a/ios/chrome/browser/signin/OWNERS
+++ b/ios/chrome/browser/signin/OWNERS
@@ -1,3 +1 @@
 file://components/signin/ios/OWNERS
-
-# COMPONENT: Services>SignIn
diff --git a/ios/chrome/browser/ssl/DIR_METADATA b/ios/chrome/browser/ssl/DIR_METADATA
new file mode 100644
index 0000000..b26baeb
--- /dev/null
+++ b/ios/chrome/browser/ssl/DIR_METADATA
@@ -0,0 +1,9 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+team_email: "security-enamel@chromium.org"
\ No newline at end of file
diff --git a/ios/chrome/browser/ssl/OWNERS b/ios/chrome/browser/ssl/OWNERS
index db977a0..9a5eb5e1c 100644
--- a/ios/chrome/browser/ssl/OWNERS
+++ b/ios/chrome/browser/ssl/OWNERS
@@ -1,5 +1,2 @@
 estark@chromium.org
 felt@chromium.org
-
-# TEAM: security-enamel@chromium.org
-# OS: iOS
diff --git a/ios/chrome/browser/suggestions/DIR_METADATA b/ios/chrome/browser/suggestions/DIR_METADATA
new file mode 100644
index 0000000..c86eea28
--- /dev/null
+++ b/ios/chrome/browser/suggestions/DIR_METADATA
@@ -0,0 +1,12 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "UI>Browser>NewTabPage"
+}
+team_email: "ntp-dev@chromium.org"
\ No newline at end of file
diff --git a/ios/chrome/browser/suggestions/OWNERS b/ios/chrome/browser/suggestions/OWNERS
index 2c6e9e7..8fde2a2 100644
--- a/ios/chrome/browser/suggestions/OWNERS
+++ b/ios/chrome/browser/suggestions/OWNERS
@@ -1,7 +1,3 @@
 justincohen@chromium.org
 mathp@chromium.org
 rohitrao@chromium.org
-
-# TEAM: ntp-dev@chromium.org
-# COMPONENT: UI>Browser>NewTabPage
-# OS: iOS
diff --git a/ios/chrome/browser/sync/DIR_METADATA b/ios/chrome/browser/sync/DIR_METADATA
new file mode 100644
index 0000000..48d7e48
--- /dev/null
+++ b/ios/chrome/browser/sync/DIR_METADATA
@@ -0,0 +1,11 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "Services>Sync"
+}
\ No newline at end of file
diff --git a/ios/chrome/browser/sync/OWNERS b/ios/chrome/browser/sync/OWNERS
index e18c01b4..19950d6e 100644
--- a/ios/chrome/browser/sync/OWNERS
+++ b/ios/chrome/browser/sync/OWNERS
@@ -4,5 +4,3 @@
 per-file consent_auditor_factory.*=markusheintz@chromium.org
 per-file consent_auditor_factory.*=msarda@chromium.org
 per-file consent_auditor_factory.*=msramek@chromium.org
-
-# COMPONENT: Services>Sync
diff --git a/ios/chrome/browser/ui/authentication/DIR_METADATA b/ios/chrome/browser/ui/authentication/DIR_METADATA
new file mode 100644
index 0000000..3f72231
--- /dev/null
+++ b/ios/chrome/browser/ui/authentication/DIR_METADATA
@@ -0,0 +1,11 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "Services>SignIn"
+}
\ No newline at end of file
diff --git a/ios/chrome/browser/ui/authentication/OWNERS b/ios/chrome/browser/ui/authentication/OWNERS
index 6b7400f7..56e768f 100644
--- a/ios/chrome/browser/ui/authentication/OWNERS
+++ b/ios/chrome/browser/ui/authentication/OWNERS
@@ -1,3 +1 @@
 file://components/signin/ios/OWNERS
-
-# COMPONENT: Services>SignIn
diff --git a/ios/chrome/browser/ui/location_bar/DIR_METADATA b/ios/chrome/browser/ui/location_bar/DIR_METADATA
new file mode 100644
index 0000000..e776efa
--- /dev/null
+++ b/ios/chrome/browser/ui/location_bar/DIR_METADATA
@@ -0,0 +1,11 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "UI>Browser>Omnibox"
+}
\ No newline at end of file
diff --git a/ios/chrome/browser/ui/location_bar/OWNERS b/ios/chrome/browser/ui/location_bar/OWNERS
index 62e5c6ef..96e7948a 100644
--- a/ios/chrome/browser/ui/location_bar/OWNERS
+++ b/ios/chrome/browser/ui/location_bar/OWNERS
@@ -1,3 +1 @@
 stkhapugin@chromium.org
-
-# COMPONENT: UI>Browser>Omnibox
diff --git a/ios/chrome/browser/ui/omnibox/DIR_METADATA b/ios/chrome/browser/ui/omnibox/DIR_METADATA
new file mode 100644
index 0000000..e776efa
--- /dev/null
+++ b/ios/chrome/browser/ui/omnibox/DIR_METADATA
@@ -0,0 +1,11 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "UI>Browser>Omnibox"
+}
\ No newline at end of file
diff --git a/ios/chrome/browser/ui/omnibox/OWNERS b/ios/chrome/browser/ui/omnibox/OWNERS
index 7667796..4437e1c 100644
--- a/ios/chrome/browser/ui/omnibox/OWNERS
+++ b/ios/chrome/browser/ui/omnibox/OWNERS
@@ -2,5 +2,3 @@
 rohitrao@chromium.org
 stkhapugin@chromium.org
 jdonnelly@chromium.org
-
-# COMPONENT: UI>Browser>Omnibox
diff --git a/ios/chrome/browser/ui/send_tab_to_self/DIR_METADATA b/ios/chrome/browser/ui/send_tab_to_self/DIR_METADATA
new file mode 100644
index 0000000..1d90daa
--- /dev/null
+++ b/ios/chrome/browser/ui/send_tab_to_self/DIR_METADATA
@@ -0,0 +1,11 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "UI>Browser>Sharing"
+}
\ No newline at end of file
diff --git a/ios/chrome/browser/ui/send_tab_to_self/OWNERS b/ios/chrome/browser/ui/send_tab_to_self/OWNERS
index 63e3f1f..5d4aaf4 100644
--- a/ios/chrome/browser/ui/send_tab_to_self/OWNERS
+++ b/ios/chrome/browser/ui/send_tab_to_self/OWNERS
@@ -3,5 +3,3 @@
 
 # Secondary
 sczs@chromium.org
-
-# COMPONENT: UI>Browser>Sharing
diff --git a/ios/chrome/browser/ui/settings/sync/utils/DIR_METADATA b/ios/chrome/browser/ui/settings/sync/utils/DIR_METADATA
new file mode 100644
index 0000000..48d7e48
--- /dev/null
+++ b/ios/chrome/browser/ui/settings/sync/utils/DIR_METADATA
@@ -0,0 +1,11 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "Services>Sync"
+}
\ No newline at end of file
diff --git a/ios/chrome/browser/ui/settings/sync/utils/OWNERS b/ios/chrome/browser/ui/settings/sync/utils/OWNERS
index 3431e1a..fd467bd 100644
--- a/ios/chrome/browser/ui/settings/sync/utils/OWNERS
+++ b/ios/chrome/browser/ui/settings/sync/utils/OWNERS
@@ -1,3 +1 @@
 msarda@chromium.org
-
-# COMPONENT: Services>Sync
diff --git a/ios/chrome/browser/ui/webui/gcm/DIR_METADATA b/ios/chrome/browser/ui/webui/gcm/DIR_METADATA
new file mode 100644
index 0000000..a6b11371
--- /dev/null
+++ b/ios/chrome/browser/ui/webui/gcm/DIR_METADATA
@@ -0,0 +1,11 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "Services>CloudMessaging"
+}
\ No newline at end of file
diff --git a/ios/chrome/browser/ui/webui/gcm/OWNERS b/ios/chrome/browser/ui/webui/gcm/OWNERS
index df975d1..efae577 100644
--- a/ios/chrome/browser/ui/webui/gcm/OWNERS
+++ b/ios/chrome/browser/ui/webui/gcm/OWNERS
@@ -1,5 +1,3 @@
 dimich@chromium.org
 fgorski@chromium.org
 jianli@chromium.org
-
-# COMPONENT: Services>CloudMessaging
diff --git a/ios/chrome/browser/ui/webui/net_export/DIR_METADATA b/ios/chrome/browser/ui/webui/net_export/DIR_METADATA
new file mode 100644
index 0000000..8c78ff5
--- /dev/null
+++ b/ios/chrome/browser/ui/webui/net_export/DIR_METADATA
@@ -0,0 +1,11 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "Internals>Network>Logging"
+}
\ No newline at end of file
diff --git a/ios/chrome/browser/ui/webui/net_export/OWNERS b/ios/chrome/browser/ui/webui/net_export/OWNERS
index be796293..fb59c70 100644
--- a/ios/chrome/browser/ui/webui/net_export/OWNERS
+++ b/ios/chrome/browser/ui/webui/net_export/OWNERS
@@ -1,3 +1 @@
 file://net/OWNERS
-
-# COMPONENT: Internals>Network>Logging
diff --git a/ios/chrome/browser/unified_consent/DIR_METADATA b/ios/chrome/browser/unified_consent/DIR_METADATA
new file mode 100644
index 0000000..2d69945
--- /dev/null
+++ b/ios/chrome/browser/unified_consent/DIR_METADATA
@@ -0,0 +1,12 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "Services>SignIn"
+}
+team_email: "chrome-signin@chromium.org"
\ No newline at end of file
diff --git a/ios/chrome/browser/unified_consent/OWNERS b/ios/chrome/browser/unified_consent/OWNERS
index e7d6708f..56e768f 100644
--- a/ios/chrome/browser/unified_consent/OWNERS
+++ b/ios/chrome/browser/unified_consent/OWNERS
@@ -1,4 +1 @@
 file://components/signin/ios/OWNERS
-
-# TEAM: chrome-signin@chromium.org
-# COMPONENT: Services>SignIn
diff --git a/ios/chrome/browser/update_client/DIR_METADATA b/ios/chrome/browser/update_client/DIR_METADATA
new file mode 100644
index 0000000..65f2ffa
--- /dev/null
+++ b/ios/chrome/browser/update_client/DIR_METADATA
@@ -0,0 +1,12 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+#   https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+  component: "Internals>Installer>Components"
+}
+team_email: "chrome-updates-dev@chromium.org"
\ No newline at end of file
diff --git a/ios/chrome/browser/update_client/OWNERS b/ios/chrome/browser/update_client/OWNERS
index 1bba613..f29f5ea 100644
--- a/ios/chrome/browser/update_client/OWNERS
+++ b/ios/chrome/browser/update_client/OWNERS
@@ -1,5 +1 @@
 file://components/update_client/OWNERS
-
-# COMPONENT: Internals>Installer>Components
-# TEAM: chrome-updates-dev@chromium.org
-# OS: iOS
diff --git a/media/blink/webmediaplayer_impl.cc b/media/blink/webmediaplayer_impl.cc
index 128ba69..27ff24c 100644
--- a/media/blink/webmediaplayer_impl.cc
+++ b/media/blink/webmediaplayer_impl.cc
@@ -1345,14 +1345,10 @@
   DCHECK(main_task_runner_->BelongsToCurrentThread());
   TRACE_EVENT0("media", "WebMediaPlayerImpl:paint");
 
-  // We can't copy from protected frames.
-  if (cdm_context_ref_)
-    return;
-
   scoped_refptr<VideoFrame> video_frame = GetCurrentFrameFromCompositor();
 
   gfx::Rect gfx_rect(rect);
-  if (video_frame.get() && video_frame->HasTextures()) {
+  if (video_frame && video_frame->HasTextures()) {
     if (!raster_context_provider_)
       return;  // Unable to get/create a shared main thread context.
     if (!raster_context_provider_->GrContext())
@@ -1373,6 +1369,10 @@
       raster_context_provider_.get());
 }
 
+scoped_refptr<VideoFrame> WebMediaPlayerImpl::GetCurrentFrame() {
+  return GetCurrentFrameFromCompositor();
+}
+
 bool WebMediaPlayerImpl::WouldTaintOrigin() const {
   if (demuxer_found_hls_) {
     // HLS manifests might pull segments from a different origin. We can't know
@@ -1437,14 +1437,11 @@
   DCHECK(main_task_runner_->BelongsToCurrentThread());
   TRACE_EVENT0("media", "WebMediaPlayerImpl:copyVideoTextureToPlatformTexture");
 
-  // We can't copy from protected frames.
-  if (cdm_context_ref_)
-    return false;
-
   scoped_refptr<VideoFrame> video_frame = GetCurrentFrameFromCompositor();
-  if (!video_frame.get() || !video_frame->HasTextures()) {
+  if (!video_frame || !video_frame->HasTextures()) {
     return false;
   }
+
   if (out_metadata) {
     // WebGL last-uploaded-frame-metadata API is enabled.
     // https://crbug.com/639174
@@ -2968,6 +2965,10 @@
   DCHECK(main_task_runner_->BelongsToCurrentThread());
   TRACE_EVENT0("media", "WebMediaPlayerImpl::GetCurrentFrameFromCompositor");
 
+  // We can't copy from protected frames.
+  if (cdm_context_ref_)
+    return nullptr;
+
   // Can be null.
   scoped_refptr<VideoFrame> video_frame =
       compositor_->GetCurrentFrameOnAnyThread();
diff --git a/media/blink/webmediaplayer_impl.h b/media/blink/webmediaplayer_impl.h
index e1a9acb..c8ed323 100644
--- a/media/blink/webmediaplayer_impl.h
+++ b/media/blink/webmediaplayer_impl.h
@@ -149,6 +149,7 @@
              cc::PaintFlags& flags,
              int already_uploaded_id,
              VideoFrameUploadMetadata* out_metadata) override;
+  scoped_refptr<VideoFrame> GetCurrentFrame() override;
 
   // True if the loaded media has a playable video/audio track.
   bool HasVideo() const override;
diff --git a/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.cc b/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.cc
index fd52b40..e93e5e45 100644
--- a/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.cc
+++ b/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.cc
@@ -34,10 +34,6 @@
 #include "media/filters/vpx_video_decoder.h"
 #endif
 
-#if BUILDFLAG(ENABLE_LIBAOM)
-#include "media/filters/aom_video_decoder.h"
-#endif
-
 #if BUILDFLAG(ENABLE_DAV1D_DECODER)
 #include "media/filters/dav1d_video_decoder.h"
 #endif
@@ -321,9 +317,6 @@
 #if BUILDFLAG(ENABLE_DAV1D_DECODER)
     if (config.codec == cdm::kCodecAv1)
       video_decoder.reset(new Dav1dVideoDecoder(null_media_log.get()));
-#elif BUILDFLAG(ENABLE_LIBAOM)
-    if (config.codec == cdm::kCodecAv1)
-      video_decoder.reset(new AomVideoDecoder(null_media_log.get()));
 #endif
   }
 
diff --git a/media/filters/BUILD.gn b/media/filters/BUILD.gn
index ac0bf31b..18d140b 100644
--- a/media/filters/BUILD.gn
+++ b/media/filters/BUILD.gn
@@ -140,14 +140,6 @@
     deps += [ "//third_party/libvpx" ]
   }
 
-  if (enable_libaom) {
-    sources += [
-      "aom_video_decoder.cc",
-      "aom_video_decoder.h",
-    ]
-    deps += [ "//third_party/libaom" ]
-  }
-
   if (enable_dav1d_decoder) {
     sources += [
       "dav1d_video_decoder.cc",
@@ -383,10 +375,6 @@
     sources += [ "vpx_video_decoder_unittest.cc" ]
   }
 
-  if (enable_libaom) {
-    sources += [ "aom_video_decoder_unittest.cc" ]
-  }
-
   if (enable_dav1d_decoder) {
     sources += [ "dav1d_video_decoder_unittest.cc" ]
   }
diff --git a/media/filters/aom_video_decoder.cc b/media/filters/aom_video_decoder.cc
deleted file mode 100644
index a9ae5615..0000000
--- a/media/filters/aom_video_decoder.cc
+++ /dev/null
@@ -1,314 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "media/filters/aom_video_decoder.h"
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/logging.h"
-#include "base/threading/sequenced_task_runner_handle.h"
-#include "media/base/bind_to_current_loop.h"
-#include "media/base/decoder_buffer.h"
-#include "media/base/media_log.h"
-#include "media/base/status.h"
-#include "media/base/video_util.h"
-#include "media/filters/frame_buffer_pool.h"
-#include "third_party/libyuv/include/libyuv/convert.h"
-
-// Include libaom header files.
-extern "C" {
-#include "third_party/libaom/source/libaom/aom/aom_decoder.h"
-#include "third_party/libaom/source/libaom/aom/aom_frame_buffer.h"
-#include "third_party/libaom/source/libaom/aom/aomdx.h"
-}
-
-namespace media {
-
-// Returns the number of threads.
-static int GetAomVideoDecoderThreadCount(const VideoDecoderConfig& config) {
-  // For AOM decode when using the default thread count, increase the number
-  // of decode threads to equal the maximum number of tiles possible for
-  // higher resolution streams.
-  return VideoDecoder::GetRecommendedThreadCount(config.coded_size().width() /
-                                                 256);
-}
-
-static VideoPixelFormat AomImgFmtToVideoPixelFormat(const aom_image_t* img) {
-  switch (img->fmt) {
-    case AOM_IMG_FMT_I420:
-      return PIXEL_FORMAT_I420;
-    case AOM_IMG_FMT_I422:
-      return PIXEL_FORMAT_I422;
-    case AOM_IMG_FMT_I444:
-      return PIXEL_FORMAT_I444;
-
-    case AOM_IMG_FMT_I42016:
-      switch (img->bit_depth) {
-        case 10:
-          return PIXEL_FORMAT_YUV420P10;
-        case 12:
-          return PIXEL_FORMAT_YUV420P12;
-        default:
-          DLOG(ERROR) << "Unsupported bit depth: " << img->bit_depth;
-          return PIXEL_FORMAT_UNKNOWN;
-      }
-
-    case AOM_IMG_FMT_I42216:
-      switch (img->bit_depth) {
-        case 10:
-          return PIXEL_FORMAT_YUV422P10;
-        case 12:
-          return PIXEL_FORMAT_YUV422P12;
-        default:
-          DLOG(ERROR) << "Unsupported bit depth: " << img->bit_depth;
-          return PIXEL_FORMAT_UNKNOWN;
-      }
-
-    case AOM_IMG_FMT_I44416:
-      switch (img->bit_depth) {
-        case 10:
-          return PIXEL_FORMAT_YUV444P10;
-        case 12:
-          return PIXEL_FORMAT_YUV444P12;
-        default:
-          DLOG(ERROR) << "Unsupported bit depth: " << img->bit_depth;
-          return PIXEL_FORMAT_UNKNOWN;
-      }
-
-    default:
-      DLOG(ERROR) << "Unsupported pixel format: " << img->fmt;
-      return PIXEL_FORMAT_UNKNOWN;
-  }
-}
-
-static void SetColorSpaceForFrame(const aom_image_t* img,
-                                  const VideoDecoderConfig& config,
-                                  VideoFrame* frame) {
-  gfx::ColorSpace::RangeID range = img->range == AOM_CR_FULL_RANGE
-                                       ? gfx::ColorSpace::RangeID::FULL
-                                       : gfx::ColorSpace::RangeID::LIMITED;
-
-  // AOM color space defines match ISO 23001-8:2016 via ISO/IEC 23091-4/ITU-T
-  // H.273.
-  // http://av1-spec.argondesign.com/av1-spec/av1-spec.html#color-config-semantics
-  media::VideoColorSpace color_space(img->cp, img->tc, img->mc, range);
-
-  // If the bitstream doesn't specify a color space, use the one from the
-  // container.
-  if (!color_space.IsSpecified())
-    color_space = config.color_space_info();
-
-  frame->set_color_space(color_space.ToGfxColorSpace());
-}
-
-static int GetFrameBuffer(void* cb_priv,
-                          size_t min_size,
-                          aom_codec_frame_buffer* fb) {
-  DCHECK(cb_priv);
-  DCHECK(fb);
-  FrameBufferPool* pool = static_cast<FrameBufferPool*>(cb_priv);
-  fb->data = pool->GetFrameBuffer(min_size, &fb->priv);
-  fb->size = min_size;
-  return 0;
-}
-
-static int ReleaseFrameBuffer(void* cb_priv, aom_codec_frame_buffer* fb) {
-  DCHECK(cb_priv);
-  DCHECK(fb);
-  if (!fb->priv)
-    return -1;
-
-  FrameBufferPool* pool = static_cast<FrameBufferPool*>(cb_priv);
-  pool->ReleaseFrameBuffer(fb->priv);
-  return 0;
-}
-
-AomVideoDecoder::AomVideoDecoder(MediaLog* media_log) : media_log_(media_log) {
-  DETACH_FROM_THREAD(thread_checker_);
-}
-
-AomVideoDecoder::~AomVideoDecoder() {
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  CloseDecoder();
-}
-
-std::string AomVideoDecoder::GetDisplayName() const {
-  return "AomVideoDecoder";
-}
-
-void AomVideoDecoder::Initialize(const VideoDecoderConfig& config,
-                                 bool /* low_delay */,
-                                 CdmContext* /* cdm_context */,
-                                 InitCB init_cb,
-                                 const OutputCB& output_cb,
-                                 const WaitingCB& /* waiting_cb */) {
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  DCHECK(config.IsValidConfig());
-
-  InitCB bound_init_cb = BindToCurrentLoop(std::move(init_cb));
-  if (config.is_encrypted() || config.codec() != kCodecAV1) {
-    std::move(bound_init_cb).Run(StatusCode::kDecoderFailedInitialization);
-    return;
-  }
-
-  // Clear any previously initialized decoder.
-  CloseDecoder();
-
-  aom_codec_dec_cfg_t aom_config = {0};
-  aom_config.w = config.coded_size().width();
-  aom_config.h = config.coded_size().height();
-  aom_config.threads = GetAomVideoDecoderThreadCount(config);
-
-  // Misleading name. Required to ensure libaom doesn't output 8-bit samples
-  // in uint16_t containers. Without this we have to manually pack the values
-  // into uint8_t samples.
-  aom_config.allow_lowbitdepth = 1;
-
-  // TODO(dalecurtis, tguilbert): Move decoding off the media thread to the
-  // offload thread via OffloadingVideoDecoder. https://crbug.com/867613
-
-  std::unique_ptr<aom_codec_ctx> context = std::make_unique<aom_codec_ctx>();
-  if (aom_codec_dec_init(context.get(), aom_codec_av1_dx(), &aom_config,
-                         0 /* flags */) != AOM_CODEC_OK) {
-    MEDIA_LOG(ERROR, media_log_) << "aom_codec_dec_init() failed: "
-                                 << aom_codec_error(aom_decoder_.get());
-    std::move(bound_init_cb).Run(StatusCode::kDecoderFailedInitialization);
-    return;
-  }
-
-  // Setup codec for zero copy frames.
-  if (!memory_pool_)
-    memory_pool_ = new FrameBufferPool();
-  if (aom_codec_set_frame_buffer_functions(
-          context.get(), &GetFrameBuffer, &ReleaseFrameBuffer,
-          memory_pool_.get()) != AOM_CODEC_OK) {
-    DLOG(ERROR) << "Failed to configure external buffers. "
-                << aom_codec_error(context.get());
-    std::move(bound_init_cb).Run(StatusCode::kDecoderFailedInitialization);
-    return;
-  }
-
-  config_ = config;
-  state_ = DecoderState::kNormal;
-  output_cb_ = BindToCurrentLoop(output_cb);
-  aom_decoder_ = std::move(context);
-  std::move(bound_init_cb).Run(OkStatus());
-}
-
-void AomVideoDecoder::Decode(scoped_refptr<DecoderBuffer> buffer,
-                             DecodeCB decode_cb) {
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  DCHECK(buffer);
-  DCHECK(decode_cb);
-  DCHECK_NE(state_, DecoderState::kUninitialized)
-      << "Called Decode() before successful Initialize()";
-
-  DecodeCB bound_decode_cb = BindToCurrentLoop(std::move(decode_cb));
-
-  if (state_ == DecoderState::kError) {
-    std::move(bound_decode_cb).Run(DecodeStatus::DECODE_ERROR);
-    return;
-  }
-
-  // No need to flush since we retrieve all available frames after a packet is
-  // provided.
-  if (buffer->end_of_stream()) {
-    DCHECK_EQ(state_, DecoderState::kNormal);
-    state_ = DecoderState::kDecodeFinished;
-    std::move(bound_decode_cb).Run(DecodeStatus::OK);
-    return;
-  }
-
-  if (!DecodeBuffer(buffer.get())) {
-    state_ = DecoderState::kError;
-    std::move(bound_decode_cb).Run(DecodeStatus::DECODE_ERROR);
-    return;
-  }
-
-  // VideoDecoderShim expects |decode_cb| call after |output_cb_|.
-  std::move(bound_decode_cb).Run(DecodeStatus::OK);
-}
-
-void AomVideoDecoder::Reset(base::OnceClosure closure) {
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  state_ = DecoderState::kNormal;
-  timestamps_.clear();
-  base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE,
-                                                   std::move(closure));
-}
-
-void AomVideoDecoder::CloseDecoder() {
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  if (!aom_decoder_)
-    return;
-  aom_codec_destroy(aom_decoder_.get());
-  aom_decoder_.reset();
-
-  if (memory_pool_) {
-    memory_pool_->Shutdown();
-    memory_pool_ = nullptr;
-  }
-}
-
-bool AomVideoDecoder::DecodeBuffer(const DecoderBuffer* buffer) {
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-  DCHECK(!buffer->end_of_stream());
-
-  timestamps_.push_back(buffer->timestamp());
-  if (aom_codec_decode(aom_decoder_.get(), buffer->data(), buffer->data_size(),
-                       nullptr) != AOM_CODEC_OK) {
-    const char* detail = aom_codec_error_detail(aom_decoder_.get());
-    MEDIA_LOG(ERROR, media_log_)
-        << "aom_codec_decode() failed: " << aom_codec_error(aom_decoder_.get())
-        << (detail ? ", " : "") << (detail ? detail : "")
-        << ", input: " << buffer->AsHumanReadableString();
-    return false;
-  }
-
-  aom_codec_iter_t iter = nullptr;
-  while (aom_image_t* img = aom_codec_get_frame(aom_decoder_.get(), &iter)) {
-    auto frame = CopyImageToVideoFrame(img);
-    if (!frame) {
-      MEDIA_LOG(DEBUG, media_log_)
-          << "Failed to produce video frame from aom_image_t.";
-      return false;
-    }
-
-    // TODO(dalecurtis): Is this true even for low resolutions?
-    frame->metadata()->power_efficient = false;
-
-    // Ensure the frame memory is returned to the MemoryPool upon discard.
-    frame->AddDestructionObserver(
-        memory_pool_->CreateFrameCallback(img->fb_priv));
-
-    SetColorSpaceForFrame(img, config_, frame.get());
-    output_cb_.Run(std::move(frame));
-  }
-
-  return true;
-}
-
-scoped_refptr<VideoFrame> AomVideoDecoder::CopyImageToVideoFrame(
-    const struct aom_image* img) {
-  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
-
-  VideoPixelFormat pixel_format = AomImgFmtToVideoPixelFormat(img);
-  if (pixel_format == PIXEL_FORMAT_UNKNOWN)
-    return nullptr;
-
-  // Pull the expected timestamp from the front of the queue.
-  DCHECK(!timestamps_.empty());
-  const base::TimeDelta timestamp = timestamps_.front();
-  timestamps_.pop_front();
-
-  const gfx::Rect visible_rect(img->d_w, img->d_h);
-  return VideoFrame::WrapExternalYuvData(
-      pixel_format, visible_rect.size(), visible_rect,
-      GetNaturalSize(visible_rect, config_.GetPixelAspectRatio()),
-      img->stride[AOM_PLANE_Y], img->stride[AOM_PLANE_U],
-      img->stride[AOM_PLANE_V], img->planes[AOM_PLANE_Y],
-      img->planes[AOM_PLANE_U], img->planes[AOM_PLANE_V], timestamp);
-}
-
-}  // namespace media
diff --git a/media/filters/aom_video_decoder.h b/media/filters/aom_video_decoder.h
deleted file mode 100644
index 42589ce..0000000
--- a/media/filters/aom_video_decoder.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef MEDIA_FILTERS_AOM_VIDEO_DECODER_H_
-#define MEDIA_FILTERS_AOM_VIDEO_DECODER_H_
-
-#include "base/callback_forward.h"
-#include "base/containers/circular_deque.h"
-#include "base/macros.h"
-#include "base/threading/thread_checker.h"
-#include "media/base/video_decoder.h"
-#include "media/base/video_decoder_config.h"
-#include "media/base/video_frame.h"
-
-struct aom_codec_ctx;
-struct aom_image;
-
-namespace media {
-class FrameBufferPool;
-class MediaLog;
-
-// libaom video decoder wrapper.
-class MEDIA_EXPORT AomVideoDecoder : public VideoDecoder {
- public:
-  explicit AomVideoDecoder(MediaLog* media_log);
-  ~AomVideoDecoder() override;
-
-  // VideoDecoder implementation.
-  std::string GetDisplayName() const override;
-  void Initialize(const VideoDecoderConfig& config,
-                  bool low_delay,
-                  CdmContext* cdm_context,
-                  InitCB init_cb,
-                  const OutputCB& output_cb,
-                  const WaitingCB& waiting_cb) override;
-  void Decode(scoped_refptr<DecoderBuffer> buffer, DecodeCB decode_cb) override;
-  void Reset(base::OnceClosure closure) override;
-
- private:
-  enum class DecoderState {
-    kUninitialized,
-    kNormal,
-    kFlushCodec,
-    kDecodeFinished,
-    kError
-  };
-
-  // Releases any configured decoder and clears |aom_decoder_|.
-  void CloseDecoder();
-
-  // Invokes the decoder and calls |output_cb_| for any returned frames.
-  bool DecodeBuffer(const DecoderBuffer* buffer);
-
-  // Copies the contents of |img| into a new VideoFrame; attempts to reuse
-  // previously allocated memory via |frame_pool_| for performance.
-  scoped_refptr<VideoFrame> CopyImageToVideoFrame(const struct aom_image* img);
-
-  THREAD_CHECKER(thread_checker_);
-
-  // Used to report error messages to the client.
-  MediaLog* const media_log_;
-
-  // Current decoder state. Used to ensure methods are called as expected.
-  DecoderState state_ = DecoderState::kUninitialized;
-
-  // Callback given during Initialize() used for delivering decoded frames.
-  OutputCB output_cb_;
-
-  // The configuration passed to Initialize(), saved since some fields are
-  // needed to annotate video frames after decoding.
-  VideoDecoderConfig config_;
-
-  // Pool used for memory efficiency when vending frames from the decoder.
-  scoped_refptr<FrameBufferPool> memory_pool_;
-
-  // Timestamps are FIFO for libaom decoding.
-  base::circular_deque<base::TimeDelta> timestamps_;
-
-  // The allocated decoder; null before Initialize() and anytime after
-  // CloseDecoder().
-  std::unique_ptr<aom_codec_ctx> aom_decoder_;
-
-  DISALLOW_COPY_AND_ASSIGN(AomVideoDecoder);
-};
-
-}  // namespace media
-
-#endif  // MEDIA_FILTERS_AOM_VIDEO_DECODER_H_
diff --git a/media/filters/aom_video_decoder_unittest.cc b/media/filters/aom_video_decoder_unittest.cc
deleted file mode 100644
index 3de1a54..0000000
--- a/media/filters/aom_video_decoder_unittest.cc
+++ /dev/null
@@ -1,288 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/run_loop.h"
-#include "base/test/task_environment.h"
-#include "build/build_config.h"
-#include "media/base/decoder_buffer.h"
-#include "media/base/limits.h"
-#include "media/base/mock_media_log.h"
-#include "media/base/test_data_util.h"
-#include "media/base/test_helpers.h"
-#include "media/base/video_frame.h"
-#include "media/ffmpeg/ffmpeg_common.h"
-#include "media/filters/aom_video_decoder.h"
-#include "media/filters/in_memory_url_protocol.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-using ::testing::_;
-
-namespace media {
-
-namespace {
-
-MATCHER(ContainsDecoderErrorLog, "") {
-  return CONTAINS_STRING(arg, "aom_codec_decode() failed");
-}
-
-}  // namespace
-
-class AomVideoDecoderTest : public testing::Test {
- public:
-  AomVideoDecoderTest()
-      : decoder_(new AomVideoDecoder(&media_log_)),
-        i_frame_buffer_(ReadTestDataFile("av1-I-frame-320x240")) {}
-
-  ~AomVideoDecoderTest() override { Destroy(); }
-
-  void Initialize() {
-    InitializeWithConfig(TestVideoConfig::Normal(kCodecAV1));
-  }
-
-  void InitializeWithConfigWithResult(const VideoDecoderConfig& config,
-                                      bool success) {
-    decoder_->Initialize(config, false, nullptr,
-                         base::BindOnce(
-                             [](bool success, Status status) {
-                               EXPECT_EQ(status.is_ok(), success);
-                             },
-                             success),
-                         base::BindRepeating(&AomVideoDecoderTest::FrameReady,
-                                             base::Unretained(this)),
-                         base::NullCallback());
-    base::RunLoop().RunUntilIdle();
-  }
-
-  void InitializeWithConfig(const VideoDecoderConfig& config) {
-    InitializeWithConfigWithResult(config, true);
-  }
-
-  void Reinitialize() {
-    InitializeWithConfig(TestVideoConfig::Large(kCodecAV1));
-  }
-
-  void Reset() {
-    decoder_->Reset(NewExpectedClosure());
-    base::RunLoop().RunUntilIdle();
-  }
-
-  void Destroy() {
-    decoder_.reset();
-    base::RunLoop().RunUntilIdle();
-  }
-
-  // Sets up expectations and actions to put AomVideoDecoder in an active
-  // decoding state.
-  void ExpectDecodingState() {
-    EXPECT_EQ(DecodeStatus::OK, DecodeSingleFrame(i_frame_buffer_));
-    ASSERT_EQ(1U, output_frames_.size());
-  }
-
-  // Sets up expectations and actions to put AomVideoDecoder in an end
-  // of stream state.
-  void ExpectEndOfStreamState() {
-    EXPECT_EQ(DecodeStatus::OK,
-              DecodeSingleFrame(DecoderBuffer::CreateEOSBuffer()));
-    ASSERT_FALSE(output_frames_.empty());
-  }
-
-  using InputBuffers = std::vector<scoped_refptr<DecoderBuffer>>;
-  using OutputFrames = std::vector<scoped_refptr<VideoFrame>>;
-
-  // Decodes all buffers in |input_buffers| and push all successfully decoded
-  // output frames into |output_frames|. Returns the last decode status returned
-  // by the decoder.
-  DecodeStatus DecodeMultipleFrames(const InputBuffers& input_buffers) {
-    for (auto iter = input_buffers.begin(); iter != input_buffers.end();
-         ++iter) {
-      DecodeStatus status = Decode(*iter);
-      switch (status) {
-        case DecodeStatus::OK:
-          break;
-        case DecodeStatus::ABORTED:
-          NOTREACHED();
-          FALLTHROUGH;
-        case DecodeStatus::DECODE_ERROR:
-          DCHECK(output_frames_.empty());
-          return status;
-      }
-    }
-    return DecodeStatus::OK;
-  }
-
-  // Decodes the single compressed frame in |buffer|.
-  DecodeStatus DecodeSingleFrame(scoped_refptr<DecoderBuffer> buffer) {
-    InputBuffers input_buffers;
-    input_buffers.push_back(std::move(buffer));
-    return DecodeMultipleFrames(input_buffers);
-  }
-
-  // Decodes |i_frame_buffer_| and then decodes the data contained in the file
-  // named |test_file_name|. This function expects both buffers to decode to
-  // frames that are the same size.
-  void DecodeIFrameThenTestFile(const std::string& test_file_name,
-                                const gfx::Size& expected_size) {
-    Initialize();
-    scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(test_file_name);
-
-    InputBuffers input_buffers;
-    input_buffers.push_back(i_frame_buffer_);
-    input_buffers.push_back(buffer);
-    input_buffers.push_back(DecoderBuffer::CreateEOSBuffer());
-
-    DecodeStatus status = DecodeMultipleFrames(input_buffers);
-
-    EXPECT_EQ(DecodeStatus::OK, status);
-    ASSERT_EQ(2U, output_frames_.size());
-
-    gfx::Size original_size = TestVideoConfig::NormalCodedSize();
-    EXPECT_EQ(original_size.width(),
-              output_frames_[0]->visible_rect().size().width());
-    EXPECT_EQ(original_size.height(),
-              output_frames_[0]->visible_rect().size().height());
-    EXPECT_EQ(expected_size.width(),
-              output_frames_[1]->visible_rect().size().width());
-    EXPECT_EQ(expected_size.height(),
-              output_frames_[1]->visible_rect().size().height());
-  }
-
-  DecodeStatus Decode(scoped_refptr<DecoderBuffer> buffer) {
-    DecodeStatus status;
-    EXPECT_CALL(*this, DecodeDone(_)).WillOnce(testing::SaveArg<0>(&status));
-
-    decoder_->Decode(std::move(buffer),
-                     base::BindOnce(&AomVideoDecoderTest::DecodeDone,
-                                    base::Unretained(this)));
-    base::RunLoop().RunUntilIdle();
-
-    return status;
-  }
-
-  void FrameReady(scoped_refptr<VideoFrame> frame) {
-    DCHECK(!frame->metadata()->IsTrue(VideoFrameMetadata::END_OF_STREAM));
-    output_frames_.push_back(std::move(frame));
-  }
-
-  MOCK_METHOD1(DecodeDone, void(DecodeStatus));
-
-  testing::StrictMock<MockMediaLog> media_log_;
-
-  base::test::SingleThreadTaskEnvironment task_environment_;
-  std::unique_ptr<AomVideoDecoder> decoder_;
-
-  scoped_refptr<DecoderBuffer> i_frame_buffer_;
-  OutputFrames output_frames_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(AomVideoDecoderTest);
-};
-
-TEST_F(AomVideoDecoderTest, Initialize_Normal) {
-  Initialize();
-}
-
-TEST_F(AomVideoDecoderTest, Reinitialize_Normal) {
-  Initialize();
-  Reinitialize();
-}
-
-TEST_F(AomVideoDecoderTest, Reinitialize_AfterDecodeFrame) {
-  Initialize();
-  ExpectDecodingState();
-  Reinitialize();
-}
-
-TEST_F(AomVideoDecoderTest, Reinitialize_AfterReset) {
-  Initialize();
-  ExpectDecodingState();
-  Reset();
-  Reinitialize();
-}
-
-TEST_F(AomVideoDecoderTest, DecodeFrame_Normal) {
-  Initialize();
-
-  // Simulate decoding a single frame.
-  EXPECT_EQ(DecodeStatus::OK, DecodeSingleFrame(i_frame_buffer_));
-  ASSERT_EQ(1U, output_frames_.size());
-}
-
-// Decode |i_frame_buffer_| and then a frame with a larger width and verify
-// the output size was adjusted.
-// TODO(dalecurtis): Get an I-frame from a larger video.
-TEST_F(AomVideoDecoderTest, DISABLED_DecodeFrame_LargerWidth) {
-  DecodeIFrameThenTestFile("av1-I-frame-320x240", gfx::Size(1280, 720));
-}
-
-// Decode a VP9 frame which should trigger a decoder error.
-TEST_F(AomVideoDecoderTest, DecodeFrame_Error) {
-  Initialize();
-  EXPECT_MEDIA_LOG(ContainsDecoderErrorLog());
-  DecodeSingleFrame(ReadTestDataFile("vp9-I-frame-320x240"));
-}
-
-// Test resetting when decoder has initialized but not decoded.
-TEST_F(AomVideoDecoderTest, Reset_Initialized) {
-  Initialize();
-  Reset();
-}
-
-// Test resetting when decoder has decoded single frame.
-TEST_F(AomVideoDecoderTest, Reset_Decoding) {
-  Initialize();
-  ExpectDecodingState();
-  Reset();
-}
-
-// Test resetting when decoder has hit end of stream.
-TEST_F(AomVideoDecoderTest, Reset_EndOfStream) {
-  Initialize();
-  ExpectDecodingState();
-  ExpectEndOfStreamState();
-  Reset();
-}
-
-// Test destruction when decoder has initialized but not decoded.
-TEST_F(AomVideoDecoderTest, Destroy_Initialized) {
-  Initialize();
-  Destroy();
-}
-
-// Test destruction when decoder has decoded single frame.
-TEST_F(AomVideoDecoderTest, Destroy_Decoding) {
-  Initialize();
-  ExpectDecodingState();
-  Destroy();
-}
-
-// Test destruction when decoder has hit end of stream.
-TEST_F(AomVideoDecoderTest, Destroy_EndOfStream) {
-  Initialize();
-  ExpectDecodingState();
-  ExpectEndOfStreamState();
-  Destroy();
-}
-
-TEST_F(AomVideoDecoderTest, FrameValidAfterPoolDestruction) {
-  Initialize();
-  Decode(i_frame_buffer_);
-  Destroy();
-
-  ASSERT_FALSE(output_frames_.empty());
-
-  // Write to the Y plane. The memory tools should detect a
-  // use-after-free if the storage was actually removed by pool destruction.
-  memset(output_frames_.front()->data(VideoFrame::kYPlane), 0xff,
-         output_frames_.front()->rows(VideoFrame::kYPlane) *
-             output_frames_.front()->stride(VideoFrame::kYPlane));
-}
-
-}  // namespace media
diff --git a/media/gpu/args.gni b/media/gpu/args.gni
index 8432ec2..9672fba 100644
--- a/media/gpu/args.gni
+++ b/media/gpu/args.gni
@@ -16,7 +16,9 @@
 
   # Indicates if VA-API-based hardware acceleration is to be used. This
   # is typically the case on x86-based ChromeOS devices.
-  use_vaapi = false
+  # VA-API should also be compiled by default on x11-using linux devices
+  # using x86/x64.
+  use_vaapi = is_linux && (current_cpu == "x86" || current_cpu == "x64")
 
   # Indicates if ChromeOS protected media support exists. This is used
   # to enable the CDM daemon in Chrome OS as well as support for
diff --git a/media/gpu/test/video.cc b/media/gpu/test/video.cc
index 3f85ebe2..1f065ae9 100644
--- a/media/gpu/test/video.cc
+++ b/media/gpu/test/video.cc
@@ -542,6 +542,8 @@
     return VP9PROFILE_PROFILE0;
   } else if (profile == "VP9PROFILE_PROFILE2") {
     return VP9PROFILE_PROFILE2;
+  } else if (profile == "AV1PROFILE_PROFILE_MAIN") {
+    return AV1PROFILE_PROFILE_MAIN;
   } else {
     VLOG(2) << profile << " is not supported";
     return base::nullopt;
@@ -557,6 +559,8 @@
     return kCodecVP8;
   } else if (profile >= VP9PROFILE_MIN && profile <= VP9PROFILE_MAX) {
     return kCodecVP9;
+  } else if (profile >= AV1PROFILE_MIN && profile <= AV1PROFILE_MAX) {
+    return kCodecAV1;
   } else {
     VLOG(2) << GetProfileName(profile) << " is not supported";
     return base::nullopt;
diff --git a/media/gpu/test/video_test_helpers.cc b/media/gpu/test/video_test_helpers.cc
index 62eca88..8801a779d 100644
--- a/media/gpu/test/video_test_helpers.cc
+++ b/media/gpu/test/video_test_helpers.cc
@@ -135,6 +135,7 @@
       return GetNextFragment();
     case kCodecVP8:
     case kCodecVP9:
+    case kCodecAV1:
       return GetNextFrame();
     default:
       NOTREACHED();
@@ -343,6 +344,9 @@
     }
     // Stream configuration is present in a keyframe in vp9.
     return frame_header.IsKeyframe();
+  } else if (profile >= AV1PROFILE_MIN && profile <= AV1PROFILE_MAX) {
+    // TODO(hiroh): Implement this.
+    return false;
   }
   // Shouldn't happen at this point.
   LOG(FATAL) << "Invalid profile: " << GetProfileName(profile);
diff --git a/media/gpu/windows/dxva_video_decode_accelerator_win.cc b/media/gpu/windows/dxva_video_decode_accelerator_win.cc
index e72b5c4..d9ed085 100644
--- a/media/gpu/windows/dxva_video_decode_accelerator_win.cc
+++ b/media/gpu/windows/dxva_video_decode_accelerator_win.cc
@@ -617,6 +617,7 @@
       processing_config_changed_(false),
       use_empty_video_hdr_metadata_(workarounds.use_empty_video_hdr_metadata) {
   weak_ptr_ = weak_this_factory_.GetWeakPtr();
+  pb_weak_ptr_ = pb_weak_this_factory_.GetWeakPtr();
   memset(&input_stream_info_, 0, sizeof(input_stream_info_));
   memset(&output_stream_info_, 0, sizeof(output_stream_info_));
   use_color_info_ = base::FeatureList::IsEnabled(kVideoBlitColorAccuracy);
@@ -1138,7 +1139,7 @@
           FROM_HERE,
           base::BindOnce(
               &DXVAVideoDecodeAccelerator::DeferredDismissStaleBuffer,
-              weak_ptr_, picture_buffer_id));
+              pb_weak_ptr_, picture_buffer_id));
     }
     return;
   }
@@ -1198,7 +1199,7 @@
     main_thread_task_runner_->PostDelayedTask(
         FROM_HERE,
         base::BindOnce(&DXVAVideoDecodeAccelerator::WaitForOutputBuffer,
-                       weak_ptr_, picture_buffer_id, count + 1),
+                       pb_weak_ptr_, picture_buffer_id, count + 1),
         base::TimeDelta::FromMilliseconds(kFlushDecoderSurfaceTimeoutMs));
     return;
   }
@@ -1847,7 +1848,7 @@
   main_thread_task_runner_->PostTask(
       FROM_HERE,
       base::BindOnce(&DXVAVideoDecodeAccelerator::RequestPictureBuffers,
-                     weak_ptr_, width, height));
+                     pb_weak_ptr_, width, height));
 
   pictures_requested_ = true;
   return true;
@@ -2010,6 +2011,9 @@
   // resolution changes. We already handle that in the
   // HandleResolutionChanged() function.
   if (GetState() != kConfigChange) {
+    pb_weak_this_factory_.InvalidateWeakPtrs();
+    pb_weak_ptr_ = pb_weak_this_factory_.GetWeakPtr();
+
     output_picture_buffers_.clear();
     stale_output_picture_buffers_.clear();
     // We want to continue processing pending input after detecting a config
@@ -2335,12 +2339,12 @@
   main_thread_task_runner_->PostTask(
       FROM_HERE,
       base::BindOnce(&DXVAVideoDecodeAccelerator::DismissStaleBuffers,
-                     weak_ptr_, false));
+                     pb_weak_ptr_, false));
 
   main_thread_task_runner_->PostTask(
       FROM_HERE,
       base::BindOnce(&DXVAVideoDecodeAccelerator::RequestPictureBuffers,
-                     weak_ptr_, width, height));
+                     pb_weak_ptr_, width, height));
 }
 
 void DXVAVideoDecodeAccelerator::DismissStaleBuffers(bool force) {
diff --git a/media/gpu/windows/dxva_video_decode_accelerator_win.h b/media/gpu/windows/dxva_video_decode_accelerator_win.h
index 430b01b..de916b6 100644
--- a/media/gpu/windows/dxva_video_decode_accelerator_win.h
+++ b/media/gpu/windows/dxva_video_decode_accelerator_win.h
@@ -532,6 +532,7 @@
   // thread safety of reaching into this class from multiple threads to
   // attain a WeakPtr.
   base::WeakPtr<DXVAVideoDecodeAccelerator> weak_ptr_;
+  base::WeakPtr<DXVAVideoDecodeAccelerator> pb_weak_ptr_;
 
   // Set to true if we are in the context of a Flush operation. Used to prevent
   // multiple flush done notifications being sent out.
@@ -613,6 +614,9 @@
   // WeakPtrFactory for posting tasks back to |this|.
   base::WeakPtrFactory<DXVAVideoDecodeAccelerator> weak_this_factory_{this};
 
+  // WeakPtrFactory for posting picture buffer related tasks back to |this|.
+  base::WeakPtrFactory<DXVAVideoDecodeAccelerator> pb_weak_this_factory_{this};
+
   // Function pointer for the MFCreateDXGIDeviceManager API.
   static CreateDXGIDeviceManager create_dxgi_device_manager_;
 
diff --git a/media/media_options.gni b/media/media_options.gni
index 81bcf0a4..57894aa 100644
--- a/media/media_options.gni
+++ b/media/media_options.gni
@@ -102,7 +102,7 @@
 
 declare_args() {
   enable_av1_decoder =
-      enable_dav1d_decoder || enable_libaom || enable_libgav1_decoder
+      enable_dav1d_decoder || enable_libgav1_decoder
 }
 
 # enable_hls_sample_aes can only be true if enable_mse_mpeg2ts_stream_parser is.
diff --git a/media/renderers/default_decoder_factory.cc b/media/renderers/default_decoder_factory.cc
index f821dc2..0d4b732e2 100644
--- a/media/renderers/default_decoder_factory.cc
+++ b/media/renderers/default_decoder_factory.cc
@@ -30,10 +30,6 @@
 #include "media/filters/fuchsia/fuchsia_video_decoder.h"
 #endif
 
-#if BUILDFLAG(ENABLE_LIBAOM)
-#include "media/filters/aom_video_decoder.h"
-#endif
-
 #if BUILDFLAG(ENABLE_DAV1D_DECODER)
 #include "media/filters/dav1d_video_decoder.h"
 #endif
@@ -161,8 +157,6 @@
 #if BUILDFLAG(ENABLE_DAV1D_DECODER)
     video_decoders->push_back(
         std::make_unique<OffloadingDav1dVideoDecoder>(media_log));
-#elif BUILDFLAG(ENABLE_LIBAOM)
-    video_decoders->push_back(std::make_unique<AomVideoDecoder>(media_log));
 #endif
   }
 
diff --git a/media/test/pipeline_integration_test_base.cc b/media/test/pipeline_integration_test_base.cc
index 736e9db..41713be94 100644
--- a/media/test/pipeline_integration_test_base.cc
+++ b/media/test/pipeline_integration_test_base.cc
@@ -28,10 +28,6 @@
 #include "media/test/test_media_source.h"
 #include "third_party/libaom/libaom_buildflags.h"
 
-#if BUILDFLAG(ENABLE_LIBAOM)
-#include "media/filters/aom_video_decoder.h"
-#endif
-
 #if BUILDFLAG(ENABLE_DAV1D_DECODER)
 #include "media/filters/dav1d_video_decoder.h"
 #endif
@@ -89,8 +85,6 @@
 #if BUILDFLAG(ENABLE_DAV1D_DECODER)
     video_decoders.push_back(
         std::make_unique<OffloadingDav1dVideoDecoder>(media_log));
-#elif BUILDFLAG(ENABLE_LIBAOM)
-    video_decoders.push_back(std::make_unique<AomVideoDecoder>(media_log));
 #endif
   }
 
diff --git a/mojo/public/js/BUILD.gn b/mojo/public/js/BUILD.gn
index 261dfaf..dc2a1d3 100644
--- a/mojo/public/js/BUILD.gn
+++ b/mojo/public/js/BUILD.gn
@@ -103,7 +103,7 @@
     "interface_support.js",
     "bindings_uncompiled_module_export.js.part",
   ]
-  output = "bindings_uncompiled.m.js"
+  output = "bindings_uncompiled.js"
   deps = [ "//mojo/public/interfaces/bindings:bindings_js_library" ]
 }
 
@@ -128,13 +128,13 @@
       "$target_gen_dir/mojo_bindings_lite.js",
       "bindings_module_export.js.part",
     ]
-    output = "bindings_compiled.m.js"
+    output = "bindings_compiled.js"
     deps = [ ":bindings_lite" ]
   }
 
   copy("bindings_module") {
-    sources = [ "$target_gen_dir/bindings_compiled.m.js" ]
-    outputs = [ "$target_gen_dir/bindings.m.js" ]
+    sources = [ "$target_gen_dir/bindings_compiled.js" ]
+    outputs = [ "$target_gen_dir/bindings.js" ]
     deps = [ ":bindings_compiled_module" ]
   }
 } else {
@@ -158,19 +158,19 @@
   }
 
   copy("bindings_module") {
-    sources = [ "$target_gen_dir/bindings_uncompiled.m.js" ]
-    outputs = [ "$target_gen_dir/bindings.m.js" ]
+    sources = [ "$target_gen_dir/bindings_uncompiled.js" ]
+    outputs = [ "$target_gen_dir/bindings.js" ]
     deps = [ ":bindings_uncompiled_module" ]
   }
 }
 
 # This is the library target used in the dependency tree of any JS libraries
 # or binaries compiling against mojom JS bindings. This library is functionally
-# equivalent to the bindings.m.js generated by the ":bindings_module" target and
+# equivalent to the bindings.js generated by the ":bindings_module" target and
 # used at runtime by all consumers, except that this module includes all type
 # annotations and is suitable for Closure compilation and type checking.
-js_library("bindings_uncompiled.m") {
-  sources = [ "$target_gen_dir/bindings_uncompiled.m.js" ]
+js_library("bindings_uncompiled") {
+  sources = [ "$target_gen_dir/bindings_uncompiled.js" ]
   extra_deps = [ ":bindings_uncompiled_module" ]
 }
 
@@ -192,6 +192,7 @@
   deps = [
     ":bindings",
     ":bindings_lite",
+    ":bindings_module",
     "//mojo/public/mojom/base:base_js",
   ]
 }
diff --git a/mojo/public/js/mojo_bindings_resources.grd b/mojo/public/js/mojo_bindings_resources.grd
index e86d260..6eb31b1 100644
--- a/mojo/public/js/mojo_bindings_resources.grd
+++ b/mojo/public/js/mojo_bindings_resources.grd
@@ -7,7 +7,7 @@
     <output filename="grit/mojo_bindings_resources_map.h"
         type="resource_map_header" />
     <output filename="grit/mojo_bindings_resources_map.cc"
-        type="resource_map_source" />
+        type="resource_file_map_source" />
     <output filename="mojo_bindings_resources.pak" type="data_package" />
   </outputs>
   <translations />
@@ -18,55 +18,73 @@
         <include name="IDR_MOJO_MOJO_BINDINGS_JS"
             file="${root_gen_dir}/mojo/public/js/mojo_bindings.js"
             use_base_dir="false"
+            resource_path="mojo/mojo/public/js/mojo_bindings.js"
             type="BINDATA" />
       </if>
+      <include name="IDR_MOJO_BINDINGS_JS"
+          file="${root_gen_dir}/mojo/public/js/bindings.js"
+          use_base_dir="false"
+          resource_path="mojo/mojo/public/js/bindings.js"
+          type="BINDATA" />
       <include name="IDR_MOJO_MOJO_BINDINGS_LITE_HTML"
           file="mojo_bindings_lite.html"
+          resource_path="mojo/mojo/public/js/mojo_bindings_lite.html"
           type="BINDATA" />
       <include name="IDR_MOJO_MOJO_BINDINGS_LITE_JS"
           file="${root_gen_dir}/mojo/public/js/mojo_bindings_lite.js"
           use_base_dir="false"
+          resource_path="mojo/mojo/public/js/mojo_bindings_lite.js"
           type="BINDATA" />
       <include name="IDR_MOJO_BIG_BUFFER_MOJOM_HTML"
           file="${root_gen_dir}/mojo/public/mojom/base/big_buffer.mojom.html"
           use_base_dir="false"
+          resource_path="mojo/mojo/public/mojom/base/big_buffer.mojom.html"
           type="BINDATA" />
       <include name="IDR_MOJO_BIG_BUFFER_MOJOM_LITE_JS"
           file="${root_gen_dir}/mojo/public/mojom/base/big_buffer.mojom-lite.js"
           use_base_dir="false"
+          resource_path="mojo/mojo/public/mojom/base/big_buffer.mojom-lite.js"
           type="BINDATA" />
       <include name="IDR_MOJO_FILE_MOJOM_HTML"
           file="${root_gen_dir}/mojo/public/mojom/base/file.mojom.html"
           use_base_dir="false"
+          resource_path="mojo/mojo/public/mojom/base/file.mojom.html"
           type="BINDATA" />
       <include name="IDR_MOJO_FILE_MOJOM_LITE_JS"
           file="${root_gen_dir}/mojo/public/mojom/base/file.mojom-lite.js"
           use_base_dir="false"
+          resource_path="mojo/mojo/public/mojom/base/file.mojom-lite.js"
           type="BINDATA" />
       <include name="IDR_MOJO_STRING16_MOJOM_HTML"
           file="${root_gen_dir}/mojo/public/mojom/base/string16.mojom.html"
           use_base_dir="false"
+          resource_path="mojo/mojo/public/mojom/base/string16.mojom.html"
           type="BINDATA" />
       <include name="IDR_MOJO_STRING16_MOJOM_LITE_JS"
           file="${root_gen_dir}/mojo/public/mojom/base/string16.mojom-lite.js"
           use_base_dir="false"
+          resource_path="mojo/mojo/public/mojom/base/string16.mojom-lite.js"
           type="BINDATA" />
       <include name="IDR_MOJO_TEXT_DIRECTION_MOJOM_HTML"
           file="${root_gen_dir}/mojo/public/mojom/base/text_direction.mojom.html"
           use_base_dir="false"
+          resource_path="mojo/mojo/public/mojom/base/text_direction.mojom.html"
           type="BINDATA" />
       <include name="IDR_MOJO_TEXT_DIRECTION_MOJOM_LITE_JS"
           file="${root_gen_dir}/mojo/public/mojom/base/text_direction.mojom-lite.js"
           use_base_dir="false"
+          resource_path="mojo/mojo/public/mojom/base/text_direction.mojom-lite.js"
           type="BINDATA" />
       <if expr="is_win or is_macosx or is_linux or is_android">
         <include name="IDR_MOJO_TIME_MOJOM_HTML"
             file="${root_gen_dir}/mojo/public/mojom/base/time.mojom.html"
             use_base_dir="false"
+            resource_path="mojo/mojo/public/mojom/base/time.mojom.html"
             type="BINDATA"
             compress="gzip" />
         <include name="IDR_MOJO_TIME_MOJOM_LITE_JS"
             file="${root_gen_dir}/mojo/public/mojom/base/time.mojom-lite.js"
+            resource_path="mojo/mojo/public/mojom/base/time.mojom-lite.js"
             use_base_dir="false"
             type="BINDATA"
             compress="gzip" />
diff --git a/mojo/public/tools/bindings/generators/js_templates/lite/mojom-lite.js.tmpl b/mojo/public/tools/bindings/generators/js_templates/lite/mojom-lite.js.tmpl
index 4f4cdce95..e057457 100644
--- a/mojo/public/tools/bindings/generators/js_templates/lite/mojom-lite.js.tmpl
+++ b/mojo/public/tools/bindings/generators/js_templates/lite/mojom-lite.js.tmpl
@@ -1,7 +1,11 @@
+{# For bindings internals, generated code is concatenated into a larger module
+ # at build time, so we avoid a superfluous file header here. #}
+{%- if not for_bindings_internals -%}
 // 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.
 'use strict';
+{%- endif %}
 
 {% if generate_closure_exports -%}
 goog.require('mojo.internal');
diff --git a/mojo/public/tools/bindings/generators/js_templates/lite/struct_definition.tmpl b/mojo/public/tools/bindings/generators/js_templates/lite/struct_definition.tmpl
index 1d6acbc..8b3e45a 100644
--- a/mojo/public/tools/bindings/generators/js_templates/lite/struct_definition.tmpl
+++ b/mojo/public/tools/bindings/generators/js_templates/lite/struct_definition.tmpl
@@ -40,6 +40,7 @@
 
 {%  if generate_closure_exports -%}
 goog.provide('{{module.namespace}}.{{struct.name}}');
+{%- endif %}
 
 /** @record */
 {{module.namespace}}.{{struct.name}} = class {
@@ -51,4 +52,3 @@
   }
 };
 
-{%- endif %}
diff --git a/mojo/public/tools/bindings/generators/mojom_js_generator.py b/mojo/public/tools/bindings/generators/mojom_js_generator.py
index 218050b4c..f5a46d82 100644
--- a/mojo/public/tools/bindings/generators/mojom_js_generator.py
+++ b/mojo/public/tools/bindings/generators/mojom_js_generator.py
@@ -203,6 +203,16 @@
 }
 
 
+_SHARED_MODULE_PREFIX = 'chrome://resources/mojo'
+
+
+def _GetWebUiModulePath(module):
+  path = module.metadata.get('webui_module_path')
+  if path is None:
+    return None
+  return path.strip('/')
+
+
 def JavaScriptPayloadSize(packed):
   packed_fields = packed.packed_fields
   if not packed_fields:
@@ -265,24 +275,40 @@
 
 
 class Generator(generator.Generator):
-  def _GetParameters(self, for_compile=False):
+  def _GetParameters(self, for_compile=False, for_webui_module=False):
     return {
-        "bindings_library_path": self._GetBindingsLibraryPath(),
-        "enums": self.module.enums,
-        "for_bindings_internals": self.disallow_native_types,
-        "html_imports": self._GenerateHtmlImports(),
-        "imports": self.module.imports,
-        "interfaces": self.module.interfaces,
-        "js_module_imports": self._GetJsModuleImports(),
-        "kinds": self.module.kinds,
-        "module": self.module,
-        "mojom_filename": os.path.basename(self.module.path),
-        "mojom_namespace": self.module.mojom_namespace,
-        "structs": self.module.structs + self._GetStructsFromMethods(),
-        "unions": self.module.unions,
-        "generate_fuzzing": self.generate_fuzzing,
-        "generate_closure_exports": for_compile,
-        "generate_struct_deserializers": self.js_generate_struct_deserializers,
+        "bindings_library_path":
+        self._GetBindingsLibraryPath(for_webui_module=for_webui_module),
+        "enums":
+        self.module.enums,
+        "for_bindings_internals":
+        self.disallow_native_types,
+        "html_imports":
+        self._GenerateHtmlImports(),
+        "imports":
+        self.module.imports,
+        "interfaces":
+        self.module.interfaces,
+        "js_module_imports":
+        self._GetJsModuleImports(for_webui_module=for_webui_module),
+        "kinds":
+        self.module.kinds,
+        "module":
+        self.module,
+        "mojom_filename":
+        os.path.basename(self.module.path),
+        "mojom_namespace":
+        self.module.mojom_namespace,
+        "structs":
+        self.module.structs + self._GetStructsFromMethods(),
+        "unions":
+        self.module.unions,
+        "generate_fuzzing":
+        self.generate_fuzzing,
+        "generate_closure_exports":
+        for_compile,
+        "generate_struct_deserializers":
+        self.js_generate_struct_deserializers,
     }
 
   @staticmethod
@@ -386,6 +412,10 @@
   def _GenerateJsModule(self):
     return self._GetParameters()
 
+  @UseJinja("lite/mojom.m.js.tmpl")
+  def _GenerateWebUiModule(self):
+    return self._GetParameters(for_webui_module=True)
+
   def GenerateFiles(self, args):
     if self.variant:
       raise Exception("Variants not supported in JavaScript bindings.")
@@ -409,6 +439,9 @@
                             "%s-lite-for-compile.js" % self.module.path)
       self.WriteWithComment(self._GenerateJsModule(),
                             "%s.m.js" % self.module.path)
+      if _GetWebUiModulePath(self.module) is not None:
+        self.WriteWithComment(self._GenerateWebUiModule(),
+                              "mojom-webui/%s-webui.js" % self.module.path)
 
   def _GetRelativePath(self, path):
     relpath = urllib_request.pathname2url(
@@ -417,8 +450,10 @@
       return relpath
     return './' + relpath
 
-  def _GetBindingsLibraryPath(self):
-    return self._GetRelativePath('mojo/public/js/bindings.m.js')
+  def _GetBindingsLibraryPath(self, for_webui_module=False):
+    if for_webui_module:
+      return "chrome://resources/mojo/mojo/public/js/bindings.js"
+    return self._GetRelativePath('mojo/public/js/bindings.js')
 
   def _SetUniqueNameForImports(self):
     used_names = set()
@@ -951,13 +986,39 @@
           os.path.relpath(full_import.path, os.path.dirname(self.module.path)))
     return result
 
-  def _GetJsModuleImports(self):
+  def _GetJsModuleImports(self, for_webui_module=False):
+    this_module_path = _GetWebUiModulePath(self.module)
+    if this_module_path:
+      this_module_is_shared = this_module_path.startswith(_SHARED_MODULE_PREFIX)
     imports = dict()
     for spec, kind in self.module.imported_kinds.items():
-      path = self._GetRelativePath(kind.module.path) + '.m.js'
-      if path not in imports:
-        imports[path] = []
-      imports[path].append(kind)
+      if for_webui_module:
+        base_path = _GetWebUiModulePath(kind.module)
+        assert base_path is not None
+        import_path = '{}/{}-webui.js'.format(
+            base_path, os.path.basename(kind.module.path))
+        import_module_is_shared = import_path.startswith(_SHARED_MODULE_PREFIX)
+        if import_module_is_shared == this_module_is_shared:
+          # Either we're a non-shared resource importing another non-shared
+          # resource, or we're a shared resource importing another shared
+          # resource. In both cases, we assume a relative import path will
+          # suffice.
+          import_path = os.path.relpath(
+              import_path.lstrip(_SHARED_MODULE_PREFIX),
+              this_module_path.lstrip(_SHARED_MODULE_PREFIX))
+          if (not import_path.startswith('.')
+              and not import_path.startswith('/')):
+            import_path = './' + import_path
+        else:
+          assert import_module_is_shared, \
+              'Shared WebUI module "{}" cannot depend on non-shared WebUI ' \
+                  'module "{}"'.format(self.module.path, kind.module.path)
+      else:
+        import_path = self._GetRelativePath(kind.module.path) + '.m.js'
+
+      if import_path not in imports:
+        imports[import_path] = []
+      imports[import_path].append(kind)
     return imports
 
   def _GetStructsFromMethods(self):
diff --git a/mojo/public/tools/bindings/mojom.gni b/mojo/public/tools/bindings/mojom.gni
index 9bebffdb..83b91a2 100644
--- a/mojo/public/tools/bindings/mojom.gni
+++ b/mojo/public/tools/bindings/mojom.gni
@@ -291,6 +291,21 @@
 #       List of extra C++ templates that are used to generate additional source
 #       and/or header files. The templates should end with extension ".tmpl".
 #
+#   webui_module_path (optional)
+#       The path or URL at which modules generated by this target will be
+#       accessible to WebUI pages. This may either be an absolute path or
+#       a full URL path starting with "chrome://resources/mojo".
+#
+#       If an absolute path, a WebUI page may only import these modules if
+#       they are manually packaged and mapped independently by that page's
+#       WebUIDataSource. The mapped path must match the path given here.
+#
+#       If this is is instead a URL string starting with
+#       "chrome://resources/mojo", the generated resources must be added to
+#       content_resources.grd and registered with
+#       content::SharedResourcesDataSource with a corresponding path, at which
+#       point they will be made available to all WebUI pages at the given URL.
+#
 # The following parameters are used to support the component build. They are
 # needed so that bindings which are linked with a component can use the same
 # export settings for classes. The first three are for the chromium variant, and
@@ -656,6 +671,13 @@
           enabled_feature,
         ]
       }
+
+      if (defined(invoker.webui_module_path)) {
+        args += [
+          "--add-module-metadata",
+          "webui_module_path=${invoker.webui_module_path}",
+        ]
+      }
     }
   }
 
@@ -1556,6 +1578,10 @@
             "$root_gen_dir/$base_path.html",
             "$root_gen_dir/$base_path-lite-for-compile.js",
           ]
+
+          if (defined(invoker.webui_module_path)) {
+            outputs += [ "$root_gen_dir/mojom-webui/$base_path-webui.js" ]
+          }
         }
 
         response_file_contents = filelist
@@ -1689,7 +1715,7 @@
             invoker.disallow_native_types) {
           deps = []
         } else {
-          deps = [ "//mojo/public/js:bindings_uncompiled.m" ]
+          deps = [ "//mojo/public/js:bindings_uncompiled" ]
         }
         foreach(d, all_deps) {
           full_name = get_label_info(d, "label_no_toolchain")
@@ -1700,6 +1726,36 @@
       group(js_modules_target_name) {
       }
     }
+
+    if (defined(invoker.webui_module_path)) {
+      webui_js_target_name = "${target_name}_webui_js"
+      if (sources_list != []) {
+        js_library(webui_js_target_name) {
+          extra_public_deps = [ ":$generator_js_target_name" ]
+          sources = []
+          foreach(base_path, output_file_base_paths) {
+            sources += [ "$root_gen_dir/mojom-webui/${base_path}-webui.js" ]
+          }
+          externs_list = [
+            "${externs_path}/mojo_core.js",
+            "${externs_path}/pending.js",
+          ]
+          if (defined(invoker.disallow_native_types) &&
+              invoker.disallow_native_types) {
+            deps = []
+          } else {
+            deps = [ "//mojo/public/js:bindings_uncompiled" ]
+          }
+          foreach(d, all_deps) {
+            full_name = get_label_info(d, "label_no_toolchain")
+            deps += [ "${full_name}_webui_js" ]
+          }
+        }
+      } else {
+        group(webui_js_target_name) {
+        }
+      }
+    }
   }
   if ((generate_fuzzing || !defined(invoker.cpp_only) || !invoker.cpp_only) &&
       use_typescript_for_target) {
diff --git a/mojo/public/tools/mojom/mojom/generate/module.py b/mojo/public/tools/mojom/mojom/generate/module.py
index d2aedeb8..e76f66a 100644
--- a/mojo/public/tools/mojom/mojom/generate/module.py
+++ b/mojo/public/tools/mojom/mojom/generate/module.py
@@ -1362,6 +1362,7 @@
     self.attributes = attributes
     self.imports = []
     self.imported_kinds = {}
+    self.metadata = {}
 
   def __repr__(self):
     # Gives us a decent __repr__ for modules.
diff --git a/mojo/public/tools/mojom/mojom_parser.py b/mojo/public/tools/mojom/mojom_parser.py
index 12adbfb..998304c 100755
--- a/mojo/public/tools/mojom/mojom_parser.py
+++ b/mojo/public/tools/mojom/mojom_parser.py
@@ -98,7 +98,7 @@
 
 
 def _EnsureInputLoaded(mojom_abspath, module_path, abs_paths, asts,
-                       dependencies, loaded_modules):
+                       dependencies, loaded_modules, module_metadata):
   """Recursively ensures that a module and its dependencies are loaded.
 
   Args:
@@ -111,10 +111,8 @@
         by absolute file path.
     loaded_modules: A mapping of all modules loaded so far, including non-input
         modules that were pulled in as transitive dependencies of the inputs.
-    import_set: The working set of mojom imports processed so far in this
-        call stack. Used to detect circular dependencies.
-    import_stack: An ordered list of imports processed so far in this call
-        stack. Used to report circular dependencies.
+    module_metadata: Metadata to be attached to every module loaded by this
+        helper.
 
   Returns:
     None
@@ -129,7 +127,7 @@
   for dep_abspath, dep_path in dependencies[mojom_abspath]:
     if dep_abspath not in loaded_modules:
       _EnsureInputLoaded(dep_abspath, dep_path, abs_paths, asts, dependencies,
-                         loaded_modules)
+                         loaded_modules, module_metadata)
 
   imports = {}
   for imp in asts[mojom_abspath].import_list:
@@ -137,6 +135,7 @@
     imports[path] = loaded_modules[abs_paths[path]]
   loaded_modules[mojom_abspath] = translate.OrderedModule(
       asts[mojom_abspath], module_path, imports)
+  loaded_modules[mojom_abspath].metadata = dict(module_metadata)
 
 
 def _CollectAllowedImportsFromBuildMetadata(build_metadata_filename):
@@ -161,6 +160,7 @@
                  input_root_paths,
                  output_root_path,
                  enabled_features,
+                 module_metadata,
                  allowed_imports=None):
   """Parses a set of mojom files and produces serialized module outputs.
 
@@ -176,6 +176,8 @@
         modules for any transitive dependencies not listed in mojom_files.
     enabled_features: A list of enabled feature names, controlling which AST
         nodes are filtered by [EnableIf] attributes.
+    module_metadata: A list of 2-tuples representing metadata key-value pairs to
+        attach to each compiled module output.
 
   Returns:
     None.
@@ -236,7 +238,7 @@
   num_existing_modules_loaded = len(loaded_modules)
   for mojom_abspath, mojom_path in mojom_files_to_parse.items():
     _EnsureInputLoaded(mojom_abspath, mojom_path, abs_paths, loaded_mojom_asts,
-                       input_dependencies, loaded_modules)
+                       input_dependencies, loaded_modules, module_metadata)
   assert (num_existing_modules_loaded +
           len(mojom_files_to_parse) == len(loaded_modules))
 
@@ -333,6 +335,16 @@
       'build-time dependency checking for mojom imports, where each build '
       'metadata file corresponds to a build target in the dependency graph of '
       'a typical build system.')
+  arg_parser.add_argument(
+      '--add-module-metadata',
+      dest='module_metadata',
+      default=[],
+      action='append',
+      metavar='KEY=VALUE',
+      help='Adds a metadata key-value pair to the output module. This can be '
+      'used by build toolchains to augment parsed mojom modules with product-'
+      'specific metadata for later extraction and use by custom bindings '
+      'generators.')
 
   args, _ = arg_parser.parse_known_args(command_line)
   if args.mojom_file_list:
@@ -353,8 +365,9 @@
   else:
     allowed_imports = None
 
+  module_metadata = map(lambda kvp: tuple(kvp.split('=')), args.module_metadata)
   _ParseMojoms(mojom_files, input_roots, output_root, args.enabled_features,
-               allowed_imports)
+               module_metadata, allowed_imports)
 
 
 if __name__ == '__main__':
diff --git a/net/base/net_info_source_list.h b/net/base/net_info_source_list.h
index 40223c3..d947860 100644
--- a/net/base/net_info_source_list.h
+++ b/net/base/net_info_source_list.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef NET_LOG_NET_INFO_SOURCE_LIST_H_
-#define NET_LOG_NET_INFO_SOURCE_LIST_H_
+#ifndef NET_BASE_NET_INFO_SOURCE_LIST_H_
+#define NET_BASE_NET_INFO_SOURCE_LIST_H_
 
 // NetInfo Sources written to NetLog JSON files.
 const char kNetInfoProxySettings[] = "proxySettings";
@@ -16,5 +16,6 @@
 const char kNetInfoAltSvcMappings[] = "altSvcMappings";
 const char kNetInfoHTTPCache[] = "httpCacheInfo";
 const char kNetInfoReporting[] = "reportingInfo";
+const char kNetInfoFieldTrials[] = "activeFieldTrialGroups";
 
-#endif
+#endif  // NET_BASE_NET_INFO_SOURCE_LIST_H_
diff --git a/net/cookies/parsed_cookie_unittest.cc b/net/cookies/parsed_cookie_unittest.cc
index 27ce53d..83eb707 100644
--- a/net/cookies/parsed_cookie_unittest.cc
+++ b/net/cookies/parsed_cookie_unittest.cc
@@ -48,7 +48,7 @@
   EXPECT_EQ("value", empty_name.Value());
   EXPECT_FALSE(empty_name.SetValue(""));
   EXPECT_EQ("value", empty_name.Value());
-  EXPECT_TRUE(empty_value.IsValid());
+  EXPECT_TRUE(empty_name.IsValid());
 }
 
 TEST(ParsedCookieTest, TestQuoted) {
diff --git a/net/log/net_log_util.cc b/net/log/net_log_util.cc
index 513b12c2..56f66e5 100644
--- a/net/log/net_log_util.cc
+++ b/net/log/net_log_util.cc
@@ -122,6 +122,16 @@
   return request1->net_log().source().id < request2->net_log().source().id;
 }
 
+base::Value GetActiveFieldTrialList() {
+  base::FieldTrial::ActiveGroups active_groups;
+  base::FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
+  base::Value field_trial_groups(base::Value::Type::LIST);
+  for (const auto& group : active_groups) {
+    field_trial_groups.Append(group.trial_name + ":" + group.group_name);
+  }
+  return field_trial_groups;
+}
+
 }  // namespace
 
 base::Value GetNetConstants() {
@@ -314,20 +324,9 @@
   constants_dict.SetKey("clientInfo",
                         base::Value(base::Value::Type::DICTIONARY));
 
-  // Add a list of active field experiments.
-  {
-    base::FieldTrial::ActiveGroups active_groups;
-    base::FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
-    auto field_trial_groups = std::make_unique<base::ListValue>();
-    for (base::FieldTrial::ActiveGroups::const_iterator it =
-             active_groups.begin();
-         it != active_groups.end(); ++it) {
-      field_trial_groups->AppendString(it->trial_name + ":" + it->group_name);
-    }
-    constants_dict.SetKey(
-        "activeFieldTrialGroups",
-        base::Value::FromUniquePtrValue(std::move(field_trial_groups)));
-  }
+  // Add a list of field experiments active at the start of the capture.
+  // Additional trials may be enabled later in the browser session.
+  constants_dict.SetKey(kNetInfoFieldTrials, GetActiveFieldTrialList());
 
   return constants_dict;
 }
@@ -470,6 +469,10 @@
 #endif  // BUILDFLAG(ENABLE_REPORTING)
   }
 
+  // Log currently-active field trials. New trials may have been enabled since
+  // the start of this browser session (crbug.com/1133396).
+  net_info_dict.SetKey(kNetInfoFieldTrials, GetActiveFieldTrialList());
+
   return net_info_dict;
 }
 
diff --git a/net/log/net_log_util_unittest.cc b/net/log/net_log_util_unittest.cc
index ac8cbc5..c36f65d 100644
--- a/net/log/net_log_util_unittest.cc
+++ b/net/log/net_log_util_unittest.cc
@@ -8,6 +8,8 @@
 #include <vector>
 
 #include "base/files/file_path.h"
+#include "base/metrics/field_trial.h"
+#include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "base/values.h"
 #include "net/base/net_errors.h"
@@ -44,7 +46,7 @@
   EXPECT_FALSE(http_cache->GetCurrentBackend());
   EXPECT_GT(net_info_without_cache.DictSize(), 0u);
 
-  // Fore creation of a cache backend, and get NetInfo again.
+  // Force creation of a cache backend, and get NetInfo again.
   disk_cache::Backend* backend = nullptr;
   EXPECT_EQ(OK, context.http_transaction_factory()->GetCache()->GetBackend(
                     &backend, TestCompletionCallback().callback()));
@@ -55,6 +57,36 @@
   EXPECT_EQ(net_info_without_cache.DictSize(), net_info_with_cache.DictSize());
 }
 
+// Verify that active Field Trials are reflected.
+TEST(NetLogUtil, GetNetInfoIncludesFieldTrials) {
+  base::test::TaskEnvironment task_environment;
+
+  // Clear all Field Trials.
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitWithFeatureList(
+      std::make_unique<base::FeatureList>());
+
+  // Add and activate a new Field Trial.
+  base::FieldTrial* field_trial = base::FieldTrialList::FactoryGetFieldTrial(
+      "NewFieldTrial", 100, "Default", base::FieldTrial::ONE_TIME_RANDOMIZED,
+      nullptr);
+  field_trial->AppendGroup("Active", 100);
+  EXPECT_EQ(field_trial->group_name(), "Active");
+
+  TestURLRequestContext context;
+  base::Value net_info(GetNetInfo(&context));
+
+  // Verify that the returned information reflects the new trial.
+  ASSERT_TRUE(net_info.is_dict());
+  base::Value* trials = net_info.FindListPath("activeFieldTrialGroups");
+  ASSERT_NE(nullptr, trials);
+  const auto& trial_list = trials->GetList();
+  EXPECT_EQ(1u, trial_list.size());
+  std::string result;
+  EXPECT_TRUE(trial_list[0].GetAsString(&result));
+  EXPECT_EQ("NewFieldTrial:Active", result);
+}
+
 // Make sure CreateNetLogEntriesForActiveObjects works for requests from a
 // single URLRequestContext.
 TEST(NetLogUtil, CreateNetLogEntriesForActiveObjectsOneContext) {
diff --git a/services/data_decoder/README.md b/services/data_decoder/README.md
index e84b2a13..a99ab4a7 100644
--- a/services/data_decoder/README.md
+++ b/services/data_decoder/README.md
@@ -1,3 +1,5 @@
 The data_decoder service exists to facilitate safe data decoding within an
 isolated sandboxed process.
 
+NOTE: Protobuf is considered robust enough to decode untrusted input even
+without sandboxing. So you won't find a protobuf decoder in this service.
diff --git a/services/network/public/cpp/features.cc b/services/network/public/cpp/features.cc
index 5d8e8876..90169f5dd 100644
--- a/services/network/public/cpp/features.cc
+++ b/services/network/public/cpp/features.cc
@@ -151,17 +151,6 @@
 const base::FeatureParam<std::string> kEmergencyLegacyCookieAccessParam{
     &kEmergencyLegacyCookieAccess, kEmergencyLegacyCookieAccessParamName, ""};
 
-// Controls whether the CORB allowlist [1] is also applied to OOR-CORS (e.g.
-// whether non-allowlisted content scripts are subject to CORS in OOR-CORS
-// mode).  See also: https://crbug.com/920638
-//
-// [1]
-// https://www.chromium.org/Home/chromium-security/extension-content-script-fetches
-const base::Feature kCorbAllowlistAlsoAppliesToOorCors = {
-    "CorbAllowlistAlsoAppliesToOorCors", base::FEATURE_ENABLED_BY_DEFAULT};
-const char kCorbAllowlistAlsoAppliesToOorCorsParamName[] =
-    "AllowlistForCorbAndCors";
-
 // Controls whether a |request_initiator| that mismatches
 // |request_initiator_origin_lock| leads to 1) failing the HTTP request and 2)
 // calling mojo::ReportBadMessage (on desktop platforms, where NetworkService
diff --git a/services/network/public/cpp/features.h b/services/network/public/cpp/features.h
index 1fc5e77b..2878954 100644
--- a/services/network/public/cpp/features.h
+++ b/services/network/public/cpp/features.h
@@ -64,10 +64,6 @@
 extern const base::FeatureParam<std::string> kEmergencyLegacyCookieAccessParam;
 
 COMPONENT_EXPORT(NETWORK_CPP)
-extern const base::Feature kCorbAllowlistAlsoAppliesToOorCors;
-COMPONENT_EXPORT(NETWORK_CPP)
-extern const char kCorbAllowlistAlsoAppliesToOorCorsParamName[];
-COMPONENT_EXPORT(NETWORK_CPP)
 extern const base::Feature kRequestInitiatorSiteLockEnfocement;
 COMPONENT_EXPORT(NETWORK_CPP)
 extern const base::Feature kCertVerifierService;
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json
index 94000ccc..db66efd 100644
--- a/testing/buildbot/chromium.android.fyi.json
+++ b/testing/buildbot/chromium.android.fyi.json
@@ -3007,154 +3007,6 @@
           "--test-runner-outdir",
           ".",
           "--client-outdir",
-          "../../weblayer_instrumentation_test_M84/out/Release",
-          "--implementation-outdir",
-          ".",
-          "--test-expectations",
-          "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--client-version=84",
-          "--gs-results-bucket=chromium-result-details",
-          "--recover-devices",
-          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb"
-        ],
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "weblayer_instrumentation_test_versions_apk_M84_Client_Library_Tests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "name": "weblayer_instrumentation_test_versions_apk_M84_Client_Library_Tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "chromium/testing/weblayer-x86",
-              "location": "weblayer_instrumentation_test_M84",
-              "revision": "version:dup-84.0.4147.89"
-            },
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "cpu": "x86-64",
-              "device_os": null,
-              "device_type": null,
-              "machine_type": "n1-standard-4",
-              "os": "Ubuntu-16.04",
-              "pool": "chromium.tests.avd"
-            }
-          ],
-          "named_caches": [
-            {
-              "name": "avd_generic_android28",
-              "path": ".android"
-            },
-            {
-              "name": "system_images_android_28_google_apis_x86",
-              "path": ".emulator_sdk"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "weblayer_instrumentation_test_versions_apk",
-        "test_id_prefix": "ninja://weblayer/browser/android/javatests:weblayer_instrumentation_test_versions_apk/"
-      },
-      {
-        "args": [
-          "--test-runner-outdir",
-          ".",
-          "--client-outdir",
-          ".",
-          "--implementation-outdir",
-          "../../weblayer_instrumentation_test_M84/out/Release",
-          "--test-expectations",
-          "../../weblayer/browser/android/javatests/skew/expectations.txt",
-          "--impl-version=84",
-          "--gs-results-bucket=chromium-result-details",
-          "--recover-devices",
-          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb"
-        ],
-        "merge": {
-          "args": [
-            "--bucket",
-            "chromium-result-details",
-            "--test-name",
-            "weblayer_instrumentation_test_versions_apk_M84_Implementation_Library_Tests"
-          ],
-          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
-        },
-        "name": "weblayer_instrumentation_test_versions_apk_M84_Implementation_Library_Tests",
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "cipd_packages": [
-            {
-              "cipd_package": "chromium/testing/weblayer-x86",
-              "location": "weblayer_instrumentation_test_M84",
-              "revision": "version:dup-84.0.4147.89"
-            },
-            {
-              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
-              "location": "bin",
-              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
-            }
-          ],
-          "dimension_sets": [
-            {
-              "cpu": "x86-64",
-              "device_os": null,
-              "device_type": null,
-              "machine_type": "n1-standard-4",
-              "os": "Ubuntu-16.04",
-              "pool": "chromium.tests.avd"
-            }
-          ],
-          "named_caches": [
-            {
-              "name": "avd_generic_android28",
-              "path": ".android"
-            },
-            {
-              "name": "system_images_android_28_google_apis_x86",
-              "path": ".emulator_sdk"
-            }
-          ],
-          "output_links": [
-            {
-              "link": [
-                "https://luci-logdog.appspot.com/v/?s",
-                "=android%2Fswarming%2Flogcats%2F",
-                "${TASK_ID}%2F%2B%2Funified_logcats"
-              ],
-              "name": "shard #${SHARD_INDEX} logcats"
-            }
-          ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
-        },
-        "test": "weblayer_instrumentation_test_versions_apk",
-        "test_id_prefix": "ninja://weblayer/browser/android/javatests:weblayer_instrumentation_test_versions_apk/"
-      },
-      {
-        "args": [
-          "--test-runner-outdir",
-          ".",
-          "--client-outdir",
           "../../weblayer_instrumentation_test_M85/out/Release",
           "--implementation-outdir",
           ".",
@@ -3181,7 +3033,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M85",
-              "revision": "version:85.0.4183.81"
+              "revision": "version:85.0.4183.140"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -3445,6 +3297,154 @@
         },
         "test": "weblayer_instrumentation_test_versions_apk",
         "test_id_prefix": "ninja://weblayer/browser/android/javatests:weblayer_instrumentation_test_versions_apk/"
+      },
+      {
+        "args": [
+          "--test-runner-outdir",
+          ".",
+          "--client-outdir",
+          "../../weblayer_instrumentation_test_M87/out/Release",
+          "--implementation-outdir",
+          ".",
+          "--test-expectations",
+          "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--client-version=87",
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "weblayer_instrumentation_test_versions_apk_M87_Client_Library_Tests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "name": "weblayer_instrumentation_test_versions_apk_M87_Client_Library_Tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "chromium/testing/weblayer-x86",
+              "location": "weblayer_instrumentation_test_M87",
+              "revision": "version:87.0.4280.20"
+            },
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4",
+              "os": "Ubuntu-16.04",
+              "pool": "chromium.tests.avd"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "avd_generic_android28",
+              "path": ".android"
+            },
+            {
+              "name": "system_images_android_28_google_apis_x86",
+              "path": ".emulator_sdk"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "weblayer_instrumentation_test_versions_apk",
+        "test_id_prefix": "ninja://weblayer/browser/android/javatests:weblayer_instrumentation_test_versions_apk/"
+      },
+      {
+        "args": [
+          "--test-runner-outdir",
+          ".",
+          "--client-outdir",
+          ".",
+          "--implementation-outdir",
+          "../../weblayer_instrumentation_test_M87/out/Release",
+          "--test-expectations",
+          "../../weblayer/browser/android/javatests/skew/expectations.txt",
+          "--impl-version=87",
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices",
+          "--avd-config=../../tools/android/avd/proto/generic_android28.textpb"
+        ],
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "weblayer_instrumentation_test_versions_apk_M87_Implementation_Library_Tests"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "name": "weblayer_instrumentation_test_versions_apk_M87_Implementation_Library_Tests",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "chromium/testing/weblayer-x86",
+              "location": "weblayer_instrumentation_test_M87",
+              "revision": "version:87.0.4280.20"
+            },
+            {
+              "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
+              "location": "bin",
+              "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4",
+              "os": "Ubuntu-16.04",
+              "pool": "chromium.tests.avd"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "avd_generic_android28",
+              "path": ".android"
+            },
+            {
+              "name": "system_images_android_28_google_apis_x86",
+              "path": ".emulator_sdk"
+            }
+          ],
+          "output_links": [
+            {
+              "link": [
+                "https://luci-logdog.appspot.com/v/?s",
+                "=android%2Fswarming%2Flogcats%2F",
+                "${TASK_ID}%2F%2B%2Funified_logcats"
+              ],
+              "name": "shard #${SHARD_INDEX} logcats"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "weblayer_instrumentation_test_versions_apk",
+        "test_id_prefix": "ninja://weblayer/browser/android/javatests:weblayer_instrumentation_test_versions_apk/"
       }
     ]
   }
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json
index cea38190..79aeb81 100644
--- a/testing/buildbot/chromium.android.json
+++ b/testing/buildbot/chromium.android.json
@@ -33778,6 +33778,42 @@
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
         "test_id_prefix": "ninja://components:components_perftests/"
+      },
+      {
+        "args": [
+          "--avd-config=../../tools/android/avd/proto/generic_android23.textpb"
+        ],
+        "isolate_name": "monochrome_public_apk_checker",
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "monochrome_public_apk_checker",
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "x86-64",
+              "device_os": null,
+              "device_type": null,
+              "machine_type": "n1-standard-4",
+              "os": "Ubuntu-16.04",
+              "pool": "chromium.tests.avd"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "avd_generic_android23",
+              "path": ".android"
+            },
+            {
+              "name": "system_images_android_23_google_apis_x86",
+              "path": ".emulator_sdk"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://chrome/android/monochrome:monochrome_public_apk_checker/"
       }
     ]
   },
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index 082fcde3..5891249 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -4323,6 +4323,18 @@
         "test_id_prefix": "ninja://chrome/test:lacros_chrome_browsertests/"
       },
       {
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "ui_base_unittests",
+        "test_id_prefix": "ninja://ui/base:ui_base_unittests/"
+      },
+      {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/lacros.unit_tests.filter"
         ],
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index a4a98354..15f09cdd 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -21275,7 +21275,7 @@
           "--platform",
           "iPhone 6s",
           "--version",
-          "12.4",
+          "13.6",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -21290,7 +21290,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "absl_hardening_tests_iPhone 6s 12.4",
+        "name": "absl_hardening_tests_iPhone 6s 13.6",
         "resultdb": {
           "enable": false
         },
@@ -21323,7 +21323,7 @@
           "--platform",
           "iPhone 6s",
           "--version",
-          "13.6",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -21338,7 +21338,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "absl_hardening_tests_iPhone 6s 13.6",
+        "name": "absl_hardening_tests_iPhone 6s 14.0",
         "resultdb": {
           "enable": false
         },
@@ -21417,6 +21417,54 @@
       {
         "args": [
           "--platform",
+          "iPad Air 2",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "base_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "base_unittests_iPad Air 2 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://base:base_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 6s",
           "--version",
           "13.6",
@@ -21465,6 +21513,54 @@
       {
         "args": [
           "--platform",
+          "iPhone 6s",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "base_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "base_unittests_iPhone 6s 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://base:base_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 6s Plus",
           "--version",
           "13.6",
@@ -21513,6 +21609,54 @@
       {
         "args": [
           "--platform",
+          "iPhone 6s Plus",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "base_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "base_unittests_iPhone 6s Plus 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://base:base_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone SE (1st generation)",
           "--version",
           "13.6",
@@ -21561,9 +21705,9 @@
       {
         "args": [
           "--platform",
-          "iPhone 6s",
+          "iPhone SE (1st generation)",
           "--version",
-          "12.4",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -21572,13 +21716,13 @@
           "12a7209",
           "--xctest"
         ],
-        "isolate_name": "boringssl_crypto_tests",
+        "isolate_name": "base_unittests",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "boringssl_crypto_tests_iPhone 6s 12.4",
+        "name": "base_unittests_iPhone SE (1st generation) 14.0",
         "resultdb": {
           "enable": false
         },
@@ -21604,7 +21748,7 @@
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
-        "test_id_prefix": "ninja://third_party/boringssl:boringssl_crypto_tests/"
+        "test_id_prefix": "ninja://base:base_unittests/"
       },
       {
         "args": [
@@ -21659,7 +21803,55 @@
           "--platform",
           "iPhone 6s",
           "--version",
-          "12.4",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "boringssl_crypto_tests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "boringssl_crypto_tests_iPhone 6s 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://third_party/boringssl:boringssl_crypto_tests/"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone 6s",
+          "--version",
+          "13.6",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -21674,7 +21866,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "boringssl_ssl_tests_iPhone 6s 12.4",
+        "name": "boringssl_ssl_tests_iPhone 6s 13.6",
         "resultdb": {
           "enable": false
         },
@@ -21707,7 +21899,7 @@
           "--platform",
           "iPhone 6s",
           "--version",
-          "13.6",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -21722,7 +21914,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "boringssl_ssl_tests_iPhone 6s 13.6",
+        "name": "boringssl_ssl_tests_iPhone 6s 14.0",
         "resultdb": {
           "enable": false
         },
@@ -21801,6 +21993,54 @@
       {
         "args": [
           "--platform",
+          "iPad Air 2",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "components_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "components_unittests_iPad Air 2 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://components:components_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 6s",
           "--version",
           "13.6",
@@ -21849,6 +22089,54 @@
       {
         "args": [
           "--platform",
+          "iPhone 6s",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "components_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "components_unittests_iPhone 6s 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://components:components_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 6s Plus",
           "--version",
           "13.6",
@@ -21897,6 +22185,54 @@
       {
         "args": [
           "--platform",
+          "iPhone 6s Plus",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "components_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "components_unittests_iPhone 6s Plus 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://components:components_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone SE (1st generation)",
           "--version",
           "13.6",
@@ -21945,9 +22281,57 @@
       {
         "args": [
           "--platform",
+          "iPhone SE (1st generation)",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "components_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "components_unittests_iPhone SE (1st generation) 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://components:components_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 6s",
           "--version",
-          "12.4",
+          "13.6",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -21962,7 +22346,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "crypto_unittests_iPhone 6s 12.4",
+        "name": "crypto_unittests_iPhone 6s 13.6",
         "resultdb": {
           "enable": false
         },
@@ -21995,7 +22379,7 @@
           "--platform",
           "iPhone 6s",
           "--version",
-          "13.6",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -22010,7 +22394,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "crypto_unittests_iPhone 6s 13.6",
+        "name": "crypto_unittests_iPhone 6s 14.0",
         "resultdb": {
           "enable": false
         },
@@ -22089,6 +22473,54 @@
       {
         "args": [
           "--platform",
+          "iPad Air 2",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "gfx_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "gfx_unittests_iPad Air 2 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ui/gfx:gfx_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 6s",
           "--version",
           "13.6",
@@ -22137,6 +22569,54 @@
       {
         "args": [
           "--platform",
+          "iPhone 6s",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "gfx_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "gfx_unittests_iPhone 6s 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ui/gfx:gfx_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 6s Plus",
           "--version",
           "13.6",
@@ -22185,6 +22665,54 @@
       {
         "args": [
           "--platform",
+          "iPhone 6s Plus",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "gfx_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "gfx_unittests_iPhone 6s Plus 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ui/gfx:gfx_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone SE (1st generation)",
           "--version",
           "13.6",
@@ -22233,9 +22761,9 @@
       {
         "args": [
           "--platform",
-          "iPhone 6s",
+          "iPhone SE (1st generation)",
           "--version",
-          "12.4",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -22244,13 +22772,13 @@
           "12a7209",
           "--xctest"
         ],
-        "isolate_name": "google_apis_unittests",
+        "isolate_name": "gfx_unittests",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "google_apis_unittests_iPhone 6s 12.4",
+        "name": "gfx_unittests_iPhone SE (1st generation) 14.0",
         "resultdb": {
           "enable": false
         },
@@ -22276,7 +22804,7 @@
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
-        "test_id_prefix": "ninja://google_apis:google_apis_unittests/"
+        "test_id_prefix": "ninja://ui/gfx:gfx_unittests/"
       },
       {
         "args": [
@@ -22329,9 +22857,57 @@
       {
         "args": [
           "--platform",
+          "iPhone 6s",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "google_apis_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "google_apis_unittests_iPhone 6s 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://google_apis:google_apis_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPad Air 2",
           "--version",
-          "12.4",
+          "13.6",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -22347,7 +22923,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_chrome_bookmarks_eg2tests_module_iPad Air 2 12.4",
+        "name": "ios_chrome_bookmarks_eg2tests_module_iPad Air 2 13.6",
         "resultdb": {
           "enable": false
         },
@@ -22380,7 +22956,7 @@
           "--platform",
           "iPad Air 2",
           "--version",
-          "13.6",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -22396,7 +22972,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_chrome_bookmarks_eg2tests_module_iPad Air 2 13.6",
+        "name": "ios_chrome_bookmarks_eg2tests_module_iPad Air 2 14.0",
         "resultdb": {
           "enable": false
         },
@@ -22476,9 +23052,9 @@
       {
         "args": [
           "--platform",
-          "iPhone X",
+          "iPhone 7",
           "--version",
-          "12.4",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -22494,7 +23070,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_chrome_bookmarks_eg2tests_module_iPhone X 12.4",
+        "name": "ios_chrome_bookmarks_eg2tests_module_iPhone 7 14.0",
         "resultdb": {
           "enable": false
         },
@@ -22574,9 +23150,9 @@
       {
         "args": [
           "--platform",
-          "iPad Air 2",
+          "iPhone X",
           "--version",
-          "12.4",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -22586,13 +23162,13 @@
           "--xctest",
           "--xcode-parallelization"
         ],
-        "isolate_name": "ios_chrome_integration_eg2tests_module",
+        "isolate_name": "ios_chrome_bookmarks_eg2tests_module",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_chrome_integration_eg2tests_module_iPad Air 2 12.4",
+        "name": "ios_chrome_bookmarks_eg2tests_module_iPhone X 14.0",
         "resultdb": {
           "enable": false
         },
@@ -22616,10 +23192,9 @@
               "path": "Xcode.app"
             }
           ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 3
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
-        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_integration_eg2tests_module/"
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/"
       },
       {
         "args": [
@@ -22674,9 +23249,9 @@
       {
         "args": [
           "--platform",
-          "iPhone 6s",
+          "iPad Air 2",
           "--version",
-          "12.4",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -22692,7 +23267,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_chrome_integration_eg2tests_module_iPhone 6s 12.4",
+        "name": "ios_chrome_integration_eg2tests_module_iPad Air 2 14.0",
         "resultdb": {
           "enable": false
         },
@@ -22774,6 +23349,56 @@
       {
         "args": [
           "--platform",
+          "iPhone 6s",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest",
+          "--xcode-parallelization"
+        ],
+        "isolate_name": "ios_chrome_integration_eg2tests_module",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_integration_eg2tests_module_iPhone 6s 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 3
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_integration_eg2tests_module/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 7",
           "--version",
           "13.6",
@@ -22824,9 +23449,59 @@
       {
         "args": [
           "--platform",
+          "iPhone 7",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest",
+          "--xcode-parallelization"
+        ],
+        "isolate_name": "ios_chrome_integration_eg2tests_module",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_integration_eg2tests_module_iPhone 7 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 3
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_integration_eg2tests_module/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPad Air 2",
           "--version",
-          "12.4",
+          "13.6",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -22842,7 +23517,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_chrome_settings_eg2tests_module_iPad Air 2 12.4",
+        "name": "ios_chrome_settings_eg2tests_module_iPad Air 2 13.6",
         "resultdb": {
           "enable": false
         },
@@ -22876,7 +23551,7 @@
           "--platform",
           "iPad Air 2",
           "--version",
-          "13.6",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -22892,7 +23567,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_chrome_settings_eg2tests_module_iPad Air 2 13.6",
+        "name": "ios_chrome_settings_eg2tests_module_iPad Air 2 14.0",
         "resultdb": {
           "enable": false
         },
@@ -22974,9 +23649,9 @@
       {
         "args": [
           "--platform",
-          "iPhone X",
+          "iPhone 7",
           "--version",
-          "12.4",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -22992,7 +23667,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_chrome_settings_eg2tests_module_iPhone X 12.4",
+        "name": "ios_chrome_settings_eg2tests_module_iPhone 7 14.0",
         "resultdb": {
           "enable": false
         },
@@ -23074,9 +23749,9 @@
       {
         "args": [
           "--platform",
-          "iPad Air 2",
+          "iPhone X",
           "--version",
-          "12.4",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -23086,13 +23761,13 @@
           "--xctest",
           "--xcode-parallelization"
         ],
-        "isolate_name": "ios_chrome_signin_eg2tests_module",
+        "isolate_name": "ios_chrome_settings_eg2tests_module",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_chrome_signin_eg2tests_module_iPad Air 2 12.4",
+        "name": "ios_chrome_settings_eg2tests_module_iPhone X 14.0",
         "resultdb": {
           "enable": false
         },
@@ -23116,9 +23791,10 @@
               "path": "Xcode.app"
             }
           ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 3
         },
-        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_signin_eg2tests_module/"
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/"
       },
       {
         "args": [
@@ -23172,9 +23848,9 @@
       {
         "args": [
           "--platform",
-          "iPhone 6s",
+          "iPad Air 2",
           "--version",
-          "12.4",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -23190,7 +23866,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_chrome_signin_eg2tests_module_iPhone 6s 12.4",
+        "name": "ios_chrome_signin_eg2tests_module_iPad Air 2 14.0",
         "resultdb": {
           "enable": false
         },
@@ -23270,6 +23946,55 @@
       {
         "args": [
           "--platform",
+          "iPhone 6s",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest",
+          "--xcode-parallelization"
+        ],
+        "isolate_name": "ios_chrome_signin_eg2tests_module",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_signin_eg2tests_module_iPhone 6s 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_signin_eg2tests_module/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 7",
           "--version",
           "13.6",
@@ -23319,9 +24044,58 @@
       {
         "args": [
           "--platform",
+          "iPhone 7",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest",
+          "--xcode-parallelization"
+        ],
+        "isolate_name": "ios_chrome_signin_eg2tests_module",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_signin_eg2tests_module_iPhone 7 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_signin_eg2tests_module/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPad Air 2",
           "--version",
-          "12.4",
+          "13.6",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -23337,7 +24111,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_chrome_smoke_eg2tests_module_iPad Air 2 12.4",
+        "name": "ios_chrome_smoke_eg2tests_module_iPad Air 2 13.6",
         "resultdb": {
           "enable": false
         },
@@ -23370,7 +24144,7 @@
           "--platform",
           "iPad Air 2",
           "--version",
-          "13.6",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -23386,7 +24160,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_chrome_smoke_eg2tests_module_iPad Air 2 13.6",
+        "name": "ios_chrome_smoke_eg2tests_module_iPad Air 2 14.0",
         "resultdb": {
           "enable": false
         },
@@ -23466,9 +24240,9 @@
       {
         "args": [
           "--platform",
-          "iPhone X",
+          "iPhone 7",
           "--version",
-          "12.4",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -23484,7 +24258,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_chrome_smoke_eg2tests_module_iPhone X 12.4",
+        "name": "ios_chrome_smoke_eg2tests_module_iPhone 7 14.0",
         "resultdb": {
           "enable": false
         },
@@ -23564,9 +24338,9 @@
       {
         "args": [
           "--platform",
-          "iPad Air 2",
+          "iPhone X",
           "--version",
-          "12.4",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -23576,13 +24350,13 @@
           "--xctest",
           "--xcode-parallelization"
         ],
-        "isolate_name": "ios_chrome_ui_eg2tests_module",
+        "isolate_name": "ios_chrome_smoke_eg2tests_module",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_chrome_ui_eg2tests_module_iPad Air 2 12.4",
+        "name": "ios_chrome_smoke_eg2tests_module_iPhone X 14.0",
         "resultdb": {
           "enable": false
         },
@@ -23606,10 +24380,9 @@
               "path": "Xcode.app"
             }
           ],
-          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
-          "shards": 5
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
-        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_ui_eg2tests_module/"
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/"
       },
       {
         "args": [
@@ -23664,9 +24437,9 @@
       {
         "args": [
           "--platform",
-          "iPhone 6s",
+          "iPad Air 2",
           "--version",
-          "12.4",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -23682,7 +24455,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_chrome_ui_eg2tests_module_iPhone 6s 12.4",
+        "name": "ios_chrome_ui_eg2tests_module_iPad Air 2 14.0",
         "resultdb": {
           "enable": false
         },
@@ -23764,6 +24537,56 @@
       {
         "args": [
           "--platform",
+          "iPhone 6s",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest",
+          "--xcode-parallelization"
+        ],
+        "isolate_name": "ios_chrome_ui_eg2tests_module",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_ui_eg2tests_module_iPhone 6s 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 5
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_ui_eg2tests_module/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 7",
           "--version",
           "13.6",
@@ -23814,6 +24637,56 @@
       {
         "args": [
           "--platform",
+          "iPhone 7",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest",
+          "--xcode-parallelization"
+        ],
+        "isolate_name": "ios_chrome_ui_eg2tests_module",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_ui_eg2tests_module_iPhone 7 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
+          "shards": 5
+        },
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_ui_eg2tests_module/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPad Air 2",
           "--version",
           "13.6",
@@ -23862,6 +24735,54 @@
       {
         "args": [
           "--platform",
+          "iPad Air 2",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "ios_chrome_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_unittests_iPad Air 2 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 6s",
           "--version",
           "13.6",
@@ -23910,6 +24831,54 @@
       {
         "args": [
           "--platform",
+          "iPhone 6s",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "ios_chrome_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_unittests_iPhone 6s 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 6s Plus",
           "--version",
           "13.6",
@@ -23958,6 +24927,54 @@
       {
         "args": [
           "--platform",
+          "iPhone 6s Plus",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "ios_chrome_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_unittests_iPhone 6s Plus 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone SE (1st generation)",
           "--version",
           "13.6",
@@ -24006,9 +25023,57 @@
       {
         "args": [
           "--platform",
+          "iPhone SE (1st generation)",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "ios_chrome_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_chrome_unittests_iPhone SE (1st generation) 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPad Air 2",
           "--version",
-          "12.4",
+          "13.6",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -24024,7 +25089,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_chrome_web_eg2tests_module_iPad Air 2 12.4",
+        "name": "ios_chrome_web_eg2tests_module_iPad Air 2 13.6",
         "resultdb": {
           "enable": false
         },
@@ -24057,7 +25122,7 @@
           "--platform",
           "iPad Air 2",
           "--version",
-          "13.6",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -24073,7 +25138,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_chrome_web_eg2tests_module_iPad Air 2 13.6",
+        "name": "ios_chrome_web_eg2tests_module_iPad Air 2 14.0",
         "resultdb": {
           "enable": false
         },
@@ -24153,9 +25218,9 @@
       {
         "args": [
           "--platform",
-          "iPhone X",
+          "iPhone 7",
           "--version",
-          "12.4",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -24171,7 +25236,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_chrome_web_eg2tests_module_iPhone X 12.4",
+        "name": "ios_chrome_web_eg2tests_module_iPhone 7 14.0",
         "resultdb": {
           "enable": false
         },
@@ -24251,24 +25316,25 @@
       {
         "args": [
           "--platform",
-          "iPhone 6s",
+          "iPhone X",
           "--version",
-          "12.4",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
           "12a7209",
-          "--xctest"
+          "--xctest",
+          "--xcode-parallelization"
         ],
-        "isolate_name": "ios_components_unittests",
+        "isolate_name": "ios_chrome_web_eg2tests_module",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_components_unittests_iPhone 6s 12.4",
+        "name": "ios_chrome_web_eg2tests_module_iPhone X 14.0",
         "resultdb": {
           "enable": false
         },
@@ -24294,7 +25360,7 @@
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
-        "test_id_prefix": "ninja://ios/components:ios_components_unittests/"
+        "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/"
       },
       {
         "args": [
@@ -24349,7 +25415,7 @@
           "--platform",
           "iPhone 6s",
           "--version",
-          "12.4",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -24358,13 +25424,13 @@
           "12a7209",
           "--xctest"
         ],
-        "isolate_name": "ios_net_unittests",
+        "isolate_name": "ios_components_unittests",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_net_unittests_iPhone 6s 12.4",
+        "name": "ios_components_unittests_iPhone 6s 14.0",
         "resultdb": {
           "enable": false
         },
@@ -24390,7 +25456,7 @@
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
-        "test_id_prefix": "ninja://ios/net:ios_net_unittests/"
+        "test_id_prefix": "ninja://ios/components:ios_components_unittests/"
       },
       {
         "args": [
@@ -24445,7 +25511,7 @@
           "--platform",
           "iPhone 6s",
           "--version",
-          "12.4",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -24454,13 +25520,13 @@
           "12a7209",
           "--xctest"
         ],
-        "isolate_name": "ios_remoting_unittests",
+        "isolate_name": "ios_net_unittests",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_remoting_unittests_iPhone 6s 12.4",
+        "name": "ios_net_unittests_iPhone 6s 14.0",
         "resultdb": {
           "enable": false
         },
@@ -24486,7 +25552,7 @@
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
-        "test_id_prefix": "ninja://remoting/ios:ios_remoting_unittests/"
+        "test_id_prefix": "ninja://ios/net:ios_net_unittests/"
       },
       {
         "args": [
@@ -24539,9 +25605,57 @@
       {
         "args": [
           "--platform",
+          "iPhone 6s",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "ios_remoting_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_remoting_unittests_iPhone 6s 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://remoting/ios:ios_remoting_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPad Air 2",
           "--version",
-          "12.4",
+          "13.6",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -24557,7 +25671,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_showcase_eg2tests_module_iPad Air 2 12.4",
+        "name": "ios_showcase_eg2tests_module_iPad Air 2 13.6",
         "resultdb": {
           "enable": false
         },
@@ -24590,7 +25704,7 @@
           "--platform",
           "iPad Air 2",
           "--version",
-          "13.6",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -24606,7 +25720,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_showcase_eg2tests_module_iPad Air 2 13.6",
+        "name": "ios_showcase_eg2tests_module_iPad Air 2 14.0",
         "resultdb": {
           "enable": false
         },
@@ -24686,9 +25800,9 @@
       {
         "args": [
           "--platform",
-          "iPhone X",
+          "iPhone 7",
           "--version",
-          "12.4",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -24704,7 +25818,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_showcase_eg2tests_module_iPhone X 12.4",
+        "name": "ios_showcase_eg2tests_module_iPhone 7 14.0",
         "resultdb": {
           "enable": false
         },
@@ -24784,9 +25898,58 @@
       {
         "args": [
           "--platform",
+          "iPhone X",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest",
+          "--xcode-parallelization"
+        ],
+        "isolate_name": "ios_showcase_eg2tests_module",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_showcase_eg2tests_module_iPhone X 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 6s",
           "--version",
-          "12.4",
+          "13.6",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -24801,7 +25964,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_testing_unittests_iPhone 6s 12.4",
+        "name": "ios_testing_unittests_iPhone 6s 13.6",
         "resultdb": {
           "enable": false
         },
@@ -24834,7 +25997,7 @@
           "--platform",
           "iPhone 6s",
           "--version",
-          "13.6",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -24849,7 +26012,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_testing_unittests_iPhone 6s 13.6",
+        "name": "ios_testing_unittests_iPhone 6s 14.0",
         "resultdb": {
           "enable": false
         },
@@ -24928,6 +26091,54 @@
       {
         "args": [
           "--platform",
+          "iPad Air 2",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_inttests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_inttests_iPad Air 2 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web:ios_web_inttests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 6s",
           "--version",
           "13.6",
@@ -24976,6 +26187,54 @@
       {
         "args": [
           "--platform",
+          "iPhone 6s",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_inttests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_inttests_iPhone 6s 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web:ios_web_inttests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 6s Plus",
           "--version",
           "13.6",
@@ -25024,6 +26283,54 @@
       {
         "args": [
           "--platform",
+          "iPhone 6s Plus",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_inttests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_inttests_iPhone 6s Plus 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web:ios_web_inttests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone SE (1st generation)",
           "--version",
           "13.6",
@@ -25072,25 +26379,24 @@
       {
         "args": [
           "--platform",
-          "iPad Air 2",
+          "iPhone SE (1st generation)",
           "--version",
-          "12.4",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
           "12a7209",
-          "--xctest",
-          "--xcode-parallelization"
+          "--xctest"
         ],
-        "isolate_name": "ios_web_shell_eg2tests_module",
+        "isolate_name": "ios_web_inttests",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_web_shell_eg2tests_module_iPad Air 2 12.4",
+        "name": "ios_web_inttests_iPhone SE (1st generation) 14.0",
         "resultdb": {
           "enable": false
         },
@@ -25116,7 +26422,7 @@
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
-        "test_id_prefix": "ninja://ios/web/shell/test:ios_web_shell_eg2tests_module/"
+        "test_id_prefix": "ninja://ios/web:ios_web_inttests/"
       },
       {
         "args": [
@@ -25170,9 +26476,9 @@
       {
         "args": [
           "--platform",
-          "iPhone 6s",
+          "iPad Air 2",
           "--version",
-          "12.4",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -25188,7 +26494,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "ios_web_shell_eg2tests_module_iPhone 6s 12.4",
+        "name": "ios_web_shell_eg2tests_module_iPad Air 2 14.0",
         "resultdb": {
           "enable": false
         },
@@ -25268,6 +26574,55 @@
       {
         "args": [
           "--platform",
+          "iPhone 6s",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest",
+          "--xcode-parallelization"
+        ],
+        "isolate_name": "ios_web_shell_eg2tests_module",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_shell_eg2tests_module_iPhone 6s 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web/shell/test:ios_web_shell_eg2tests_module/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 7",
           "--version",
           "13.6",
@@ -25317,6 +26672,55 @@
       {
         "args": [
           "--platform",
+          "iPhone 7",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest",
+          "--xcode-parallelization"
+        ],
+        "isolate_name": "ios_web_shell_eg2tests_module",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_shell_eg2tests_module_iPhone 7 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web/shell/test:ios_web_shell_eg2tests_module/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPad Air 2",
           "--version",
           "13.6",
@@ -25365,6 +26769,54 @@
       {
         "args": [
           "--platform",
+          "iPad Air 2",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_unittests_iPad Air 2 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web:ios_web_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 6s",
           "--version",
           "13.6",
@@ -25413,6 +26865,54 @@
       {
         "args": [
           "--platform",
+          "iPhone 6s",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_unittests_iPhone 6s 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web:ios_web_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 6s Plus",
           "--version",
           "13.6",
@@ -25461,6 +26961,54 @@
       {
         "args": [
           "--platform",
+          "iPhone 6s Plus",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_unittests_iPhone 6s Plus 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web:ios_web_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone SE (1st generation)",
           "--version",
           "13.6",
@@ -25509,6 +27057,54 @@
       {
         "args": [
           "--platform",
+          "iPhone SE (1st generation)",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_unittests_iPhone SE (1st generation) 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web:ios_web_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPad Air 2",
           "--version",
           "13.6",
@@ -25557,6 +27153,54 @@
       {
         "args": [
           "--platform",
+          "iPad Air 2",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_view_inttests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_view_inttests_iPad Air 2 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 6s",
           "--version",
           "13.6",
@@ -25605,6 +27249,54 @@
       {
         "args": [
           "--platform",
+          "iPhone 6s",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_view_inttests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_view_inttests_iPhone 6s 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 6s Plus",
           "--version",
           "13.6",
@@ -25653,6 +27345,54 @@
       {
         "args": [
           "--platform",
+          "iPhone 6s Plus",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_view_inttests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_view_inttests_iPhone 6s Plus 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone SE (1st generation)",
           "--version",
           "13.6",
@@ -25701,6 +27441,54 @@
       {
         "args": [
           "--platform",
+          "iPhone SE (1st generation)",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_view_inttests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_view_inttests_iPhone SE (1st generation) 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPad Air 2",
           "--version",
           "13.6",
@@ -25749,6 +27537,54 @@
       {
         "args": [
           "--platform",
+          "iPad Air 2",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_view_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_view_unittests_iPad Air 2 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 6s",
           "--version",
           "13.6",
@@ -25797,6 +27633,54 @@
       {
         "args": [
           "--platform",
+          "iPhone 6s",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_view_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_view_unittests_iPhone 6s 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 6s Plus",
           "--version",
           "13.6",
@@ -25845,6 +27729,54 @@
       {
         "args": [
           "--platform",
+          "iPhone 6s Plus",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "ios_web_view_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ios_web_view_unittests_iPhone 6s Plus 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone SE (1st generation)",
           "--version",
           "13.6",
@@ -25893,9 +27825,9 @@
       {
         "args": [
           "--platform",
-          "iPhone 6s",
+          "iPhone SE (1st generation)",
           "--version",
-          "12.4",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -25904,13 +27836,13 @@
           "12a7209",
           "--xctest"
         ],
-        "isolate_name": "net_unittests",
+        "isolate_name": "ios_web_view_unittests",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "net_unittests_iPhone 6s 12.4",
+        "name": "ios_web_view_unittests_iPhone SE (1st generation) 14.0",
         "resultdb": {
           "enable": false
         },
@@ -25936,7 +27868,7 @@
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
         },
-        "test_id_prefix": "ninja://net:net_unittests/"
+        "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/"
       },
       {
         "args": [
@@ -25991,7 +27923,55 @@
           "--platform",
           "iPhone 6s",
           "--version",
-          "12.4",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "net_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "net_unittests_iPhone 6s 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://net:net_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone 6s",
+          "--version",
+          "13.6",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -26006,7 +27986,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "services_unittests_iPhone 6s 12.4",
+        "name": "services_unittests_iPhone 6s 13.6",
         "resultdb": {
           "enable": false
         },
@@ -26039,7 +28019,7 @@
           "--platform",
           "iPhone 6s",
           "--version",
-          "13.6",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -26054,7 +28034,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "services_unittests_iPhone 6s 13.6",
+        "name": "services_unittests_iPhone 6s 14.0",
         "resultdb": {
           "enable": false
         },
@@ -26133,6 +28113,54 @@
       {
         "args": [
           "--platform",
+          "iPad Air 2",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "skia_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "skia_unittests_iPad Air 2 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://skia:skia_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 6s",
           "--version",
           "13.6",
@@ -26181,6 +28209,54 @@
       {
         "args": [
           "--platform",
+          "iPhone 6s",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "skia_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "skia_unittests_iPhone 6s 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://skia:skia_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 6s Plus",
           "--version",
           "13.6",
@@ -26229,6 +28305,54 @@
       {
         "args": [
           "--platform",
+          "iPhone 6s Plus",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "skia_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "skia_unittests_iPhone 6s Plus 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://skia:skia_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone SE (1st generation)",
           "--version",
           "13.6",
@@ -26277,9 +28401,57 @@
       {
         "args": [
           "--platform",
+          "iPhone SE (1st generation)",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "skia_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "skia_unittests_iPhone SE (1st generation) 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://skia:skia_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 6s",
           "--version",
-          "12.4",
+          "13.6",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -26294,7 +28466,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "sql_unittests_iPhone 6s 12.4",
+        "name": "sql_unittests_iPhone 6s 13.6",
         "resultdb": {
           "enable": false
         },
@@ -26327,7 +28499,7 @@
           "--platform",
           "iPhone 6s",
           "--version",
-          "13.6",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -26342,7 +28514,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "sql_unittests_iPhone 6s 13.6",
+        "name": "sql_unittests_iPhone 6s 14.0",
         "resultdb": {
           "enable": false
         },
@@ -26421,6 +28593,54 @@
       {
         "args": [
           "--platform",
+          "iPad Air 2",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "ui_base_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ui_base_unittests_iPad Air 2 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ui/base:ui_base_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 6s",
           "--version",
           "13.6",
@@ -26469,6 +28689,54 @@
       {
         "args": [
           "--platform",
+          "iPhone 6s",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "ui_base_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ui_base_unittests_iPhone 6s 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ui/base:ui_base_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 6s Plus",
           "--version",
           "13.6",
@@ -26517,6 +28785,54 @@
       {
         "args": [
           "--platform",
+          "iPhone 6s Plus",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "ui_base_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ui_base_unittests_iPhone 6s Plus 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ui/base:ui_base_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone SE (1st generation)",
           "--version",
           "13.6",
@@ -26565,9 +28881,57 @@
       {
         "args": [
           "--platform",
+          "iPhone SE (1st generation)",
+          "--version",
+          "14.0",
+          "--args-json",
+          "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "12a7209",
+          "--xctest"
+        ],
+        "isolate_name": "ui_base_unittests",
+        "isolate_profile_data": true,
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "ui_base_unittests_iPhone SE (1st generation) 14.0",
+        "resultdb": {
+          "enable": false
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:796d2b92cff93fc2059623ce0a66284373ceea0a"
+            }
+          ],
+          "dimension_sets": [
+            {
+              "os": "Mac-10.15"
+            }
+          ],
+          "named_caches": [
+            {
+              "name": "xcode_ios_12a7209",
+              "path": "Xcode.app"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://ui/base:ui_base_unittests/"
+      },
+      {
+        "args": [
+          "--platform",
           "iPhone 6s",
           "--version",
-          "12.4",
+          "13.6",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -26582,7 +28946,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "url_unittests_iPhone 6s 12.4",
+        "name": "url_unittests_iPhone 6s 13.6",
         "resultdb": {
           "enable": false
         },
@@ -26615,7 +28979,7 @@
           "--platform",
           "iPhone 6s",
           "--version",
-          "13.6",
+          "14.0",
           "--args-json",
           "{\"test_args\": [\"--write-compiled-tests-json-to-writable-path\"]}",
           "--out-dir",
@@ -26630,7 +28994,7 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
         },
-        "name": "url_unittests_iPhone 6s 13.6",
+        "name": "url_unittests_iPhone 6s 14.0",
         "resultdb": {
           "enable": false
         },
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index 6ff695e..0f3e5ec 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -1722,11 +1722,6 @@
         },
       },
     },
-    'remove_from': [
-      # TODO(crbug.com/1137405): Re-enable once the test harness supports
-      # the --avd-config flag.
-      'android-marshmallow-x86-rel-non-cq',
-    ],
   },
   'monochrome_public_test_ar_apk': {
     'modifications': {
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index c1e515d..cb47e93 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -3426,6 +3426,7 @@
         },
       },
       'lacros_chrome_browsertests': {},
+      'ui_base_unittests': {},
       'unit_tests': {},
     },
 
@@ -5748,31 +5749,35 @@
       }
     },
 
+    # This suite is a union of ios_simulator_tests and
+    # ios_simulator_full_configs_tests.
     'ios_code_coverage_tests': {
       'ios_common_tests': {
         'variants': [
-          'SIM_IPHONE_6S_12_4',
           'SIM_IPHONE_6S_13_6',
+          'SIM_IPHONE_6S_14_0',
         ],
       },
       'ios_eg2_cq_tests': {
         'mixins': ['xcode_parallelization'],
         'variants': [
-          'SIM_IPHONE_6S_12_4',
-          'SIM_IPAD_AIR_2_12_4',
           'SIM_IPHONE_6S_13_6',
           'SIM_IPHONE_7_13_6',
           'SIM_IPAD_AIR_2_13_6',
+          'SIM_IPHONE_6S_14_0',
+          'SIM_IPHONE_7_14_0',
+          'SIM_IPAD_AIR_2_14_0',
         ],
       },
       'ios_eg2_tests': {
         'mixins': ['xcode_parallelization'],
         'variants': [
-          'SIM_IPAD_AIR_2_12_4',
-          'SIM_IPHONE_X_12_4',
           'SIM_IPHONE_7_13_6',
           'SIM_IPAD_AIR_2_13_6',
           'SIM_IPHONE_X_13_6',
+          'SIM_IPHONE_7_14_0',
+          'SIM_IPAD_AIR_2_14_0',
+          'SIM_IPHONE_X_14_0',
         ],
       },
       'ios_screen_size_dependent_tests': {
@@ -5780,7 +5785,11 @@
           'SIM_IPHONE_6S_PLUS_13_6',
           'SIM_IPHONE_6S_13_6',
           'SIM_IPHONE_SE_1ST_GEN_13_6',
-          'SIM_IPAD_AIR_2_13_6'
+          'SIM_IPAD_AIR_2_13_6',
+          'SIM_IPHONE_6S_PLUS_14_0',
+          'SIM_IPHONE_6S_14_0',
+          'SIM_IPHONE_SE_1ST_GEN_14_0',
+          'SIM_IPAD_AIR_2_14_0',
         ],
       },
     },
@@ -5794,7 +5803,8 @@
       }
     },
 
-    'ios_simulator_full_configs_test': {
+    # Please also change ios_code_coverage_tests for any change in this suite.
+    'ios_simulator_full_configs_tests': {
       'ios_eg2_tests': {
         'mixins': ['xcode_parallelization'],
         'variants': [
@@ -5870,6 +5880,7 @@
       },
     },
 
+    # Please also change ios_code_coverage_tests for any change in this suite.
     'ios_simulator_tests': {
       'ios_common_tests': {
         'variants': [
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index b8caa2f..55657d6 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -314,6 +314,29 @@
       '--client-outdir',
       '.',
       '--implementation-outdir',
+      '../../weblayer_instrumentation_test_M87/out/Release',
+      '--test-expectations',
+      '../../weblayer/browser/android/javatests/skew/expectations.txt',
+      '--impl-version=87',
+    ],
+    'identifier': 'M87_Implementation_Library_Tests',
+    'swarming': {
+      'cipd_packages': [
+        {
+          'cipd_package': 'chromium/testing/weblayer-x86',
+          'location': 'weblayer_instrumentation_test_M87',
+          'revision': 'version:87.0.4280.20',
+        }
+      ],
+    },
+  },
+  'WEBLAYER_IMPL_SKEW_TESTS_NTH_MINUS_ONE_MILESTONE': {
+    'args': [
+      '--test-runner-outdir',
+      '.',
+      '--client-outdir',
+      '.',
+      '--implementation-outdir',
       '../../weblayer_instrumentation_test_M86/out/Release',
       '--test-expectations',
       '../../weblayer/browser/android/javatests/skew/expectations.txt',
@@ -330,7 +353,7 @@
       ],
     },
   },
-  'WEBLAYER_IMPL_SKEW_TESTS_NTH_MINUS_ONE_MILESTONE': {
+  'WEBLAYER_IMPL_SKEW_TESTS_NTH_MINUS_TWO_MILESTONE': {
     'args': [
       '--test-runner-outdir',
       '.',
@@ -353,30 +376,30 @@
       ],
     },
   },
-  'WEBLAYER_IMPL_SKEW_TESTS_NTH_MINUS_TWO_MILESTONE': {
+  'WEBLAYER_CLIENT_SKEW_TESTS_NTH_MILESTONE': {
     'args': [
       '--test-runner-outdir',
       '.',
       '--client-outdir',
-      '.',
+      '../../weblayer_instrumentation_test_M87/out/Release',
       '--implementation-outdir',
-      '../../weblayer_instrumentation_test_M84/out/Release',
+      '.',
       '--test-expectations',
       '../../weblayer/browser/android/javatests/skew/expectations.txt',
-      '--impl-version=84',
+      '--client-version=87',
     ],
-    'identifier': 'M84_Implementation_Library_Tests',
+    'identifier': 'M87_Client_Library_Tests',
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
-          'location': 'weblayer_instrumentation_test_M84',
-          'revision': 'version:dup-84.0.4147.89',
+          'location': 'weblayer_instrumentation_test_M87',
+          'revision': 'version:87.0.4280.20',
         }
       ],
     },
   },
-  'WEBLAYER_CLIENT_SKEW_TESTS_NTH_MILESTONE': {
+  'WEBLAYER_CLIENT_SKEW_TESTS_NTH_MINUS_ONE_MILESTONE': {
     'args': [
       '--test-runner-outdir',
       '.',
@@ -399,7 +422,7 @@
       ],
     },
   },
-  'WEBLAYER_CLIENT_SKEW_TESTS_NTH_MINUS_ONE_MILESTONE': {
+  'WEBLAYER_CLIENT_SKEW_TESTS_NTH_MINUS_TWO_MILESTONE': {
     'args': [
       '--test-runner-outdir',
       '.',
@@ -417,30 +440,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M85',
-          'revision': 'version:85.0.4183.81',
-        }
-      ],
-    },
-  },
-  'WEBLAYER_CLIENT_SKEW_TESTS_NTH_MINUS_TWO_MILESTONE': {
-    'args': [
-      '--test-runner-outdir',
-      '.',
-      '--client-outdir',
-      '../../weblayer_instrumentation_test_M84/out/Release',
-      '--implementation-outdir',
-      '.',
-      '--test-expectations',
-      '../../weblayer/browser/android/javatests/skew/expectations.txt',
-      '--client-version=84',
-    ],
-    'identifier': 'M84_Client_Library_Tests',
-    'swarming': {
-      'cipd_packages': [
-        {
-          'cipd_package': 'chromium/testing/weblayer-x86',
-          'location': 'weblayer_instrumentation_test_M84',
-          'revision': 'version:dup-84.0.4147.89',
+          'revision': 'version:85.0.4183.140',
         }
       ],
     },
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index d633323..31e9536 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -4761,7 +4761,7 @@
           'xctest',
         ],
         'test_suites': {
-          'isolated_scripts': 'ios_simulator_full_configs_test'
+          'isolated_scripts': 'ios_simulator_full_configs_tests'
         },
       },
       'ios-simulator-noncq': {
diff --git a/testing/coverage_util_ios.mm b/testing/coverage_util_ios.mm
index c148b2f..53e1350 100644
--- a/testing/coverage_util_ios.mm
+++ b/testing/coverage_util_ios.mm
@@ -28,8 +28,9 @@
             .environment[@"SIMULATOR_SHARED_RESOURCES_DIRECTORY"];
     // UUID ensures that there won't be a conflict when multiple apps are
     // launched in one test suite in EG2. %m enables on-line profile merging.
-    NSString* file_name =
-        [NSString stringWithFormat:@"%@-%%m.profraw", NSUUID.UUID.UUIDString];
+    // %c helps preserve coverage data at crash.
+    NSString* file_name = [NSString
+        stringWithFormat:@"%@-%%m-%%c.profraw", NSUUID.UUID.UUIDString];
     NSString* file_path =
         [shared_resources_path stringByAppendingPathComponent:file_name];
 
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index fd4cbde..940ec87 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -1304,6 +1304,21 @@
             ]
         }
     ],
+    "ButterForPayments": [
+        {
+            "platforms": [
+                "android"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "AutofillEnableAccountWalletStorage"
+                    ]
+                }
+            ]
+        }
+    ],
     "CSSMatchedPropertiesCacheDependencies": [
         {
             "platforms": [
@@ -6060,6 +6075,21 @@
             ]
         }
     ],
+    "SafeBrowsingDelayedWarnings": [
+        {
+            "platforms": [
+                "android"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "SafeBrowsingDelayedWarnings"
+                    ]
+                }
+            ]
+        }
+    ],
     "SafeBrowsingEnhancedProtectionAndroid": [
         {
             "platforms": [
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
index 878fd2cc..172680c 100644
--- a/third_party/blink/common/features.cc
+++ b/third_party/blink/common/features.cc
@@ -288,8 +288,7 @@
 const base::Feature kAllowSyncXHRInPageDismissal{
     "AllowSyncXHRInPageDismissal", base::FEATURE_DISABLED_BY_DEFAULT};
 
-// Font enumeration and table access. https://crbug.com/535764 and
-// https://crbug.com/982054.
+// Font enumeration and data access. https://crbug.com/535764
 const base::Feature kFontAccess{"FontAccess",
                                 base::FEATURE_DISABLED_BY_DEFAULT};
 
diff --git a/third_party/blink/public/mojom/frame/user_activation_notification_type.mojom b/third_party/blink/public/mojom/frame/user_activation_notification_type.mojom
index 7e6f3b1..bf7ef0d5 100644
--- a/third_party/blink/public/mojom/frame/user_activation_notification_type.mojom
+++ b/third_party/blink/public/mojom/frame/user_activation_notification_type.mojom
@@ -24,7 +24,9 @@
   // An extension API caused the notification call through GuestView.
   kExtensionGuestView,
 
-  // An extension messaging API caused the notification call.
+  // An extension messaging API caused the notification call.  This enum value
+  // is deprecated by more specific enums kExtensionMessaging* below, we are
+  // preserving this enum value only for UMA consistency.
   kExtensionMessaging,
 
   // A media API caused the notification call.
@@ -47,5 +49,24 @@
   kWebScriptExec,
 
   // Android voice search API caused the notification call.
-  kVoiceSearch
+  kVoiceSearch,
+
+  // An extension messaging API caused the notification call, where the script
+  // contexts of both the sender and the receiver of the message are privileged.
+  kExtensionMessagingBothPrivileged,
+
+  // An extension messaging API caused the notification call, where the script
+  // context of only the sender (and not the receiver) of the message is
+  // privileged.
+  kExtensionMessagingSenderPrivileged,
+
+  // An extension messaging API caused the notification call, where the script
+  // context of only the receiver (and not the sender) of the message is
+  // privileged.
+  kExtensionMessagingReceiverPrivileged,
+
+  // An extension messaging API caused the notification call, where the script
+  // context of neither the sender nor the receiver of the message is
+  // privileged.
+  kExtensionMessagingNeitherPrivileged
 };
diff --git a/third_party/blink/public/platform/web_media_player.h b/third_party/blink/public/platform/web_media_player.h
index 9a7e50a..4a558587 100644
--- a/third_party/blink/public/platform/web_media_player.h
+++ b/third_party/blink/public/platform/web_media_player.h
@@ -31,6 +31,7 @@
 #ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_MEDIA_PLAYER_H_
 #define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_MEDIA_PLAYER_H_
 
+#include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "base/time/time.h"
 #include "components/viz/common/surfaces/surface_id.h"
@@ -54,6 +55,10 @@
 }
 }
 
+namespace media {
+class VideoFrame;
+}
+
 namespace blink {
 
 class WebContentDecryptionModule;
@@ -263,6 +268,12 @@
                      int already_uploaded_id = -1,
                      VideoFrameUploadMetadata* out_metadata = nullptr) = 0;
 
+  // Similar to Paint(), but just returns the frame directly instead of trying
+  // to upload or convert it. Note: This may kick off a process to update the
+  // current frame for a future call in some cases. Returns nullptr if no frame
+  // is available.
+  virtual scoped_refptr<media::VideoFrame> GetCurrentFrame() = 0;
+
   // Do a GPU-GPU texture copy of the current video frame to |texture|,
   // reallocating |texture| at the appropriate size with given internal
   // format, format, and type if necessary.
diff --git a/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h b/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h
index 7166dbc4..2ff0dea6 100644
--- a/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h
+++ b/third_party/blink/public/web/modules/mediastream/webmediaplayer_ms.h
@@ -128,6 +128,7 @@
              cc::PaintFlags& flags,
              int already_uploaded_id,
              VideoFrameUploadMetadata* out_metadata) override;
+  scoped_refptr<media::VideoFrame> GetCurrentFrame() override;
   media::PaintCanvasVideoRenderer* GetPaintCanvasVideoRenderer();
   void ResetCanvasCache();
 
diff --git a/third_party/blink/public/web/web_frame_widget.h b/third_party/blink/public/web/web_frame_widget.h
index 8071d35..445132b 100644
--- a/third_party/blink/public/web/web_frame_widget.h
+++ b/third_party/blink/public/web/web_frame_widget.h
@@ -206,6 +206,10 @@
   // See https://github.com/webscreens/window-segments/blob/master/EXPLAINER.md
   virtual const WebVector<gfx::Rect>& WindowSegments() const = 0;
 
+  // Release any mouse lock or pointer capture held. This is used to reset
+  // state between WebTest runs.
+  virtual void ReleaseMouseLockAndPointerCaptureForTesting() = 0;
+
  private:
   // This private constructor and the class/friend declaration ensures that
   // WebFrameWidgetBase is the only concrete subclass that implements
diff --git a/third_party/blink/public/web/web_plugin.h b/third_party/blink/public/web/web_plugin.h
index d83814b..d768ca3 100644
--- a/third_party/blink/public/web/web_plugin.h
+++ b/third_party/blink/public/web/web_plugin.h
@@ -255,6 +255,13 @@
   // it loading later.
   virtual bool IsErrorPlaceholder() { return false; }
 
+  // Indication that a current mouse lock has been lost.
+  virtual void DidLoseMouseLock() {}
+
+  // A response has been received from a previous WebPluginContainer::LockMouse
+  // call.
+  virtual void DidReceiveMouseLockResult(bool success) {}
+
  protected:
   virtual ~WebPlugin() = default;
 };
diff --git a/third_party/blink/public/web/web_plugin_container.h b/third_party/blink/public/web/web_plugin_container.h
index e41dfebb..1c71ed2 100644
--- a/third_party/blink/public/web/web_plugin_container.h
+++ b/third_party/blink/public/web/web_plugin_container.h
@@ -157,6 +157,16 @@
   // Returns true if this container was the target for the last mouse event.
   virtual bool WasTargetForLastMouseEvent() = 0;
 
+  // Whether this plugin current has the mouse lock or not.
+  virtual bool IsMouseLocked() = 0;
+
+  // Request to lock the mouse. A subsequent callback on
+  // WebPlugin::DidReceiveMouseLockResult will be called.
+  virtual bool LockMouse(bool request_unadjusted_movement) = 0;
+
+  // Request to unlock a current mouse lock.
+  virtual void UnlockMouse() = 0;
+
  protected:
   ~WebPluginContainer() = default;
 };
diff --git a/third_party/blink/public/web/web_widget.h b/third_party/blink/public/web/web_widget.h
index 5eaf757..c0ed2ae4 100644
--- a/third_party/blink/public/web/web_widget.h
+++ b/third_party/blink/public/web/web_widget.h
@@ -148,9 +148,6 @@
     return WebInputEventResult::kNotHandled;
   }
 
-  // Called to inform the WebWidget that mouse capture was lost.
-  virtual void MouseCaptureLost() {}
-
   // Called to inform the WebWidget of the mouse cursor's visibility.
   virtual void SetCursorVisibilityState(bool is_visible) {}
 
@@ -160,16 +157,6 @@
   // Returns the state of focus for the WebWidget.
   virtual bool HasFocus() { return false; }
 
-  // Calling WebWidgetClient::requestPointerLock() will result in one
-  // return call to didAcquirePointerLock() or didNotAcquirePointerLock().
-  virtual void DidAcquirePointerLock() {}
-  virtual void DidNotAcquirePointerLock() {}
-
-  // Pointer lock was held, but has been lost. This may be due to a
-  // request via WebWidgetClient::requestPointerUnlock(), or for other
-  // reasons such as the user exiting lock, window focus changing, etc.
-  virtual void DidLosePointerLock() {}
-
   // Accessor to the WebWidget scheduing state.
   virtual scheduler::WebRenderWidgetSchedulingState*
   RendererWidgetSchedulingState() = 0;
@@ -207,16 +194,6 @@
   // updated state will be sent to the browser.
   virtual void UpdateTextInputState() = 0;
 
-  // Request Mouse Lock. This can be removed eventually when the mouse lock
-  // dispatcher is moved into blink.
-  virtual void RequestMouseLock(
-      bool has_transient_user_activation,
-      bool request_unadjusted_movement,
-      base::OnceCallback<
-          void(mojom::PointerLockResult,
-               CrossVariantMojoRemote<mojom::PointerLockContextInterfaceBase>)>
-          callback) = 0;
-
   // Flush any pending input.
   virtual void FlushInputProcessedCallback() = 0;
 
diff --git a/third_party/blink/public/web/web_widget_client.h b/third_party/blink/public/web/web_widget_client.h
index 13f7cce6..b0387c1 100644
--- a/third_party/blink/public/web/web_widget_client.h
+++ b/third_party/blink/public/web/web_widget_client.h
@@ -68,9 +68,6 @@
 
 namespace blink {
 class WebDragData;
-class WebMouseEvent;
-class WebWidget;
-class WebLocalFrame;
 class WebString;
 
 class WebWidgetClient {
@@ -113,33 +110,6 @@
     return nullptr;
   }
 
-  // Requests to lock the mouse cursor for the |requester_frame| in the
-  // widget. If true is returned, the success result will be asynchronously
-  // returned via a single call to WebWidget::didAcquirePointerLock() or
-  // WebWidget::didNotAcquirePointerLock() and a single call to the callback.
-  // If false, the request has been denied synchronously.
-  using PointerLockCallback =
-      base::OnceCallback<void(mojom::PointerLockResult)>;
-  virtual bool RequestPointerLock(WebLocalFrame* requester_frame,
-                                  PointerLockCallback callback,
-                                  bool request_unadjusted_movement) {
-    return false;
-  }
-
-  virtual bool RequestPointerLockChange(WebLocalFrame* requester_frame,
-                                        PointerLockCallback callback,
-                                        bool request_unadjusted_movement) {
-    return false;
-  }
-
-  // Cause the pointer lock to be released. This may be called at any time,
-  // including when a lock is pending but not yet acquired.
-  // WebWidget::didLosePointerLock() is called when unlock is complete.
-  virtual void RequestPointerUnlock() {}
-
-  // Returns true iff the pointer is locked to this widget.
-  virtual bool IsPointerLocked() { return false; }
-
   // Called when a drag-and-drop operation should begin. Returns whether the
   // call has been handled.
   virtual bool InterceptStartDragging(const WebDragData&,
@@ -175,13 +145,6 @@
   // from background inactive to active.
   virtual void RecordTimeToFirstActivePaint(base::TimeDelta duration) {}
 
-  // Called before mouse events are processed and allows the
-  // client to handle the event itself. Return true if event was handled
-  // and further processing should stop.
-  virtual bool WillHandleMouseEvent(const WebMouseEvent& event) {
-    return false;
-  }
-
   // Determines whether composition can happen inline.
   virtual bool CanComposeInline() { return false; }
 
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index 4478cae59..58423ff 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -7411,7 +7411,7 @@
   if (Element* target = GetPage()->GetPointerLockController().GetElement()) {
     if (target->GetDocument() != this)
       return;
-    GetPage()->GetPointerLockController().RequestPointerUnlock();
+    GetPage()->GetPointerLockController().ExitPointerLock();
   }
 }
 
diff --git a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
index f07f04c..646e300 100644
--- a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
@@ -456,18 +456,6 @@
   widget_base_->CancelCompositionForPepper();
 }
 
-void WebPagePopupImpl::RequestMouseLock(
-    bool has_transient_user_activation,
-    bool request_unadjusted_movement,
-    base::OnceCallback<void(
-        mojom::blink::PointerLockResult,
-        CrossVariantMojoRemote<mojom::blink::PointerLockContextInterfaceBase>)>
-        callback) {
-  widget_base_->RequestMouseLock(has_transient_user_activation,
-                                 request_unadjusted_movement,
-                                 std::move(callback));
-}
-
 void WebPagePopupImpl::ApplyVisualProperties(
     const VisualProperties& visual_properties) {
   widget_base_->UpdateVisualProperties(visual_properties);
@@ -649,9 +637,7 @@
   return false;
 }
 
-bool WebPagePopupImpl::WillHandleMouseEvent(const WebMouseEvent& event) {
-  return WidgetClient()->WillHandleMouseEvent(event);
-}
+void WebPagePopupImpl::WillHandleMouseEvent(const WebMouseEvent& event) {}
 
 void WebPagePopupImpl::ObserveGestureEventAndResult(
     const WebGestureEvent& gesture_event,
diff --git a/third_party/blink/renderer/core/exported/web_page_popup_impl.h b/third_party/blink/renderer/core/exported/web_page_popup_impl.h
index 887e6e1..8debb93 100644
--- a/third_party/blink/renderer/core/exported/web_page_popup_impl.h
+++ b/third_party/blink/renderer/core/exported/web_page_popup_impl.h
@@ -122,7 +122,7 @@
   void SetSuppressFrameRequestsWorkaroundFor704763Only(bool) final;
   WebInputEventResult DispatchBufferedTouchEvents() override;
   bool WillHandleGestureEvent(const WebGestureEvent& event) override;
-  bool WillHandleMouseEvent(const WebMouseEvent& event) override;
+  void WillHandleMouseEvent(const WebMouseEvent& event) override;
   void ObserveGestureEventAndResult(
       const WebGestureEvent& gesture_event,
       const gfx::Vector2dF& unused_delta,
@@ -176,13 +176,6 @@
   void ShowVirtualKeyboard() override;
   void FlushInputProcessedCallback() override;
   void CancelCompositionForPepper() override;
-  void RequestMouseLock(
-      bool has_transient_user_activation,
-      bool request_unadjusted_movement,
-      base::OnceCallback<
-          void(mojom::blink::PointerLockResult,
-               CrossVariantMojoRemote<
-                   mojom::blink::PointerLockContextInterfaceBase>)>) override;
 
   // PageWidgetEventHandler functions
   WebInputEventResult HandleCharEvent(const WebKeyboardEvent&) override;
diff --git a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
index 430a1b0..53bf8ce 100644
--- a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
@@ -59,6 +59,7 @@
 #include "third_party/blink/renderer/core/clipboard/data_transfer.h"
 #include "third_party/blink/renderer/core/clipboard/system_clipboard.h"
 #include "third_party/blink/renderer/core/dom/dom_node_ids.h"
+#include "third_party/blink/renderer/core/dom/events/native_event_listener.h"
 #include "third_party/blink/renderer/core/events/drag_event.h"
 #include "third_party/blink/renderer/core/events/gesture_event.h"
 #include "third_party/blink/renderer/core/events/keyboard_event.h"
@@ -91,6 +92,7 @@
 #include "third_party/blink/renderer/core/page/chrome_client.h"
 #include "third_party/blink/renderer/core/page/focus_controller.h"
 #include "third_party/blink/renderer/core/page/page.h"
+#include "third_party/blink/renderer/core/page/pointer_lock_controller.h"
 #include "third_party/blink/renderer/core/paint/paint_layer.h"
 #include "third_party/blink/renderer/core/script/classic_script.h"
 #include "third_party/blink/renderer/core/scroll/scroll_animator_base.h"
@@ -122,6 +124,29 @@
 
 }  // namespace
 
+class WebPluginContainerImpl::MouseLockLostListener final
+    : public NativeEventListener {
+ public:
+  explicit MouseLockLostListener(WebPluginContainerImpl* plugin_container)
+      : plugin_container_(plugin_container) {}
+
+  void Disconnect() { plugin_container_ = nullptr; }
+
+  void Invoke(ExecutionContext*, Event*) override {
+    if (!plugin_container_)
+      return;
+    plugin_container_->MaybeLostMouseLock();
+  }
+
+  void Trace(Visitor* visitor) const override {
+    visitor->Trace(plugin_container_);
+    NativeEventListener::Trace(visitor);
+  }
+
+ private:
+  Member<WebPluginContainerImpl> plugin_container_;
+};
+
 // Public methods --------------------------------------------------------------
 
 void WebPluginContainerImpl::AttachToLayout() {
@@ -362,6 +387,50 @@
   Fullscreen::FullyExitFullscreen(element_->GetDocument());
 }
 
+bool WebPluginContainerImpl::IsMouseLocked() {
+  return element_->GetDocument().PointerLockElement() == element_;
+}
+
+bool WebPluginContainerImpl::LockMouse(bool request_unadjusted_movement) {
+  if (Page* page = element_->GetDocument().GetPage()) {
+    bool res = page->GetPointerLockController().RequestPointerLock(
+        element_, WTF::Bind(&WebPluginContainerImpl::HandleLockMouseResult,
+                            WrapWeakPersistent(this)));
+    if (res) {
+      mouse_lock_lost_listener_ =
+          MakeGarbageCollected<MouseLockLostListener>(this);
+      element_->GetDocument().addEventListener(
+          event_type_names::kPointerlockchange, mouse_lock_lost_listener_,
+          false);
+    }
+    return res;
+  }
+  return false;
+}
+
+void WebPluginContainerImpl::UnlockMouse() {
+  element_->GetDocument().exitPointerLock();
+}
+
+void WebPluginContainerImpl::HandleLockMouseResult(
+    mojom::blink::PointerLockResult result) {
+  web_plugin_->DidReceiveMouseLockResult(
+      result == mojom::blink::PointerLockResult::kSuccess);
+}
+
+void WebPluginContainerImpl::MaybeLostMouseLock() {
+  if (!IsMouseLocked()) {
+    if (mouse_lock_lost_listener_) {
+      mouse_lock_lost_listener_->Disconnect();
+      element_->GetDocument().removeEventListener(
+          event_type_names::kPointerlockchange, mouse_lock_lost_listener_,
+          false);
+      mouse_lock_lost_listener_ = nullptr;
+    }
+    web_plugin_->DidLoseMouseLock();
+  }
+}
+
 bool WebPluginContainerImpl::SupportsPaginatedPrint() const {
   return web_plugin_->SupportsPaginatedPrint();
 }
@@ -805,6 +874,7 @@
 
 void WebPluginContainerImpl::Trace(Visitor* visitor) const {
   visitor->Trace(element_);
+  visitor->Trace(mouse_lock_lost_listener_);
   ExecutionContextClient::Trace(visitor);
 }
 
diff --git a/third_party/blink/renderer/core/exported/web_plugin_container_impl.h b/third_party/blink/renderer/core/exported/web_plugin_container_impl.h
index d0083220..f304e679f 100644
--- a/third_party/blink/renderer/core/exported/web_plugin_container_impl.h
+++ b/third_party/blink/renderer/core/exported/web_plugin_container_impl.h
@@ -36,6 +36,7 @@
 #include "third_party/blink/public/common/input/web_coalesced_input_event.h"
 #include "third_party/blink/public/common/input/web_touch_event.h"
 #include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h"
+#include "third_party/blink/public/mojom/input/pointer_lock_result.mojom-blink-forward.h"
 #include "third_party/blink/public/web/web_plugin_container.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h"
@@ -134,27 +135,25 @@
   gfx::Point RootFrameToLocalPoint(const gfx::Point&) override;
   gfx::Point LocalToRootFramePoint(const gfx::Point&) override;
   bool WasTargetForLastMouseEvent() override;
-
   // Non-Oilpan, this cannot be null. With Oilpan, it will be
   // null when in a disposed state, pending finalization during the next GC.
   WebPlugin* Plugin() override { return web_plugin_; }
   void SetPlugin(WebPlugin*) override;
-
   void UsePluginAsFindHandler() override;
   void ReportFindInPageMatchCount(int identifier,
                                   int total,
                                   bool final_update) override;
   void ReportFindInPageSelection(int identifier, int index) override;
-
   float DeviceScaleFactor() override;
   float PageScaleFactor() override;
   float PageZoomFactor() override;
-
   void SetCcLayer(cc::Layer*, bool prevent_contents_opaque_changes) override;
-
   void RequestFullscreen() override;
   bool IsFullscreenElement() const override;
   void CancelFullscreen() override;
+  bool IsMouseLocked() override;
+  bool LockMouse(bool request_unadjusted_movement) override;
+  void UnlockMouse() override;
 
   // Printing interface. The plugin can support custom printing
   // (which means it controls the layout, number of pages etc).
@@ -194,6 +193,8 @@
   void SetFrameRect(const IntRect&) override;
   void PropagateFrameRects() override { ReportGeometry(); }
 
+  void MaybeLostMouseLock();
+
  protected:
   void ParentVisibleChanged() override;
 
@@ -221,6 +222,8 @@
   void HandleTouchEvent(TouchEvent&);
   void HandleGestureEvent(GestureEvent&);
 
+  void HandleLockMouseResult(mojom::blink::PointerLockResult result);
+
   void SynthesizeMouseEventIfPossible(TouchEvent&);
 
   void FocusPlugin();
@@ -230,8 +233,10 @@
                          IntRect& unobscured_rect);
 
   friend class WebPluginContainerTest;
+  class MouseLockLostListener;
 
   Member<HTMLPlugInElement> element_;
+  Member<MouseLockLostListener> mouse_lock_lost_listener_;
   WebPlugin* web_plugin_;
   cc::Layer* layer_;
   TouchEventRequestType touch_event_request_type_;
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
index 6268de9..2d883c2 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -2345,11 +2345,7 @@
       &CurrentInputEvent::current_input_event_, &input_event);
   UIEventWithKeyState::ClearNewTabModifierSetFromIsolatedWorld();
 
-  bool is_pointer_locked = false;
-  if (WebWidgetClient* client = widget->Client())
-    is_pointer_locked = client->IsPointerLocked();
-
-  if (is_pointer_locked &&
+  if (GetPage()->GetPointerLockController().IsPointerLocked() &&
       WebInputEvent::IsMouseEventType(input_event.GetType())) {
     widget->PointerLockMouseEvent(coalesced_event);
     return WebInputEventResult::kHandledSystem;
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_base.cc b/third_party/blink/renderer/core/frame/web_frame_widget_base.cc
index e00653aac..025ee1c3 100644
--- a/third_party/blink/renderer/core/frame/web_frame_widget_base.cc
+++ b/third_party/blink/renderer/core/frame/web_frame_widget_base.cc
@@ -596,23 +596,6 @@
   return frame_widget_host_.get();
 }
 
-void WebFrameWidgetBase::DidAcquirePointerLock() {
-  GetPage()->GetPointerLockController().DidAcquirePointerLock();
-
-  LocalFrame* focusedFrame = FocusedLocalFrameInWidget();
-  if (focusedFrame) {
-    focusedFrame->GetEventHandler().ReleaseMousePointerCapture();
-  }
-}
-
-void WebFrameWidgetBase::DidNotAcquirePointerLock() {
-  GetPage()->GetPointerLockController().DidNotAcquirePointerLock();
-}
-
-void WebFrameWidgetBase::DidLosePointerLock() {
-  GetPage()->GetPointerLockController().DidLosePointerLock();
-}
-
 void WebFrameWidgetBase::RequestDecode(
     const PaintImage& image,
     base::OnceCallback<void(bool)> callback) {
@@ -972,6 +955,12 @@
         event_type);
   }
 }
+bool WebFrameWidgetBase::IsPointerLocked() {
+  if (GetPage()) {
+    return GetPage()->GetPointerLockController().IsPointerLocked();
+  }
+  return false;
+}
 
 void WebFrameWidgetBase::ShowContextMenu(
     ui::mojom::blink::MenuSourceType source_type,
@@ -1068,11 +1057,10 @@
   return false;
 }
 
-bool WebFrameWidgetBase::WillHandleMouseEvent(const WebMouseEvent& event) {
+void WebFrameWidgetBase::WillHandleMouseEvent(const WebMouseEvent& event) {
   possible_drag_event_info_.source = ui::mojom::blink::DragEventSource::kMouse;
   possible_drag_event_info_.location =
       gfx::Point(event.PositionInScreen().x(), event.PositionInScreen().y());
-  return Client()->WillHandleMouseEvent(event);
 }
 
 void WebFrameWidgetBase::ObserveGestureEventAndResult(
@@ -1179,13 +1167,20 @@
 void WebFrameWidgetBase::RequestMouseLock(
     bool has_transient_user_activation,
     bool request_unadjusted_movement,
-    base::OnceCallback<void(
-        mojom::blink::PointerLockResult,
-        CrossVariantMojoRemote<mojom::blink::PointerLockContextInterfaceBase>)>
-        callback) {
-  widget_base_->RequestMouseLock(has_transient_user_activation,
-                                 request_unadjusted_movement,
-                                 std::move(callback));
+    mojom::blink::WidgetInputHandlerHost::RequestMouseLockCallback callback) {
+  mojom::blink::WidgetInputHandlerHost* host =
+      widget_base_->widget_input_handler_manager()->GetWidgetInputHandlerHost();
+
+  // If we don't have a host just leave the callback uncalled. This simulates
+  // the browser indefinitely postponing the mouse request which is valid.
+  // Note that |callback| is not a mojo bound callback (until it is passed
+  // into the mojo interface) and can be destructed without invoking the
+  // callback. It does share the same signature as the mojo definition
+  // for simplicity.
+  if (host) {
+    host->RequestMouseLock(has_transient_user_activation,
+                           request_unadjusted_movement, std::move(callback));
+  }
 }
 
 void WebFrameWidgetBase::ApplyVisualProperties(
@@ -2313,4 +2308,9 @@
   return {};
 }
 
+void WebFrameWidgetBase::ReleaseMouseLockAndPointerCaptureForTesting() {
+  GetPage()->GetPointerLockController().ExitPointerLock();
+  MouseCaptureLost();
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_base.h b/third_party/blink/renderer/core/frame/web_frame_widget_base.h
index d0573c42b..dc0169f9 100644
--- a/third_party/blink/renderer/core/frame/web_frame_widget_base.h
+++ b/third_party/blink/renderer/core/frame/web_frame_widget_base.h
@@ -236,6 +236,11 @@
   gfx::PointF DIPsToBlinkSpace(const gfx::PointF& point) override;
   gfx::Point DIPsToRoundedBlinkSpace(const gfx::Point& point) override;
   float DIPsToBlinkSpace(float scalar) override;
+  void RequestMouseLock(
+      bool has_transient_user_activation,
+      bool request_unadjusted_movement,
+      mojom::blink::WidgetInputHandlerHost::RequestMouseLockCallback callback)
+      override;
 
   // WebFrameWidget implementation.
   WebLocalFrame* LocalRoot() const override;
@@ -267,6 +272,7 @@
   void ClearEditCommands() override;
   bool IsPasting() override;
   bool HandlingSelectRange() override;
+  void ReleaseMouseLockAndPointerCaptureForTesting() override;
 
   // Called when a drag-n-drop operation should begin.
   void StartDragging(const WebDragData&,
@@ -288,9 +294,6 @@
       const cc::LayerTreeSettings* settings) override;
   void Close(
       scoped_refptr<base::SingleThreadTaskRunner> cleanup_runner) override;
-  void DidAcquirePointerLock() override;
-  void DidNotAcquirePointerLock() override;
-  void DidLosePointerLock() override;
   void SetCompositorVisible(bool visible) override;
   void SetCursor(const ui::Cursor& cursor) override;
   bool HandlingInputEvent() override;
@@ -304,13 +307,6 @@
   void SetFocus(bool focus) override;
   void FlushInputProcessedCallback() override;
   void CancelCompositionForPepper() override;
-  void RequestMouseLock(
-      bool has_transient_user_activation,
-      bool request_unadjusted_movement,
-      base::OnceCallback<
-          void(mojom::blink::PointerLockResult,
-               CrossVariantMojoRemote<
-                   mojom::blink::PointerLockContextInterfaceBase>)>) override;
   void ApplyVisualProperties(
       const VisualProperties& visual_properties) override;
   bool IsFullscreenGranted() override;
@@ -340,7 +336,7 @@
   void WillBeginMainFrame() override;
   void FocusChangeComplete() override;
   bool WillHandleGestureEvent(const WebGestureEvent& event) override;
-  bool WillHandleMouseEvent(const WebMouseEvent& event) override;
+  void WillHandleMouseEvent(const WebMouseEvent& event) override;
   void ObserveGestureEventAndResult(
       const WebGestureEvent& gesture_event,
       const gfx::Vector2dF& unused_delta,
@@ -602,6 +598,7 @@
 
   // Helper function to process events while pointer locked.
   void PointerLockMouseEvent(const WebCoalescedInputEvent&);
+  bool IsPointerLocked();
 
   virtual PageWidgetEventHandler* GetPageWidgetEventHandler() = 0;
 
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 cbb4ce9..cb43a7e 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
@@ -501,8 +501,7 @@
   base::AutoReset<const WebInputEvent*> current_event_change(
       &CurrentInputEvent::current_input_event_, &input_event);
 
-  DCHECK(Client());
-  if (Client()->IsPointerLocked() &&
+  if (IsPointerLocked() &&
       WebInputEvent::IsMouseEventType(input_event.GetType())) {
     PointerLockMouseEvent(coalesced_event);
     return WebInputEventResult::kHandledSystem;
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc
index cfa95c6..6e6654b 100644
--- a/third_party/blink/renderer/core/layout/layout_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -136,10 +136,11 @@
 
 LayoutUnit TextAreaIntrinsicInlineSize(const HTMLTextAreaElement& textarea,
                                        const LayoutBox& box) {
-  // <textarea>'s intrinsic inilne-size always contains the scrollbar thickness
-  // regardless of actual existence of a scrollbar. If a scrollbar exists, its
-  // thickness is not added.  See NGBlockLayoutAlgorithm::ComputeMinMaxSizes()
-  // and LayoutBlock::ComputeIntrinsicLogicalWidths().
+  // <textarea>'s intrinsic inline-size always contains the scrollbar thickness
+  // regardless of actual existence of a scrollbar.
+  //
+  // See |NGBlockLayoutAlgorithm::ComputeMinMaxSizes()| and |LayoutBlock::
+  // ComputeIntrinsicLogicalWidths()|.
   return LayoutUnit(ceilf(LayoutTextControl::GetAvgCharWidth(box.StyleRef()) *
                           textarea.cols())) +
          LayoutTextControl::ScrollbarThickness(box);
@@ -172,7 +173,7 @@
             spin_button ? spin_button->GetLayoutBox() : nullptr) {
       result += spin_box->BorderAndPaddingLogicalWidth();
       // Since the width of spin_box is not calculated yet,
-      // spin_layout_object->LogicalWidth() returns 0. Use the computed logical
+      // spin_box->LogicalWidth() returns 0. Use the computed logical
       // width instead.
       result += spin_box->StyleRef().LogicalWidth().Value();
     }
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_text_control_multi_line.h b/third_party/blink/renderer/core/layout/ng/layout_ng_text_control_multi_line.h
index 793ff08..94cfad8 100644
--- a/third_party/blink/renderer/core/layout/ng/layout_ng_text_control_multi_line.h
+++ b/third_party/blink/renderer/core/layout/ng/layout_ng_text_control_multi_line.h
@@ -9,7 +9,7 @@
 
 namespace blink {
 
-// LayoutNGTextControlSingleLine is a LayoutObject for <textarea>.
+// LayoutNGTextControlMultiLine is a LayoutObject for <textarea>.
 class LayoutNGTextControlMultiLine final : public LayoutNGBlockFlow {
  public:
   explicit LayoutNGTextControlMultiLine(Element* element);
diff --git a/third_party/blink/renderer/core/page/chrome_client.h b/third_party/blink/renderer/core/page/chrome_client.h
index 15509d50..768087b 100644
--- a/third_party/blink/renderer/core/page/chrome_client.h
+++ b/third_party/blink/renderer/core/page/chrome_client.h
@@ -431,21 +431,6 @@
 
   virtual bool IsSVGImageChromeClient() const { return false; }
 
-  virtual bool RequestPointerLock(LocalFrame*,
-                                  WebWidgetClient::PointerLockCallback callback,
-                                  bool request_unadjusted_movement) {
-    return false;
-  }
-
-  virtual bool RequestPointerLockChange(
-      LocalFrame*,
-      WebWidgetClient::PointerLockCallback callback,
-      bool request_unadjusted_movement) {
-    return false;
-  }
-
-  virtual void RequestPointerUnlock(LocalFrame*) {}
-
   virtual IntSize MinimumWindowSize() const { return IntSize(100, 100); }
 
   virtual bool IsChromeClientImpl() const { return false; }
diff --git a/third_party/blink/renderer/core/page/chrome_client_impl.cc b/third_party/blink/renderer/core/page/chrome_client_impl.cc
index ae6c53e..a9285992 100644
--- a/third_party/blink/renderer/core/page/chrome_client_impl.cc
+++ b/third_party/blink/renderer/core/page/chrome_client_impl.cc
@@ -1031,36 +1031,6 @@
   widget->ProcessTouchAction(touch_action);
 }
 
-bool ChromeClientImpl::RequestPointerLock(
-    LocalFrame* frame,
-    WebWidgetClient::PointerLockCallback callback,
-    bool request_unadjusted_movement) {
-  return WebLocalFrameImpl::FromFrame(frame)
-      ->LocalRootFrameWidget()
-      ->Client()
-      ->RequestPointerLock(WebLocalFrameImpl::FromFrame(frame),
-                           std::move(callback), request_unadjusted_movement);
-}
-
-bool ChromeClientImpl::RequestPointerLockChange(
-    LocalFrame* frame,
-    WebWidgetClient::PointerLockCallback callback,
-    bool request_unadjusted_movement) {
-  return WebLocalFrameImpl::FromFrame(frame)
-      ->LocalRootFrameWidget()
-      ->Client()
-      ->RequestPointerLockChange(WebLocalFrameImpl::FromFrame(frame),
-                                 std::move(callback),
-                                 request_unadjusted_movement);
-}
-
-void ChromeClientImpl::RequestPointerUnlock(LocalFrame* frame) {
-  return WebLocalFrameImpl::FromFrame(frame)
-      ->LocalRootFrameWidget()
-      ->Client()
-      ->RequestPointerUnlock();
-}
-
 void ChromeClientImpl::DidAssociateFormControlsAfterLoad(LocalFrame* frame) {
   if (auto* fill_client = AutofillClientFromFrame(frame))
     fill_client->DidAssociateFormControlsDynamically();
diff --git a/third_party/blink/renderer/core/page/chrome_client_impl.h b/third_party/blink/renderer/core/page/chrome_client_impl.h
index bd8c778..cab1134 100644
--- a/third_party/blink/renderer/core/page/chrome_client_impl.h
+++ b/third_party/blink/renderer/core/page/chrome_client_impl.h
@@ -235,14 +235,6 @@
       const String& dialog_message,
       Document::PageDismissalType) const override;
 
-  bool RequestPointerLock(LocalFrame*,
-                          WebWidgetClient::PointerLockCallback,
-                          bool) override;
-  bool RequestPointerLockChange(LocalFrame*,
-                                WebWidgetClient::PointerLockCallback,
-                                bool) override;
-  void RequestPointerUnlock(LocalFrame*) override;
-
   // AutofillClient pass throughs:
   void DidAssociateFormControlsAfterLoad(LocalFrame*) override;
   void HandleKeyboardEventOnTextField(HTMLInputElement&,
diff --git a/third_party/blink/renderer/core/page/pointer_lock_controller.cc b/third_party/blink/renderer/core/page/pointer_lock_controller.cc
index cfd288c..83cf68c 100644
--- a/third_party/blink/renderer/core/page/pointer_lock_controller.cc
+++ b/third_party/blink/renderer/core/page/pointer_lock_controller.cc
@@ -33,18 +33,39 @@
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/core/dom/element.h"
 #include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/input/event_handler.h"
 #include "third_party/blink/renderer/core/inspector/console_message.h"
 #include "third_party/blink/renderer/core/page/chrome_client.h"
+#include "third_party/blink/renderer/core/page/focus_controller.h"
 #include "third_party/blink/renderer/core/page/page.h"
 #include "third_party/blink/renderer/platform/heap/heap.h"
+#include "third_party/blink/renderer/platform/widget/frame_widget.h"
 
 namespace blink {
 
 PointerLockController::PointerLockController(Page* page)
     : page_(page), lock_pending_(false) {}
 
+bool PointerLockController::RequestPointerLock(Element* target,
+                                               ResultCallback callback) {
+  if (!target || !target->isConnected() ||
+      document_of_removed_element_while_waiting_for_unlock_ || element_) {
+    return false;
+  }
+  LocalDOMWindow* window = To<LocalDOMWindow>(target->GetExecutionContext());
+  window->GetFrame()->GetWidgetForLocalRoot()->RequestMouseLock(
+      LocalFrame::HasTransientUserActivation(window->GetFrame()),
+      /*unadjusted_movement_requested=*/false,
+      WTF::Bind(&PointerLockController::LockRequestCallback,
+                WrapWeakPersistent(this), std::move(callback),
+                /*unadjusted_movement_requested=*/false));
+  lock_pending_ = true;
+  element_ = target;
+  return true;
+}
+
 ScriptPromise PointerLockController::RequestPointerLock(
     ScriptPromiseResolver* resolver,
     Element* target,
@@ -98,20 +119,23 @@
           "element that currently holds the lock.");
       return promise;
     }
-
     // Attempt to change options if necessary.
     if (unadjusted_movement_requested != current_unadjusted_movement_setting_) {
-      if (!page_->GetChromeClient().RequestPointerLockChange(
-              window->GetFrame(),
-              WTF::Bind(&PointerLockController::ChangeLockRequestCallback,
-                        WrapWeakPersistent(this), WrapWeakPersistent(target),
-                        WrapPersistent(resolver),
-                        unadjusted_movement_requested),
-              unadjusted_movement_requested)) {
+      if (!mouse_lock_context_.is_bound() || lock_pending_) {
         EnqueueEvent(event_type_names::kPointerlockerror, target);
         exception_state.ThrowDOMException(
             DOMExceptionCode::kInUseAttributeError, "Pointer lock pending.");
+        return promise;
       }
+
+      mouse_lock_context_->RequestMouseLockChange(
+          unadjusted_movement_requested,
+          WTF::Bind(
+              &PointerLockController::ChangeLockRequestCallback,
+              WrapWeakPersistent(this), WrapWeakPersistent(target),
+              WTF::Bind(&PointerLockController::ProcessResultScriptPromise,
+                        WrapPersistent(resolver)),
+              unadjusted_movement_requested));
       return promise;
     }
 
@@ -120,18 +144,17 @@
     resolver->Resolve();
 
     // Subsequent steps are handled in the browser process.
-  } else if (page_->GetChromeClient().RequestPointerLock(
-                 window->GetFrame(),
-                 WTF::Bind(&PointerLockController::LockRequestCallback,
-                           WrapWeakPersistent(this), WrapPersistent(resolver),
-                           unadjusted_movement_requested),
-                 unadjusted_movement_requested)) {
+  } else {
+    window->GetFrame()->GetWidgetForLocalRoot()->RequestMouseLock(
+        LocalFrame::HasTransientUserActivation(window->GetFrame()),
+        unadjusted_movement_requested,
+        WTF::Bind(&PointerLockController::LockRequestCallback,
+                  WrapWeakPersistent(this),
+                  WTF::Bind(&PointerLockController::ProcessResultScriptPromise,
+                            WrapPersistent(resolver)),
+                  unadjusted_movement_requested));
     lock_pending_ = true;
     element_ = target;
-  } else {
-    EnqueueEvent(event_type_names::kPointerlockerror, target);
-    exception_state.ThrowDOMException(DOMExceptionCode::kInUseAttributeError,
-                                      "Pointer lock pending.");
   }
 
   return promise;
@@ -139,21 +162,41 @@
 
 void PointerLockController::ChangeLockRequestCallback(
     Element* target,
-    ScriptPromiseResolver* resolver,
+    ResultCallback callback,
     bool unadjusted_movement_requested,
     mojom::blink::PointerLockResult result) {
   if (result == mojom::blink::PointerLockResult::kSuccess)
     element_ = target;
 
-  LockRequestCallback(resolver, unadjusted_movement_requested, result);
+  ProcessResult(std::move(callback), unadjusted_movement_requested, result);
 }
 
 void PointerLockController::LockRequestCallback(
-    ScriptPromiseResolver* resolver,
+    ResultCallback callback,
     bool unadjusted_movement_requested,
+    mojom::blink::PointerLockResult result,
+    mojo::PendingRemote<blink::mojom::blink::PointerLockContext> context) {
+  if (element_ && context) {
+    mouse_lock_context_.Bind(std::move(context),
+                             element_->GetExecutionContext()->GetTaskRunner(
+                                 TaskType::kUserInteraction));
+    // The browser might unlock the mouse for many reasons including closing
+    // the tab, the user hitting esc, the page losing focus, and more.
+    mouse_lock_context_.set_disconnect_handler(WTF::Bind(
+        &PointerLockController::ExitPointerLock, WrapWeakPersistent(this)));
+  }
+  ProcessResult(std::move(callback), unadjusted_movement_requested, result);
+  if (result == mojom::blink::PointerLockResult::kSuccess) {
+    DidAcquirePointerLock();
+  } else {
+    DidNotAcquirePointerLock();
+  }
+}
+
+void PointerLockController::ProcessResultScriptPromise(
+    ScriptPromiseResolver* resolver,
     mojom::blink::PointerLockResult result) {
   if (result == mojom::blink::PointerLockResult::kSuccess) {
-    current_unadjusted_movement_setting_ = unadjusted_movement_requested;
     resolver->Resolve();
     return;
   }
@@ -161,6 +204,15 @@
   RejectIfPromiseEnabled(resolver, exception);
 }
 
+void PointerLockController::ProcessResult(
+    ResultCallback callback,
+    bool unadjusted_movement_requested,
+    mojom::blink::PointerLockResult result) {
+  if (result == mojom::blink::PointerLockResult::kSuccess)
+    current_unadjusted_movement_setting_ = unadjusted_movement_requested;
+  std::move(callback).Run(result);
+}
+
 DOMException* PointerLockController::ConvertResultToException(
     mojom::blink::PointerLockResult result) {
   switch (result) {
@@ -210,16 +262,29 @@
   }
 }
 
-void PointerLockController::RequestPointerUnlock() {
-  return page_->GetChromeClient().RequestPointerUnlock(
-      element_->GetDocument().GetFrame());
+void PointerLockController::ExitPointerLock() {
+  Document* pointer_lock_document =
+      element_ ? &element_->GetDocument()
+               : document_of_removed_element_while_waiting_for_unlock_.Get();
+  EnqueueEvent(event_type_names::kPointerlockchange, pointer_lock_document);
+
+  // Set the last mouse position back the locked position.
+  if (pointer_lock_document && pointer_lock_document->GetFrame()) {
+    pointer_lock_document->GetFrame()
+        ->GetEventHandler()
+        .ResetMousePositionForPointerUnlock();
+  }
+
+  ClearElement();
+  document_of_removed_element_while_waiting_for_unlock_ = nullptr;
+  mouse_lock_context_.reset();
 }
 
 void PointerLockController::ElementRemoved(Element* element) {
   if (element_ == element) {
     document_of_removed_element_while_waiting_for_unlock_ =
         &element_->GetDocument();
-    RequestPointerUnlock();
+    ExitPointerLock();
     // Set element null immediately to block any future interaction with it
     // including mouse events received before the unlock completes.
     ClearElement();
@@ -228,7 +293,7 @@
 
 void PointerLockController::DocumentDetached(Document* document) {
   if (element_ && element_->GetDocument() == document) {
-    RequestPointerUnlock();
+    ExitPointerLock();
     ClearElement();
   }
 }
@@ -237,6 +302,10 @@
   return lock_pending_;
 }
 
+bool PointerLockController::IsPointerLocked() const {
+  return mouse_lock_context_.is_bound();
+}
+
 Element* PointerLockController::GetElement() const {
   return element_.Get();
 }
@@ -252,6 +321,19 @@
     pointer_lock_screen_position_ = frame->LocalFrameRoot()
                                         .GetEventHandler()
                                         .LastKnownMouseScreenPosition();
+    LocalFrame* focused_frame =
+        frame->GetPage()->GetFocusController().FocusedFrame();
+    if (focused_frame) {
+      focused_frame->GetEventHandler().ReleaseMousePointerCapture();
+    }
+
+    // Mouse Lock removes the system cursor and provides all mouse motion as
+    // .movementX/Y values on events all sent to a fixed target. This requires
+    // content to specifically request the mode to be entered.
+    // Mouse Capture is implicitly given for the duration of a drag event, and
+    // sends all mouse events to the initial target of the drag.
+    // If Lock is entered it supersedes any in progress Capture.
+    frame->GetWidgetForLocalRoot()->MouseCaptureLost();
   }
 }
 
@@ -260,23 +342,6 @@
   ClearElement();
 }
 
-void PointerLockController::DidLosePointerLock() {
-  Document* pointer_lock_document =
-      element_ ? &element_->GetDocument()
-               : document_of_removed_element_while_waiting_for_unlock_.Get();
-  EnqueueEvent(event_type_names::kPointerlockchange, pointer_lock_document);
-
-  // Set the last mouse position back the locked position.
-  if (pointer_lock_document && pointer_lock_document->GetFrame()) {
-    pointer_lock_document->GetFrame()
-        ->GetEventHandler()
-        .ResetMousePositionForPointerUnlock();
-  }
-
-  ClearElement();
-  document_of_removed_element_while_waiting_for_unlock_ = nullptr;
-}
-
 void PointerLockController::DispatchLockedMouseEvent(
     const WebMouseEvent& event,
     const Vector<WebMouseEvent>& coalesced_events,
@@ -336,6 +401,7 @@
   visitor->Trace(page_);
   visitor->Trace(element_);
   visitor->Trace(document_of_removed_element_while_waiting_for_unlock_);
+  visitor->Trace(mouse_lock_context_);
 }
 
 // static
diff --git a/third_party/blink/renderer/core/page/pointer_lock_controller.h b/third_party/blink/renderer/core/page/pointer_lock_controller.h
index 30cc549..fd80b497 100644
--- a/third_party/blink/renderer/core/page/pointer_lock_controller.h
+++ b/third_party/blink/renderer/core/page/pointer_lock_controller.h
@@ -28,6 +28,7 @@
 
 #include "base/macros.h"
 #include "base/memory/scoped_refptr.h"
+#include "third_party/blink/public/mojom/input/pointer_lock_context.mojom-blink.h"
 #include "third_party/blink/public/mojom/input/pointer_lock_result.mojom-blink-forward.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
@@ -35,6 +36,7 @@
 #include "third_party/blink/renderer/platform/bindings/script_state.h"
 #include "third_party/blink/renderer/platform/geometry/float_point.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
+#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h"
 #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
 
 namespace blink {
@@ -52,19 +54,23 @@
  public:
   explicit PointerLockController(Page*);
 
+  using ResultCallback =
+      base::OnceCallback<void(mojom::blink::PointerLockResult)>;
+  bool RequestPointerLock(Element* target, ResultCallback callback);
+
   ScriptPromise RequestPointerLock(ScriptPromiseResolver* resolver,
                                    Element* target,
                                    ExceptionState& exception_state,
                                    const PointerLockOptions* options = nullptr);
-  void RequestPointerUnlock();
+  void ExitPointerLock();
   void ElementRemoved(Element*);
   void DocumentDetached(Document*);
   bool LockPending() const;
+  bool IsPointerLocked() const;
   Element* GetElement() const;
 
   void DidAcquirePointerLock();
   void DidNotAcquirePointerLock();
-  void DidLosePointerLock();
   void DispatchLockedMouseEvent(const WebMouseEvent&,
                                 const Vector<WebMouseEvent>& coalesced_events,
                                 const Vector<WebMouseEvent>& predicted_events,
@@ -83,22 +89,34 @@
   void EnqueueEvent(const AtomicString& type, Element*);
   void EnqueueEvent(const AtomicString& type, Document*);
   void ChangeLockRequestCallback(Element* target,
-                                 ScriptPromiseResolver* resolver,
+                                 ResultCallback callback,
                                  bool unadjusted_movement_requested,
                                  mojom::blink::PointerLockResult result);
-  void LockRequestCallback(ScriptPromiseResolver* resolver,
-                           bool unadjusted_movement_requested,
-                           mojom::blink::PointerLockResult result);
-  DOMException* ConvertResultToException(
+  void LockRequestCallback(
+      ResultCallback callback,
+      bool unadjusted_movement_requested,
+      mojom::blink::PointerLockResult result,
+      mojo::PendingRemote<blink::mojom::blink::PointerLockContext> context);
+
+  void ProcessResult(ResultCallback callback,
+                     bool unadjusted_movement_requested,
+                     mojom::blink::PointerLockResult result);
+
+  static void ProcessResultScriptPromise(
+      ScriptPromiseResolver* resolver,
       mojom::blink::PointerLockResult result);
-  void RejectIfPromiseEnabled(ScriptPromiseResolver* resolver,
-                              DOMException* exception);
+  static DOMException* ConvertResultToException(
+      mojom::blink::PointerLockResult result);
+  static void RejectIfPromiseEnabled(ScriptPromiseResolver* resolver,
+                                     DOMException* exception);
 
   Member<Page> page_;
   bool lock_pending_;
   Member<Element> element_;
   Member<Document> document_of_removed_element_while_waiting_for_unlock_;
 
+  HeapMojoRemote<mojom::blink::PointerLockContext> mouse_lock_context_{nullptr};
+
   // Store the locked position so that the event position keeps unchanged when
   // in locked states. These values only get set when entering lock states.
   FloatPoint pointer_lock_position_;
diff --git a/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.cc b/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.cc
index a712281..b7f3ba5 100644
--- a/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.cc
+++ b/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.cc
@@ -9,9 +9,7 @@
 #include "base/memory/ptr_util.h"
 #include "base/single_thread_task_runner.h"
 #include "base/trace_event/trace_event.h"
-#include "cc/paint/skia_paint_canvas.h"
 #include "media/base/limits.h"
-#include "skia/ext/platform_canvas.h"
 #include "third_party/blink/public/platform/web_media_player.h"
 #include "third_party/blink/public/platform/web_rect.h"
 #include "third_party/blink/public/platform/web_size.h"
@@ -20,10 +18,9 @@
 #include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
 #include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
-#include "third_party/libyuv/include/libyuv.h"
 
 namespace {
-const float kMinFramesPerSecond = 1.0;
+constexpr float kMinFramesPerSecond = 1.0;
 }  // anonymous namespace
 
 namespace blink {
@@ -50,7 +47,6 @@
     : web_media_player_(player),
       io_task_runner_(io_task_runner),
       task_runner_(task_runner),
-      is_opaque_(player->IsOpaque()),
       capture_frame_rate_(0.0) {
   DCHECK(web_media_player_);
 }
@@ -125,79 +121,18 @@
   if (start_capture_time_.is_null())
     start_capture_time_ = current_time;
 
-  if (!canvas_ || is_opaque_ != web_media_player_->IsOpaque()) {
-    // TODO(crbug.com/964494): Avoid the explicit conversion to gfx::Size here.
-    // TODO(sandersd): Implement support for size changes rather than scaling.
-    if (!canvas_)
-      natural_size_ = gfx::Size(web_media_player_->NaturalSize());
-    is_opaque_ = web_media_player_->IsOpaque();
-    if (!bitmap_.tryAllocPixels(SkImageInfo::MakeN32(
-            natural_size_.width(), natural_size_.height(),
-            is_opaque_ ? kOpaque_SkAlphaType : kPremul_SkAlphaType))) {
-      running_callback_.Run(false);
-      return;
-    }
-    canvas_ = std::make_unique<cc::SkiaPaintCanvas>(bitmap_);
-  }
-
-  cc::PaintFlags flags;
-  flags.setBlendMode(SkBlendMode::kSrc);
-  flags.setFilterQuality(kLow_SkFilterQuality);
-  // TODO(crbug.com/964494): Avoid the explicit conversion to blink::WebRect
-  // here.
-  web_media_player_->Paint(canvas_.get(),
-                           blink::WebRect(gfx::Rect(natural_size_)), flags);
-  DCHECK_NE(kUnknown_SkColorType, canvas_->imageInfo().colorType());
-
-  DCHECK_NE(kUnknown_SkColorType, bitmap_.colorType());
-  DCHECK(!bitmap_.drawsNothing());
-  DCHECK(bitmap_.getPixels());
-  if (bitmap_.colorType() != kN32_SkColorType) {
-    DLOG(ERROR) << "Only supported color type is kN32_SkColorType (ARGB/ABGR)";
-    return;
-  }
-
-  scoped_refptr<media::VideoFrame> frame = frame_pool_.CreateFrame(
-      is_opaque_ ? media::PIXEL_FORMAT_I420 : media::PIXEL_FORMAT_I420A,
-      natural_size_, gfx::Rect(natural_size_), natural_size_,
-      current_time - start_capture_time_);
-
-#if SK_PMCOLOR_BYTE_ORDER(R, G, B, A)
-  const uint32_t source_pixel_format = libyuv::FOURCC_ABGR;
-#else
-  const uint32_t source_pixel_format = libyuv::FOURCC_ARGB;
-#endif
-
-  if (frame &&
-      libyuv::ConvertToI420(
-          static_cast<uint8_t*>(bitmap_.getPixels()), bitmap_.computeByteSize(),
-          frame->visible_data(media::VideoFrame::kYPlane),
-          frame->stride(media::VideoFrame::kYPlane),
-          frame->visible_data(media::VideoFrame::kUPlane),
-          frame->stride(media::VideoFrame::kUPlane),
-          frame->visible_data(media::VideoFrame::kVPlane),
-          frame->stride(media::VideoFrame::kVPlane), 0 /* crop_x */,
-          0 /* crop_y */, frame->visible_rect().size().width(),
-          frame->visible_rect().size().height(), bitmap_.info().width(),
-          bitmap_.info().height(), libyuv::kRotate0,
-          source_pixel_format) == 0) {
-    if (!is_opaque_) {
-      // OK to use ARGB...() because alpha has the same alignment for both ABGR
-      // and ARGB.
-      libyuv::ARGBExtractAlpha(
-          static_cast<uint8_t*>(bitmap_.getPixels()),
-          static_cast<int>(bitmap_.rowBytes()) /* stride */,
-          frame->visible_data(media::VideoFrame::kAPlane),
-          frame->stride(media::VideoFrame::kAPlane), bitmap_.info().width(),
-          bitmap_.info().height());
-    }  // Success!
+  if (auto frame = web_media_player_->GetCurrentFrame()) {
+    auto new_frame = media::VideoFrame::WrapVideoFrame(
+        frame, frame->format(), frame->visible_rect(), frame->natural_size());
+    new_frame->set_timestamp(current_time - start_capture_time_);
 
     // Post with CrossThreadBind here, instead of CrossThreadBindOnce,
     // otherwise the |new_frame_callback_| ivar can be nulled out
     // unintentionally.
     PostCrossThreadTask(
         *io_task_runner_, FROM_HERE,
-        CrossThreadBindOnce(new_frame_callback_, frame, current_time));
+        CrossThreadBindOnce(new_frame_callback_, std::move(new_frame),
+                            current_time));
   }
 
   // Calculate the time in the future where the next frame should be created.
diff --git a/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.h b/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.h
index 081ea9d..07ec4f41 100644
--- a/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.h
+++ b/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source.h
@@ -9,22 +9,15 @@
 #include "base/memory/weak_ptr.h"
 #include "base/threading/thread_checker.h"
 #include "base/time/time.h"
-#include "media/base/video_frame_pool.h"
 #include "media/base/video_types.h"
 #include "media/capture/video_capturer_source.h"
 #include "third_party/blink/public/platform/web_size.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "third_party/skia/include/core/SkRefCnt.h"
 
 namespace base {
 class SingleThreadTaskRunner;
 }
 
-namespace cc {
-class PaintCanvas;
-}  // namespace cc
-
 namespace blink {
 
 class WebMediaPlayer;
@@ -61,17 +54,12 @@
   // it into a format suitable for MediaStreams.
   void sendNewFrame();
 
-  media::VideoFramePool frame_pool_;
-  SkBitmap bitmap_;
-  std::unique_ptr<cc::PaintCanvas> canvas_;
   gfx::Size natural_size_;
 
   const base::WeakPtr<blink::WebMediaPlayer> web_media_player_;
   const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
   const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
 
-  bool is_opaque_;
-
   // These three configuration items are passed on StartCapture();
   RunningCallback running_callback_;
   VideoCaptureDeliverFrameCB new_frame_callback_;
diff --git a/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc b/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc
index 13c693f8..55f576a 100644
--- a/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc
+++ b/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc
@@ -15,6 +15,7 @@
 #include "cc/paint/paint_canvas.h"
 #include "cc/paint/paint_flags.h"
 #include "media/base/limits.h"
+#include "media/base/video_frame.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
@@ -87,11 +88,17 @@
              cc::PaintFlags&,
              int already_uploaded_id,
              VideoFrameUploadMetadata* out_metadata) override {
+    return;
+  }
+
+  scoped_refptr<media::VideoFrame> GetCurrentFrame() override {
     // We could fill in |canvas| with a meaningful pattern in ARGB and verify
     // that is correctly captured (as I420) by HTMLVideoElementCapturerSource
     // but I don't think that'll be easy/useful/robust, so just let go here.
-    return;
+    return is_video_opaque_ ? media::VideoFrame::CreateBlackFrame(size_)
+                            : media::VideoFrame::CreateTransparentFrame(size_);
   }
+
   bool IsOpaque() const override { return is_video_opaque_; }
   bool HasAvailableVideoFrame() const override { return true; }
 
diff --git a/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc b/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc
index 181e023..febb2c8 100644
--- a/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc
+++ b/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc
@@ -264,24 +264,23 @@
   if (paused_)
     return;
 
-  if (!(video_frame->format() == media::PIXEL_FORMAT_I420 ||
-        video_frame->format() == media::PIXEL_FORMAT_ARGB ||
-        video_frame->format() == media::PIXEL_FORMAT_ABGR ||
-        video_frame->format() == media::PIXEL_FORMAT_I420A ||
-        video_frame->format() == media::PIXEL_FORMAT_NV12 ||
-        video_frame->format() == media::PIXEL_FORMAT_XRGB)) {
-    NOTREACHED() << media::VideoPixelFormatToString(video_frame->format());
-    return;
-  }
+  const bool is_format_supported =
+      video_frame->format() == media::PIXEL_FORMAT_I420 ||
+      video_frame->format() == media::PIXEL_FORMAT_ARGB ||
+      video_frame->format() == media::PIXEL_FORMAT_ABGR ||
+      video_frame->format() == media::PIXEL_FORMAT_I420A ||
+      video_frame->format() == media::PIXEL_FORMAT_NV12 ||
+      video_frame->format() == media::PIXEL_FORMAT_XRGB;
 
   if (num_frames_in_encode_->count() > kMaxNumberOfFramesInEncode) {
     DLOG(WARNING) << "Too many frames are queued up. Dropping this one.";
     return;
   }
 
-  if (video_frame->HasTextures() &&
-      video_frame->storage_type() !=
-          media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER) {
+  if (!is_format_supported ||
+      (video_frame->HasTextures() &&
+       video_frame->storage_type() !=
+           media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER)) {
     PostCrossThreadTask(
         *main_task_runner_.get(), FROM_HERE,
         CrossThreadBindOnce(&Encoder::RetrieveFrameOnMainThread,
@@ -333,14 +332,11 @@
   } else {
     // Accelerated decoders produce ARGB/ABGR texture-backed frames (see
     // https://crbug.com/585242), fetch them using a PaintCanvasVideoRenderer.
-    // Additionally, Macintosh accelerated decoders can produce XRGB content
+    // Additionally, macOS accelerated decoders can produce XRGB content
     // and are treated the same way.
     //
-    // TODO(crbug/1023390): Add browsertest for these.
-    DCHECK(video_frame->HasTextures());
-    DCHECK(video_frame->format() == media::PIXEL_FORMAT_ARGB ||
-           video_frame->format() == media::PIXEL_FORMAT_ABGR ||
-           video_frame->format() == media::PIXEL_FORMAT_XRGB);
+    // This path is also used for less common formats like I422, I444, and
+    // high bit depth pixel formats.
 
     const gfx::Size& old_visible_size = video_frame->visible_rect().size();
     gfx::Size new_visible_size = old_visible_size;
@@ -353,13 +349,16 @@
                                old_visible_size.width());
     }
 
-    frame = media::VideoFrame::CreateFrame(
-        media::PIXEL_FORMAT_I420, new_visible_size, gfx::Rect(new_visible_size),
-        new_visible_size, video_frame->timestamp());
+    const bool is_opaque = media::IsOpaque(video_frame->format());
+
+    frame = frame_pool_.CreateFrame(
+        is_opaque ? media::PIXEL_FORMAT_I420 : media::PIXEL_FORMAT_I420A,
+        new_visible_size, gfx::Rect(new_visible_size), new_visible_size,
+        video_frame->timestamp());
 
     const SkImageInfo info = SkImageInfo::MakeN32(
         frame->visible_rect().width(), frame->visible_rect().height(),
-        kOpaque_SkAlphaType);
+        is_opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
 
     // Create |surface_| if it doesn't exist or incoming resolution has changed.
     if (!canvas_ || canvas_->imageInfo().width() != info.width() ||
@@ -400,6 +399,14 @@
       DLOG(ERROR) << "Error converting frame to I420";
       return;
     }
+    if (!is_opaque) {
+      // Alpha has the same alignment for both ABGR and ARGB.
+      libyuv::ARGBExtractAlpha(static_cast<uint8_t*>(pixmap.writable_addr()),
+                               static_cast<int>(pixmap.rowBytes()) /* stride */,
+                               frame->visible_data(media::VideoFrame::kAPlane),
+                               frame->stride(media::VideoFrame::kAPlane),
+                               pixmap.width(), pixmap.height());
+    }
   }
 
   PostCrossThreadTask(
@@ -448,7 +455,7 @@
   auto* gmb = frame->GetGpuMemoryBuffer();
   if (!gmb->Map())
     return frame;
-  scoped_refptr<media::VideoFrame> i420_frame = media::VideoFrame::CreateFrame(
+  scoped_refptr<media::VideoFrame> i420_frame = frame_pool_.CreateFrame(
       media::VideoPixelFormat::PIXEL_FORMAT_I420, frame->coded_size(),
       frame->visible_rect(), frame->natural_size(), frame->timestamp());
   auto ret = libyuv::NV12ToI420(
diff --git a/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.h b/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.h
index 2ca9f78..d475ddc 100644
--- a/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.h
+++ b/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.h
@@ -14,6 +14,7 @@
 #include "base/threading/thread_checker.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
+#include "media/base/video_frame_pool.h"
 #include "media/muxers/webm_muxer.h"
 #include "media/video/video_encode_accelerator.h"
 #include "third_party/blink/public/common/media/video_capture.h"
@@ -196,7 +197,7 @@
     // Used mainly by the software encoders since I420 is the only supported
     // pixel format.  The function is best-effort.  If for any reason the
     // conversion fails, the original |frame| will be returned.
-    static scoped_refptr<media::VideoFrame> ConvertToI420ForSoftwareEncoder(
+    scoped_refptr<media::VideoFrame> ConvertToI420ForSoftwareEncoder(
         scoped_refptr<media::VideoFrame> frame);
 
     // Used to shutdown properly on the same thread we were created.
@@ -233,6 +234,8 @@
     SkBitmap bitmap_;
     std::unique_ptr<cc::PaintCanvas> canvas_;
 
+    media::VideoFramePool frame_pool_;
+
     DISALLOW_COPY_AND_ASSIGN(Encoder);
   };
 
diff --git a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
index 6a9e250..81699e2 100644
--- a/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
+++ b/third_party/blink/renderer/modules/mediastream/webmediaplayer_ms.cc
@@ -946,6 +946,12 @@
                         provider.get());
 }
 
+scoped_refptr<media::VideoFrame> WebMediaPlayerMS::GetCurrentFrame() {
+  DVLOG(3) << __func__;
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  return compositor_->GetCurrentFrame();
+}
+
 bool WebMediaPlayerMS::WouldTaintOrigin() const {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   return false;
diff --git a/third_party/blink/renderer/modules/xr/BUILD.gn b/third_party/blink/renderer/modules/xr/BUILD.gn
index c933239..ccb0989 100644
--- a/third_party/blink/renderer/modules/xr/BUILD.gn
+++ b/third_party/blink/renderer/modules/xr/BUILD.gn
@@ -76,6 +76,8 @@
     "xr_session.h",
     "xr_session_event.cc",
     "xr_session_event.h",
+    "xr_session_viewport_scaler.cc",
+    "xr_session_viewport_scaler.h",
     "xr_setlike.h",
     "xr_space.cc",
     "xr_space.h",
diff --git a/third_party/blink/renderer/modules/xr/xr_session.cc b/third_party/blink/renderer/modules/xr/xr_session.cc
index 749168c..ae8a4bed 100644
--- a/third_party/blink/renderer/modules/xr/xr_session.cc
+++ b/third_party/blink/renderer/modules/xr/xr_session.cc
@@ -44,6 +44,7 @@
 #include "third_party/blink/renderer/modules/xr/xr_reference_space.h"
 #include "third_party/blink/renderer/modules/xr/xr_render_state.h"
 #include "third_party/blink/renderer/modules/xr/xr_session_event.h"
+#include "third_party/blink/renderer/modules/xr/xr_session_viewport_scaler.h"
 #include "third_party/blink/renderer/modules/xr/xr_system.h"
 #include "third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_source.h"
 #include "third_party/blink/renderer/modules/xr/xr_utils.h"
@@ -325,7 +326,8 @@
           MakeGarbageCollected<XRFrameRequestCallbackCollection>(
               xr->GetExecutionContext())),
       uses_input_eventing_(device_config->uses_input_eventing),
-      supports_viewport_scaling_(device_config->supports_viewport_scaling),
+      supports_viewport_scaling_(immersive() &&
+                                 device_config->supports_viewport_scaling),
       sensorless_session_(sensorless_session) {
   client_receiver_.Bind(
       std::move(client_receiver),
@@ -1584,6 +1586,25 @@
   if (ended_)
     return;
 
+  // Apply dynamic viewport scaling if available.
+  if (frame_data && supports_viewport_scaling_) {
+    float gpu_load = frame_data->rendering_time_ratio;
+    base::Optional<double> scale = base::nullopt;
+    if (gpu_load > 0.0f) {
+      if (!viewport_scaler_) {
+        // Lazily create an instance of the viewport scaler on first use.
+        viewport_scaler_ = std::make_unique<XRSessionViewportScaler>();
+      }
+
+      viewport_scaler_->UpdateRenderingTimeRatio(gpu_load);
+      scale = viewport_scaler_->Scale();
+      DVLOG(3) << __func__ << ": gpu_load=" << gpu_load << " scale=" << *scale;
+    }
+    for (XRViewData* view : views()) {
+      view->SetRecommendedViewportScale(scale);
+    }
+  }
+
   mojo_from_viewer_ = getPoseMatrix(frame_pose);
   DVLOG(2) << __func__ << " : mojo_from_viewer_ valid? "
            << (mojo_from_viewer_ ? true : false);
@@ -1729,7 +1750,7 @@
     // at the start of an animation frame:
     // https://immersive-web.github.io/webxr/#ref-for-view-viewport-modifiable
     if (supports_viewport_scaling_) {
-      for (XRViewData* view : views_) {
+      for (XRViewData* view : views()) {
         view->SetViewportModifiable(true);
       }
     }
diff --git a/third_party/blink/renderer/modules/xr/xr_session.h b/third_party/blink/renderer/modules/xr/xr_session.h
index d88a89d..ddc5a66 100644
--- a/third_party/blink/renderer/modules/xr/xr_session.h
+++ b/third_party/blink/renderer/modules/xr/xr_session.h
@@ -49,6 +49,7 @@
 class XRReferenceSpace;
 class XRRenderState;
 class XRRenderStateInit;
+class XRSessionViewportScaler;
 class XRSpace;
 class XRSystem;
 class XRTransientInputHitTestOptionsInit;
@@ -566,6 +567,8 @@
   // Corresponds to mojo XRSession.supportsViewportScaling
   bool supports_viewport_scaling_ = false;
 
+  std::unique_ptr<XRSessionViewportScaler> viewport_scaler_;
+
   // Indicates that this is a sensorless session which should only support the
   // identity reference space.
   bool sensorless_session_ = false;
diff --git a/third_party/blink/renderer/modules/xr/xr_session_viewport_scaler.cc b/third_party/blink/renderer/modules/xr/xr_session_viewport_scaler.cc
new file mode 100644
index 0000000..50d8f6d
--- /dev/null
+++ b/third_party/blink/renderer/modules/xr/xr_session_viewport_scaler.cc
@@ -0,0 +1,67 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/modules/xr/xr_session_viewport_scaler.h"
+
+#include <algorithm>
+#include <cmath>
+
+#include "base/numerics/ranges.h"
+
+namespace blink {
+
+namespace {
+
+// Minimum and maximum viewport scale factors.
+constexpr float kMinScale = 0.25f;
+constexpr float kMaxScale = 1.0f;
+
+// With this scale step, the resulting scales include powers of 1/2:
+// [1, 0.841, 0.707, 0.595, 0.5, 0.420, 0.354, 0.297, 0.25]
+constexpr float kScaleStep = 0.840896415256f;  // sqrt(sqrt(1/2))
+
+// Thresholds for high/low load values to trigger a scale change.
+constexpr float kLoadHigh = 1.25f;
+constexpr float kLoadLow = 0.9f;
+
+// Maximum change allowed for a single update. Helps avoid glitches for
+// outliers.
+constexpr float kMaxChange = 0.5f;
+
+// Load average decay value, smaller values are smoother but react
+// slower. Higher values react quicker but may oscillate.
+// Must be between 0 and 1.
+constexpr float kLoadDecay = 0.3f;
+
+// A power of two used to round the floating point value to a certain number
+// of significant bits. This ensures that scale values exactly equal the
+// appropriate powers of 2 (1, 0.5, 0.25). We don't want rounding errors to
+// result in a scale of 0.99999 instead of 1.0 after multiple iterations of
+// scaling up and down.
+constexpr float kRound = 65536.0f;
+
+}  // namespace
+
+void XRSessionViewportScaler::ResetLoad() {
+  gpu_load_ = (kLoadHigh + kLoadLow) / 2;
+}
+
+void XRSessionViewportScaler::UpdateRenderingTimeRatio(float new_value) {
+  gpu_load_ += base::ClampToRange(kLoadDecay * (new_value - gpu_load_),
+                                  -kMaxChange, kMaxChange);
+  float old_scale = scale_;
+  if (gpu_load_ > kLoadHigh && scale_ > kMinScale) {
+    scale_ *= kScaleStep;
+    scale_ = round(scale_ * kRound) / kRound;
+  } else if (gpu_load_ < kLoadLow && scale_ < kMaxScale) {
+    scale_ /= kScaleStep;
+    scale_ = round(scale_ * kRound) / kRound;
+  }
+  scale_ = base::ClampToRange(scale_, kMinScale, kMaxScale);
+  if (scale_ != old_scale) {
+    ResetLoad();
+  }
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/modules/xr/xr_session_viewport_scaler.h b/third_party/blink/renderer/modules/xr/xr_session_viewport_scaler.h
new file mode 100644
index 0000000..0dd7124
--- /dev/null
+++ b/third_party/blink/renderer/modules/xr/xr_session_viewport_scaler.h
@@ -0,0 +1,24 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_SESSION_VIEWPORT_SCALER_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_SESSION_VIEWPORT_SCALER_H_
+
+namespace blink {
+
+class XRSessionViewportScaler final {
+ public:
+  XRSessionViewportScaler() { ResetLoad(); }
+  void UpdateRenderingTimeRatio(float value);
+  float Scale() { return scale_; }
+  void ResetLoad();
+
+ private:
+  float gpu_load_ = 1.0f;
+  float scale_ = 1.0f;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_SESSION_VIEWPORT_SCALER_H_
diff --git a/third_party/blink/renderer/modules/xr/xr_view.cc b/third_party/blink/renderer/modules/xr/xr_view.cc
index bab90023..3c88af4 100644
--- a/third_party/blink/renderer/modules/xr/xr_view.cc
+++ b/third_party/blink/renderer/modules/xr/xr_view.cc
@@ -157,7 +157,7 @@
 }
 
 base::Optional<double> XRView::recommendedViewportScale() const {
-  return base::nullopt;
+  return view_data_->recommendedViewportScale();
 }
 
 void XRView::requestViewportScale(base::Optional<double> scale) {
@@ -173,7 +173,7 @@
 }
 
 base::Optional<double> XRViewData::recommendedViewportScale() const {
-  return base::nullopt;
+  return recommended_viewport_scale_;
 }
 
 void XRViewData::requestViewportScale(base::Optional<double> scale) {
diff --git a/third_party/blink/renderer/modules/xr/xr_view.h b/third_party/blink/renderer/modules/xr/xr_view.h
index dad4948a..37fb574 100644
--- a/third_party/blink/renderer/modules/xr/xr_view.h
+++ b/third_party/blink/renderer/modules/xr/xr_view.h
@@ -89,6 +89,9 @@
   }
 
   base::Optional<double> recommendedViewportScale() const;
+  void SetRecommendedViewportScale(base::Optional<double> scale) {
+    recommended_viewport_scale_ = scale;
+  }
 
   void requestViewportScale(base::Optional<double> scale);
 
@@ -111,6 +114,7 @@
   TransformationMatrix inv_projection_;
   TransformationMatrix head_from_eye_;
   bool inv_projection_dirty_ = true;
+  base::Optional<double> recommended_viewport_scale_ = base::nullopt;
   double requested_viewport_scale_ = 1.0;
   double current_viewport_scale_ = 1.0;
   bool viewport_modifiable_ = false;
diff --git a/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc b/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc
index 3a0218c..ec7a355 100644
--- a/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc
+++ b/third_party/blink/renderer/modules/xr/xr_webgl_layer.cc
@@ -209,6 +209,8 @@
     view_data->SetCurrentViewportScale(view_data->RequestedViewportScale());
     viewports_dirty_ = true;
   }
+  TRACE_COUNTER1("xr", "XR viewport scale (%)",
+                 view_data->CurrentViewportScale() * 100);
   view_data->SetViewportModifiable(false);
 
   return GetViewportForEye(view->EyeValue());
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc b/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc
index 58bee35..70f7b51 100644
--- a/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc
+++ b/third_party/blink/renderer/platform/graphics/dark_mode_filter.cc
@@ -63,50 +63,44 @@
   WTF::LruCache<WTF::IntegralWithAllKeys<SkColor>, SkColor> cache_;
 };
 
-DarkModeFilter::DarkModeFilter()
-    : text_classifier_(nullptr),
-      background_classifier_(nullptr),
-      image_classifier_(nullptr),
-      color_filter_(nullptr),
-      image_filter_(nullptr),
-      inverted_color_cache_(new DarkModeInvertedColorCache()) {
-  DarkModeSettings default_settings;
-  UpdateSettings(default_settings);
-}
+DarkModeFilter::DarkModeFilter(const DarkModeSettings& settings)
+    : immutable_(settings),
+      inverted_color_cache_(new DarkModeInvertedColorCache()) {}
 
 DarkModeFilter::~DarkModeFilter() {}
 
-void DarkModeFilter::UpdateSettings(const DarkModeSettings& new_settings) {
-  inverted_color_cache_->Clear();
-
-  settings_ = new_settings;
-  color_filter_ = DarkModeColorFilter::FromSettings(settings_);
-  if (!color_filter_) {
-    image_filter_ = nullptr;
+DarkModeFilter::ImmutableData::ImmutableData(const DarkModeSettings& settings)
+    : settings(settings),
+      text_classifier(nullptr),
+      background_classifier(nullptr),
+      image_classifier(nullptr),
+      color_filter(nullptr),
+      image_filter(nullptr) {
+  color_filter = DarkModeColorFilter::FromSettings(settings);
+  if (!color_filter)
     return;
-  }
 
-  if (settings_.image_grayscale_percent > 0.0f)
-    image_filter_ = MakeGrayscaleFilter(settings_.image_grayscale_percent);
+  if (settings.image_grayscale_percent > 0.0f)
+    image_filter = MakeGrayscaleFilter(settings.image_grayscale_percent);
   else
-    image_filter_ = color_filter_->ToSkColorFilter();
+    image_filter = color_filter->ToSkColorFilter();
 
-  text_classifier_ =
-      DarkModeColorClassifier::MakeTextColorClassifier(settings_);
-  background_classifier_ =
-      DarkModeColorClassifier::MakeBackgroundColorClassifier(settings_);
-  image_classifier_ = std::make_unique<DarkModeImageClassifier>();
+  text_classifier = DarkModeColorClassifier::MakeTextColorClassifier(settings);
+  background_classifier =
+      DarkModeColorClassifier::MakeBackgroundColorClassifier(settings);
+  image_classifier = std::make_unique<DarkModeImageClassifier>();
 }
 
 SkColor DarkModeFilter::InvertColorIfNeeded(SkColor color, ElementRole role) {
-  if (!color_filter_)
+  if (!immutable_.color_filter)
     return color;
 
   if (role_override_.has_value())
     role = role_override_.value();
 
   if (ShouldApplyToColor(color, role)) {
-    return inverted_color_cache_->GetInvertedColor(color_filter_.get(), color);
+    return inverted_color_cache_->GetInvertedColor(
+        immutable_.color_filter.get(), color);
   }
 
   return color;
@@ -115,10 +109,10 @@
 DarkModeResult DarkModeFilter::AnalyzeShouldApplyToImage(
     const SkIRect& src,
     const SkIRect& dst) const {
-  if (settings().image_policy == DarkModeImagePolicy::kFilterNone)
+  if (immutable_.settings.image_policy == DarkModeImagePolicy::kFilterNone)
     return DarkModeResult::kDoNotApplyFilter;
 
-  if (settings().image_policy == DarkModeImagePolicy::kFilterAll)
+  if (immutable_.settings.image_policy == DarkModeImagePolicy::kFilterAll)
     return DarkModeResult::kApplyFilter;
 
   // Images being drawn from very smaller |src| rect, i.e. one of the dimensions
@@ -140,25 +134,25 @@
                                                   const SkIRect& src,
                                                   const SkIRect& dst) const {
   DCHECK(AnalyzeShouldApplyToImage(src, dst) == DarkModeResult::kNotClassified);
-  DCHECK(settings().image_policy == DarkModeImagePolicy::kFilterSmart);
-  DCHECK(image_filter_);
+  DCHECK(immutable_.settings.image_policy == DarkModeImagePolicy::kFilterSmart);
+  DCHECK(immutable_.image_filter);
 
-  return (image_classifier_->Classify(pixmap, src) ==
+  return (immutable_.image_classifier->Classify(pixmap, src) ==
           DarkModeResult::kApplyFilter)
-             ? image_filter_
+             ? immutable_.image_filter
              : nullptr;
 }
 
 sk_sp<SkColorFilter> DarkModeFilter::GetImageFilter() const {
-  DCHECK(settings().image_policy == DarkModeImagePolicy::kFilterAll);
-  DCHECK(image_filter_);
-  return image_filter_;
+  DCHECK(immutable_.settings.image_policy == DarkModeImagePolicy::kFilterAll);
+  DCHECK(immutable_.image_filter);
+  return immutable_.image_filter;
 }
 
 base::Optional<cc::PaintFlags> DarkModeFilter::ApplyToFlagsIfNeeded(
     const cc::PaintFlags& flags,
     ElementRole role) {
-  if (!color_filter_)
+  if (!immutable_.color_filter)
     return base::nullopt;
 
   if (role_override_.has_value())
@@ -166,10 +160,10 @@
 
   cc::PaintFlags dark_mode_flags = flags;
   if (flags.HasShader()) {
-    dark_mode_flags.setColorFilter(color_filter_->ToSkColorFilter());
+    dark_mode_flags.setColorFilter(immutable_.color_filter->ToSkColorFilter());
   } else if (ShouldApplyToColor(flags.getColor(), role)) {
     dark_mode_flags.setColor(inverted_color_cache_->GetInvertedColor(
-        color_filter_.get(), flags.getColor()));
+        immutable_.color_filter.get(), flags.getColor()));
   }
 
   return base::make_optional<cc::PaintFlags>(std::move(dark_mode_flags));
@@ -178,19 +172,19 @@
 bool DarkModeFilter::ShouldApplyToColor(SkColor color, ElementRole role) {
   switch (role) {
     case ElementRole::kText:
-      DCHECK(text_classifier_);
-      return text_classifier_->ShouldInvertColor(color) ==
+      DCHECK(immutable_.text_classifier);
+      return immutable_.text_classifier->ShouldInvertColor(color) ==
              DarkModeResult::kApplyFilter;
     case ElementRole::kListSymbol:
-      // TODO(prashant.n): Rename text_classifier_ to foreground_classifier_,
+      // TODO(prashant.n): Rename text_classifier to foreground_classifier,
       // so that same classifier can be used for all roles which are supposed
       // to be at foreground.
-      DCHECK(text_classifier_);
-      return text_classifier_->ShouldInvertColor(color) ==
+      DCHECK(immutable_.text_classifier);
+      return immutable_.text_classifier->ShouldInvertColor(color) ==
              DarkModeResult::kApplyFilter;
     case ElementRole::kBackground:
-      DCHECK(background_classifier_);
-      return background_classifier_->ShouldInvertColor(color) ==
+      DCHECK(immutable_.background_classifier);
+      return immutable_.background_classifier->ShouldInvertColor(color) ==
              DarkModeResult::kApplyFilter;
     case ElementRole::kSVG:
       // 1) Inline SVG images are considered as individual shapes and do not
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_filter.h b/third_party/blink/renderer/platform/graphics/dark_mode_filter.h
index 3d7172a..372c2e4 100644
--- a/third_party/blink/renderer/platform/graphics/dark_mode_filter.h
+++ b/third_party/blink/renderer/platform/graphics/dark_mode_filter.h
@@ -27,12 +27,9 @@
  public:
   // Dark mode is disabled by default. Enable it by calling UpdateSettings()
   // with a mode other than DarkMode::kOff.
-  DarkModeFilter();
+  explicit DarkModeFilter(const DarkModeSettings& settings);
   ~DarkModeFilter();
 
-  const DarkModeSettings& settings() const { return settings_; }
-  void UpdateSettings(const DarkModeSettings& new_settings);
-
   // TODO(gilmanmh): Add a role for shadows. In general, we don't want to
   // invert shadows, but we may need to do some other kind of processing for
   // them.
@@ -43,12 +40,15 @@
       const cc::PaintFlags& flags,
       ElementRole element_role);
 
+  size_t GetInvertedColorCacheSizeForTesting();
+
   // Decides whether to apply dark mode or not based on |src| and |dst|.
   // DarkModeResult::kDoNotApplyFilter - Dark mode filter should not be applied.
   // DarkModeResult::kApplyFilter - Dark mode filter should be applied and to
   // get the color filter GetImageFilter() should be called.
   // DarkModeResult::kNotClassified - Dark mode filter should be applied and to
-  // get the color filter ApplyToImage() should be called.
+  // get the color filter ApplyToImage() should be called. This API is
+  // thread-safe.
   DarkModeResult AnalyzeShouldApplyToImage(const SkIRect& src,
                                            const SkIRect& dst) const;
 
@@ -57,7 +57,8 @@
   // empty or |src| is larger than pixmap bounds. Before calling this function
   // AnalyzeShouldApplyToImage() must be called for early out or deciding
   // appropriate function call. This function should be called only if image
-  // policy is set to DarkModeImagePolicy::kFilterSmart.
+  // policy is set to DarkModeImagePolicy::kFilterSmart. This API is
+  // thread-safe.
   sk_sp<SkColorFilter> ApplyToImage(const SkPixmap& pixmap,
                                     const SkIRect& src,
                                     const SkIRect& dst) const;
@@ -65,25 +66,31 @@
   // Returns dark mode color filter for images. Before calling this function
   // AnalyzeShouldApplyToImage() must be called for early out or deciding
   // appropriate function call. This function should be called only if image
-  // policy is set to DarkModeImagePolicy::kFilterAll.
+  // policy is set to DarkModeImagePolicy::kFilterAll. This API is thread-safe.
   sk_sp<SkColorFilter> GetImageFilter() const;
-
-  size_t GetInvertedColorCacheSizeForTesting();
-
  private:
   friend class ScopedDarkModeElementRoleOverride;
 
-  DarkModeSettings settings_;
+  struct ImmutableData {
+    explicit ImmutableData(const DarkModeSettings& settings);
+
+    DarkModeSettings settings;
+    std::unique_ptr<DarkModeColorClassifier> text_classifier;
+    std::unique_ptr<DarkModeColorClassifier> background_classifier;
+    std::unique_ptr<DarkModeImageClassifier> image_classifier;
+    std::unique_ptr<DarkModeColorFilter> color_filter;
+    sk_sp<SkColorFilter> image_filter;
+  };
 
   bool ShouldApplyToColor(SkColor color, ElementRole role);
 
-  std::unique_ptr<DarkModeColorClassifier> text_classifier_;
-  std::unique_ptr<DarkModeColorClassifier> background_classifier_;
-  std::unique_ptr<DarkModeImageClassifier> image_classifier_;
+  // This is read-only data and is thread-safe.
+  const ImmutableData immutable_;
 
-  std::unique_ptr<DarkModeColorFilter> color_filter_;
-  sk_sp<SkColorFilter> image_filter_;
+  // Following two members used for color classifications are not thread-safe.
+  // TODO(prashant.n): Remove element override concept.
   base::Optional<ElementRole> role_override_;
+  // TODO(prashant.n): Move cache out of dark mode filter.
   std::unique_ptr<DarkModeInvertedColorCache> inverted_color_cache_;
 };
 
diff --git a/third_party/blink/renderer/platform/graphics/dark_mode_filter_test.cc b/third_party/blink/renderer/platform/graphics/dark_mode_filter_test.cc
index 0e58941..0b6ddc5 100644
--- a/third_party/blink/renderer/platform/graphics/dark_mode_filter_test.cc
+++ b/third_party/blink/renderer/platform/graphics/dark_mode_filter_test.cc
@@ -14,11 +14,9 @@
 namespace {
 
 TEST(DarkModeFilterTest, ApplyDarkModeToColorsAndFlags) {
-  DarkModeFilter filter;
-
   DarkModeSettings settings;
   settings.mode = DarkModeInversionAlgorithm::kSimpleInvertForTesting;
-  filter.UpdateSettings(settings);
+  DarkModeFilter filter(settings);
 
   EXPECT_EQ(SK_ColorBLACK,
             filter.InvertColorIfNeeded(
@@ -43,11 +41,9 @@
 }
 
 TEST(DarkModeFilterTest, InvertedColorCacheSize) {
-  DarkModeFilter filter;
   DarkModeSettings settings;
-
   settings.mode = DarkModeInversionAlgorithm::kSimpleInvertForTesting;
-  filter.UpdateSettings(settings);
+  DarkModeFilter filter(settings);
   EXPECT_EQ(0u, filter.GetInvertedColorCacheSizeForTesting());
   EXPECT_EQ(SK_ColorBLACK,
             filter.InvertColorIfNeeded(
@@ -58,18 +54,12 @@
             filter.InvertColorIfNeeded(
                 SK_ColorWHITE, DarkModeFilter::ElementRole::kBackground));
   EXPECT_EQ(1u, filter.GetInvertedColorCacheSizeForTesting());
-
-  // On changing DarkModeSettings, cache should be reset.
-  settings.mode = DarkModeInversionAlgorithm::kInvertLightness;
-  filter.UpdateSettings(settings);
-  EXPECT_EQ(0u, filter.GetInvertedColorCacheSizeForTesting());
 }
 
 TEST(DarkModeFilterTest, InvertedColorCacheZeroMaxKeys) {
-  DarkModeFilter filter;
   DarkModeSettings settings;
   settings.mode = DarkModeInversionAlgorithm::kSimpleInvertForTesting;
-  filter.UpdateSettings(settings);
+  DarkModeFilter filter(settings);
 
   EXPECT_EQ(0u, filter.GetInvertedColorCacheSizeForTesting());
   EXPECT_EQ(SK_ColorBLACK,
@@ -92,11 +82,10 @@
 }
 
 TEST(DarkModeFilterTest, AnalyzeShouldApplyToImage) {
-  DarkModeFilter filter;
   DarkModeSettings settings;
   settings.mode = DarkModeInversionAlgorithm::kSimpleInvertForTesting;
   settings.image_policy = DarkModeImagePolicy::kFilterSmart;
-  filter.UpdateSettings(settings);
+  DarkModeFilter filter(settings);
 
   // |dst| is smaller than threshold size.
   EXPECT_EQ(filter.AnalyzeShouldApplyToImage(SkIRect::MakeWH(100, 100),
diff --git a/third_party/blink/renderer/platform/graphics/graphics_context.cc b/third_party/blink/renderer/platform/graphics/graphics_context.cc
index b062c07..d1a8da9 100644
--- a/third_party/blink/renderer/platform/graphics/graphics_context.cc
+++ b/third_party/blink/renderer/platform/graphics/graphics_context.cc
@@ -154,8 +154,8 @@
 
 DarkModeFilter* GraphicsContext::GetDarkModeFilter() {
   if (!dark_mode_filter_) {
-    dark_mode_filter_ = std::make_unique<DarkModeFilter>();
-    dark_mode_filter_->UpdateSettings(GetCurrentDarkModeSettings());
+    dark_mode_filter_ =
+        std::make_unique<DarkModeFilter>(GetCurrentDarkModeSettings());
   }
 
   return dark_mode_filter_.get();
@@ -163,7 +163,7 @@
 
 void GraphicsContext::UpdateDarkModeSettingsForTest(
     const DarkModeSettings& settings) {
-  GetDarkModeFilter()->UpdateSettings(settings);
+  dark_mode_filter_ = std::make_unique<DarkModeFilter>(settings);
 }
 
 void GraphicsContext::Save() {
diff --git a/third_party/blink/renderer/platform/graphics/raster_dark_mode_filter_impl.cc b/third_party/blink/renderer/platform/graphics/raster_dark_mode_filter_impl.cc
index 50b656f..9f737cdc 100644
--- a/third_party/blink/renderer/platform/graphics/raster_dark_mode_filter_impl.cc
+++ b/third_party/blink/renderer/platform/graphics/raster_dark_mode_filter_impl.cc
@@ -11,8 +11,7 @@
 
 RasterDarkModeFilterImpl::RasterDarkModeFilterImpl(
     const DarkModeSettings& settings) {
-  dark_mode_filter_ = std::make_unique<DarkModeFilter>();
-  dark_mode_filter_->UpdateSettings(settings);
+  dark_mode_filter_ = std::make_unique<DarkModeFilter>(settings);
 }
 
 cc::RasterDarkModeFilter::Result
diff --git a/third_party/blink/renderer/platform/testing/DEPS b/third_party/blink/renderer/platform/testing/DEPS
index 772b4f4..84b3222 100644
--- a/third_party/blink/renderer/platform/testing/DEPS
+++ b/third_party/blink/renderer/platform/testing/DEPS
@@ -19,7 +19,7 @@
     "+cc",
     "+mojo/core/embedder",
     "+services/network/public",
-    '+testing',
+    "+testing",
 
     "+third_party/blink/renderer/platform/context_lifecycle_notifier.h",
     "+third_party/blink/renderer/platform/context_lifecycle_observer.h",
@@ -50,10 +50,13 @@
 ]
 
 specific_include_rules = {
-    'blink_fuzzer_test_support\.cc': [
+    "blink_fuzzer_test_support\.cc": [
         "+content/public/test/blink_test_environment.h",
     ],
-    'testing_platform_support_with_mock_scheduler\.cc': [
+    "empty_web_media_player\.cc": [
+        "+media/base/video_frame.h",
+    ],
+    "testing_platform_support_with_mock_scheduler\.cc": [
         "+base/task/sequence_manager/test/sequence_manager_for_test.h",
     ],
     "video_frame_utils\.cc": [
diff --git a/third_party/blink/renderer/platform/testing/empty_web_media_player.cc b/third_party/blink/renderer/platform/testing/empty_web_media_player.cc
index 119e0ff7..6b943b2 100644
--- a/third_party/blink/renderer/platform/testing/empty_web_media_player.cc
+++ b/third_party/blink/renderer/platform/testing/empty_web_media_player.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/platform/testing/empty_web_media_player.h"
 
+#include "media/base/video_frame.h"
 #include "third_party/blink/public/platform/web_size.h"
 #include "third_party/blink/public/platform/web_time_range.h"
 
@@ -34,4 +35,8 @@
   return WebString();
 }
 
+scoped_refptr<media::VideoFrame> EmptyWebMediaPlayer::GetCurrentFrame() {
+  return nullptr;
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/testing/empty_web_media_player.h b/third_party/blink/renderer/platform/testing/empty_web_media_player.h
index 2e7f32a..90d8b3e4 100644
--- a/third_party/blink/renderer/platform/testing/empty_web_media_player.h
+++ b/third_party/blink/renderer/platform/testing/empty_web_media_player.h
@@ -65,6 +65,7 @@
              cc::PaintFlags&,
              int already_uploaded_id,
              VideoFrameUploadMetadata*) override {}
+  scoped_refptr<media::VideoFrame> GetCurrentFrame() override;
   bool HasAvailableVideoFrame() const override { return false; }
   base::WeakPtr<WebMediaPlayer> AsWeakPtr() override { return nullptr; }
 };
diff --git a/third_party/blink/renderer/platform/widget/compositing/widget_compositor_unittest.cc b/third_party/blink/renderer/platform/widget/compositing/widget_compositor_unittest.cc
index f0c055b..a0c3b05 100644
--- a/third_party/blink/renderer/platform/widget/compositing/widget_compositor_unittest.cc
+++ b/third_party/blink/renderer/platform/widget/compositing/widget_compositor_unittest.cc
@@ -31,7 +31,7 @@
   }
   bool SupportsBufferedTouchEvents() override { return false; }
   bool WillHandleGestureEvent(const WebGestureEvent&) override { return false; }
-  bool WillHandleMouseEvent(const WebMouseEvent&) override { return false; }
+  void WillHandleMouseEvent(const WebMouseEvent&) override {}
   void ObserveGestureEventAndResult(const WebGestureEvent&,
                                     const gfx::Vector2dF&,
                                     const cc::OverscrollBehavior&,
diff --git a/third_party/blink/renderer/platform/widget/frame_widget.h b/third_party/blink/renderer/platform/widget/frame_widget.h
index 2bcb93c8..951ebaa 100644
--- a/third_party/blink/renderer/platform/widget/frame_widget.h
+++ b/third_party/blink/renderer/platform/widget/frame_widget.h
@@ -202,6 +202,15 @@
   virtual gfx::PointF DIPsToBlinkSpace(const gfx::PointF& point) = 0;
   virtual gfx::Point DIPsToRoundedBlinkSpace(const gfx::Point& point) = 0;
   virtual float DIPsToBlinkSpace(float scalar) = 0;
+
+  virtual void RequestMouseLock(
+      bool has_transient_user_activation,
+      bool request_unadjusted_movement,
+      mojom::blink::WidgetInputHandlerHost::RequestMouseLockCallback
+          callback) = 0;
+
+  // Mouse capture has been lost.
+  virtual void MouseCaptureLost() = 0;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/widget/input/widget_base_input_handler.cc b/third_party/blink/renderer/platform/widget/input/widget_base_input_handler.cc
index 386110f..d671c092 100644
--- a/third_party/blink/renderer/platform/widget/input/widget_base_input_handler.cc
+++ b/third_party/blink/renderer/platform/widget/input/widget_base_input_handler.cc
@@ -366,7 +366,7 @@
                  mouse_event.PositionInWidget().x(), "y",
                  mouse_event.PositionInWidget().y());
 
-    prevent_default = widget_->client()->WillHandleMouseEvent(mouse_event);
+    widget_->client()->WillHandleMouseEvent(mouse_event);
 
     // Reset the last known cursor if mouse has left this widget. So next
     // time that the mouse enters we always set the cursor accordingly.
diff --git a/third_party/blink/renderer/platform/widget/widget_base.cc b/third_party/blink/renderer/platform/widget/widget_base.cc
index a4a0664b..e07ddb2 100644
--- a/third_party/blink/renderer/platform/widget/widget_base.cc
+++ b/third_party/blink/renderer/platform/widget/widget_base.cc
@@ -1138,7 +1138,10 @@
 }
 
 void WidgetBase::MouseCaptureLost() {
-  client_->MouseCaptureLost();
+  FrameWidget* frame_widget = client_->FrameWidget();
+  if (!frame_widget)
+    return;
+  frame_widget->MouseCaptureLost();
 }
 
 void WidgetBase::SetEditCommandsForNextKeyEvent(
@@ -1313,31 +1316,6 @@
 #endif
 }
 
-void WidgetBase::RequestMouseLock(
-    bool has_transient_user_activation,
-    bool request_unadjusted_movement,
-    base::OnceCallback<void(
-        blink::mojom::PointerLockResult,
-        CrossVariantMojoRemote<mojom::blink::PointerLockContextInterfaceBase>)>
-        callback) {
-  if (mojom::blink::WidgetInputHandlerHost* host =
-          widget_input_handler_manager_->GetWidgetInputHandlerHost()) {
-    host->RequestMouseLock(
-        has_transient_user_activation, request_unadjusted_movement,
-        base::BindOnce(
-            [](base::OnceCallback<void(
-                   blink::mojom::PointerLockResult,
-                   CrossVariantMojoRemote<
-                       mojom::blink::PointerLockContextInterfaceBase>)>
-                   callback,
-               blink::mojom::PointerLockResult result,
-               mojo::PendingRemote<mojom::blink::PointerLockContext> context) {
-              std::move(callback).Run(result, std::move(context));
-            },
-            std::move(callback)));
-  }
-}
-
 void WidgetBase::UpdateSurfaceAndScreenInfo(
     const viz::LocalSurfaceId& new_local_surface_id,
     const gfx::Rect& compositor_viewport_pixel_rect,
diff --git a/third_party/blink/renderer/platform/widget/widget_base.h b/third_party/blink/renderer/platform/widget/widget_base.h
index 30ae1f6..6e01222 100644
--- a/third_party/blink/renderer/platform/widget/widget_base.h
+++ b/third_party/blink/renderer/platform/widget/widget_base.h
@@ -219,13 +219,6 @@
   void set_handling_select_range(bool value) { handling_select_range_ = value; }
   bool handling_select_range() const { return handling_select_range_; }
 
-  void RequestMouseLock(
-      bool has_transient_user_activation,
-      bool request_unadjusted_movement,
-      base::OnceCallback<
-          void(blink::mojom::PointerLockResult,
-               CrossVariantMojoRemote<
-                   mojom::blink::PointerLockContextInterfaceBase>)> callback);
   bool ComputePreferCompositingToLCDText();
 
   const viz::LocalSurfaceId& local_surface_id_from_parent() {
diff --git a/third_party/blink/renderer/platform/widget/widget_base_client.h b/third_party/blink/renderer/platform/widget/widget_base_client.h
index b051eea..a3cd6c9 100644
--- a/third_party/blink/renderer/platform/widget/widget_base_client.h
+++ b/third_party/blink/renderer/platform/widget/widget_base_client.h
@@ -121,7 +121,7 @@
 
   virtual void DidHandleKeyEvent() {}
   virtual bool WillHandleGestureEvent(const WebGestureEvent& event) = 0;
-  virtual bool WillHandleMouseEvent(const WebMouseEvent& event) = 0;
+  virtual void WillHandleMouseEvent(const WebMouseEvent& event) = 0;
   virtual void ObserveGestureEventAndResult(
       const WebGestureEvent& gesture_event,
       const gfx::Vector2dF& unused_delta,
@@ -135,9 +135,6 @@
   // Called to inform the Widget of the mouse cursor's visibility.
   virtual void SetCursorVisibilityState(bool is_visible) {}
 
-  // Mouse capture has been lost.
-  virtual void MouseCaptureLost() {}
-
   // The FrameWidget interface if this is a FrameWidget.
   virtual blink::FrameWidget* FrameWidget() { return nullptr; }
 
diff --git a/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility b/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility
index f80112c..5b7fad9 100644
--- a/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility
+++ b/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility
@@ -1,215 +1,215 @@
-# tags: [ Android Fuchsia Linux Mac Mac10.12 Mac10.13 Win Win7 Win10 ]

-# tags: [ Release Debug ]

-# results: [ Timeout Crash Pass Failure Slow Skip ]

-

-# Expectations for --force-renderer-accessibility

-# crbug.com/1138028 tracks the removal of these failure expectations

-

-compositing/iframes/content-visibility-hidden-frame.html [ Crash ]

-compositing/iframes/content-visibility-hidden-div-with-frame.html [ Crash ]

-wpt_internal/display-lock/css-content-visibility/accessibility/content-visibility-accessibility-004.html [ Crash ]

-inspector-protocol/css/css-get-platform-fonts-display-locked.js [ Crash ]

-fast/forms/fieldset/overflow-scroll-interaction.html [ Crash ]

-fast/forms/color/color-picker-appearance-color-well-right-keyboard-navigation-from-bottom-left-corner.html [ Crash ]

-fast/forms/color/color-picker-appearance-color-well-left-keyboard-navigation-from-top-right-corner.html [ Crash ]

-fast/forms/color/color-picker-appearance-color-well-left-keyboard-navigation-from-bottom-right-corner.html [ Crash ]

-fast/forms/color/color-picker-appearance-color-well-right-keyboard-navigation-from-top-left-corner.html [ Crash ]

-fast/forms/color/color-picker-appearance-color-well-right-accelerated-keyboard-navigation-from-bottom-left-corner.html [ Crash ]

-fast/forms/color/color-picker-escape-cancellation-mouse-change.html [ Crash ]

-fast/forms/color/color-picker-appearance-color-well-left-accelerated-keyboard-navigation-from-top-right-corner.html [ Crash ]

-fast/forms/color/color-picker-escape-cancellation-revert.html [ Crash ]

-fast/forms/color/color-picker-appearance-color-well-up-keyboard-navigation-from-bottom-left-corner.html [ Crash ]

-fast/forms/color/color-picker-appearance-color-well-right-edge-no-right-movement.html [ Crash ]

-fast/forms/color/color-picker-appearance-color-well-drag.html [ Crash ]

-fast/forms/color/color-picker-appearance-color-well-click.html [ Crash ]

-fast/forms/color/color-picker-appearance-color-well-keyboard-navigation-after-drag.html [ Crash ]

-fast/forms/color/color-picker-appearance-color-well-left-accelerated-keyboard-navigation-from-bottom-right-corner.html [ Crash ]

-fast/forms/color/color-picker-appearance-color-well-down-accelerated-keyboard-navigation-from-top-left-corner.html [ Crash ]

-fast/forms/color/color-picker-appearance-color-well-up-accelerated-keyboard-navigation-from-bottom-left-corner.html [ Crash ]

-fast/forms/color/color-picker-appearance-color-well-down-keyboard-navigation-from-top-right-corner.html [ Crash ]

-fast/forms/color/color-picker-events-coordinates.html [ Crash ]

-fast/forms/color/color-picker-appearance-color-well-up-keyboard-navigation-from-bottom-right-corner.html [ Crash ]

-fast/forms/color/color-picker-appearance-color-well-down-keyboard-navigation-from-top-left-corner.html [ Crash ]

-fast/forms/color/color-picker-appearance-color-well-top-edge-no-up-movement.html [ Crash ]

-fast/forms/color/color-picker-appearance-color-well-down-accelerated-keyboard-navigation-from-top-right-corner.html [ Crash ]

-fast/forms/color/color-picker-appearance-color-well-left-edge-no-left-movement.html [ Crash ]

-fast/forms/color/color-picker-appearance-color-well-up-accelerated-keyboard-navigation-from-bottom-right-corner.html [ Crash ]

-fast/forms/color/color-picker-appearance-color-well-right-accelerated-keyboard-navigation-from-top-left-corner.html [ Crash ]

-fast/deprecated-flexbox/line-clamp-crash.html [ Crash ]

-fast/deprecated-flexbox/dynamically-change-line-clamp.html [ Crash ]

-fast/css-generated-content/after-with-inline-continuation.html [ Crash ]

-fast/css-generated-content/after-with-first-letter-float-crash.html [ Crash ]

-fast/css-generated-content/table-row-after-no-crash.html [ Crash ]

-fast/css-generated-content/positioned-div-with-floating-after-content-crash.html [ Crash ]

-fast/ruby/ruby-text-before-after-content.html [ Crash ]

-fast/ruby/ruby-beforeafter.html [ Crash ]

-fast/css/text-overflow-ellipsis-text-align-right.html [ Crash ]

-fast/css/text-overflow-ellipsis-strict.html [ Crash ]

-fast/css/text-overflow-ellipsis-block-with-border-and-padding.html [ Crash ]

-fast/css/vertical-text-overflow-ellipsis-text-align-justify.html [ Crash ]

-fast/css/vertical-text-overflow-ellipsis-text-align-center.html [ Crash ]

-fast/css/text-overflow-ellipsis.html [ Crash ]

-fast/css/text-overflow-ellipsis-text-align-left.html [ Crash ]

-fast/css/vertical-text-overflow-ellipsis-text-align-right.html [ Crash ]

-fast/css/text-overflow-ellipsis-text-align-center.html [ Crash ]

-fast/css/vertical-text-overflow-ellipsis-text-align-left.html [ Crash ]

-fast/css/text-overflow-ellipsis-text-align-justify.html [ Crash ]

-paint/markers/inline-spelling-markers-hidpi-composited.html [ Crash ]

-paint/markers/inline_spelling_markers.html [ Crash ]

-paint/markers/composition-marker-split.html [ Crash ]

-paint/markers/inline-spelling-markers-hidpi.html [ Crash ]

-paint/markers/active-suggestion-marker-split.html [ Crash ]

-paint/markers/suggestion-marker-split.html [ Crash ]

-external/wpt/css/css-contain/content-visibility/content-visibility-033.sub.https.html [ Crash ]

-external/wpt/css/css-text/hyphens/hyphens-manual-inline-011.html [ Crash ]

-external/wpt/css/css-text/hyphens/hyphens-manual-inline-012.html [ Crash ]

-external/wpt/css/css-text/text-transform/text-transform-upperlower-044.html [ Crash ]

-external/wpt/css/css-text/text-transform/text-transform-upperlower-041.html [ Crash ]

-external/wpt/css/css-text/text-transform/text-transform-upperlower-043.html [ Crash ]

-external/wpt/css/css-ui/text-overflow-006.html [ Crash ]

-external/wpt/css/css-ui/text-overflow-013.html [ Crash ]

-external/wpt/css/css-ui/text-overflow-028.html [ Crash ]

-external/wpt/css/css-ui/text-overflow-027.html [ Crash ]

-external/wpt/css/css-overflow/webkit-line-clamp-031.html [ Crash ]

-external/wpt/css/css-overflow/webkit-line-clamp-034.html [ Crash ]

-external/wpt/css/css-overflow/webkit-line-clamp-025.html [ Crash ]

-external/wpt/css/css-pseudo/marker-hyphens.html [ Crash ]

-external/wpt/html/semantics/forms/input-change-event-properties.html [ Crash ]

-accessibility/contenteditable-notifications.html [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-rule-color-inherit-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-clip-002.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-margin-nested-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-basic-005.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-fill-auto-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-width-count-002.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-rule-shorthand-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-003.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-height-block-child-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-rule-percent-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-count-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-basic-006.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-columns-003.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-margin-nested-firstchild-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-basic-008.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-columns-004.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-columns-006.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-rule-fraction-002.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-columns-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-clip-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-rule-fraction-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-list-item-002.html [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-rule-stacking-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-columns-005.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-collapsing-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-width-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-rule-samelength-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-width-count-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-width-small-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-margin-003.html [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-columns-002.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-shorthand-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-rule-px-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-rule-003.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-block-no-clip-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-float-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-inherit-003.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-overflowing-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-count-002.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-rule-shorthand-2.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-block-no-clip-002.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-basic-007.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-margin-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-columns-007.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-rule-color-inherit-002.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-fill-auto-003.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-margin-bottom-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-height-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-containing-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-002.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-width-ch-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-margin-002.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-rule-large-001.xht [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-size-multicol-001.html [ Crash ]

-virtual/layout_ng_block_frag/external/wpt/css/css-contain/content-visibility/content-visibility-033.sub.https.html [ Crash ]

-virtual/layout_ng_block_frag/fast/forms/fieldset/overflow-scroll-interaction.html [ Crash ]

-virtual/layout_ng_block_frag/fast/multicol/float-not-removed-crash.html [ Crash ]

-virtual/layout_ng_block_frag/fast/multicol/change-column-rule.html [ Crash ]

-virtual/layout_ng_block_frag/fast/multicol/span/anonymous-split-block-crash.html [ Crash ]

-virtual/layout_ng_block_frag/fast/multicol/span/clone-anonymous-block-non-inline-child-crash.html [ Crash ]

-virtual/layout_ng_block_frag/fast/multicol/span/anonymous-before-child-parent-crash.html [ Crash ]

-virtual/layout_ng_block_frag/fast/multicol/huge-column-gap-crash.html [ Crash ]

-virtual/layout_ng_block_frag/fast/multicol/huge-column-count.html [ Crash ]

-virtual/text-antialias/ellipsis-in-relative-inline-2.html [ Crash ]

-virtual/text-antialias/hide-atomic-inlines-after-ellipsis.html [ Crash ]

-virtual/text-antialias/hyphen-min-preferred-width.html [ Crash ]

-virtual/text-antialias/soft-hyphen-4.html [ Crash ]

-virtual/text-antialias/whitespace/whitespace-and-margin-wrap-after-list-marker-crash.html [ Crash ]

-virtual/text-antialias/text-transform-upper-lithuanian.html [ Crash ]

-virtual/text-antialias/atomic-inline-before-ellipsis.html [ Crash ]

-virtual/text-antialias/text-transform-lower-turkic.html [ Crash ]

-virtual/text-antialias/ellipsis-in-relative-inline-3.html [ Crash ]

-virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/content-visibility/content-visibility-033.sub.https.html [ Crash ]

-virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/content-visibility/content-visibility-032.html [ Crash ]

-http/tests/devtools/sources/source-frame-toolbar-items.js [ Crash ]

-http/tests/devtools/sources/debugger/rethrow-error-from-bindings-crash.js [ Crash ]

-http/tests/devtools/sources/debugger/debugger-minified-variables-evalution.js [ Crash ]

-http/tests/devtools/sources/debugger/debugger-proto-property.js [ Crash ]

-http/tests/devtools/sources/debugger/debugger-completions-on-call-frame.js [ Crash ]

-http/tests/devtools/sources/debugger/debugger-es6-harmony-scopes.js [ Crash ]

-http/tests/devtools/sources/debugger-ui/reveal-not-skipped.js [ Crash ]

-http/tests/devtools/sources/debugger-ui/debugger-save-to-temp-var.js [ Crash ]

-http/tests/devtools/sources/debugger-ui/continue-to-location-markers-in-top-level-function.js [ Crash ]

-http/tests/devtools/sources/debugger-ui/custom-element-lifecycle-events.js [ Crash ]

-http/tests/devtools/sources/debugger-ui/debugger-expand-scope.js [ Crash ]

-http/tests/devtools/sources/debugger-ui/debugger-inline-values.js [ Crash ]

-http/tests/devtools/sources/debugger-ui/watch-expressions-preserve-expansion.js [ Crash ]

-http/tests/devtools/sources/debugger-pause/debugger-pause-on-exception.js [ Crash ]

-http/tests/devtools/sources/debugger-pause/skip-pauses-until-reload.js [ Crash ]

-http/tests/devtools/sources/debugger-pause/debugger-pause-on-promise-rejection.js [ Crash ]

-http/tests/devtools/sources/debugger-pause/debugger-eval-on-call-frame-inside-iframe.js [ Crash ]

-http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await3.js [ Crash ]

-http/tests/devtools/sources/debugger-async/async-await/async-pause-on-exception.js [ Crash ]

-http/tests/devtools/sources/debugger-breakpoints/dom-breakpoints.js [ Crash ]

-http/tests/devtools/sources/debugger-breakpoints/breakpoints-in-anonymous-script-with-two-targets.js [ Crash ]

-http/tests/devtools/sources/debugger-frameworks/frameworks-dom-xhr-event-breakpoints.js [ Crash ]

-http/tests/devtools/console/console-edit-property-value.js [ Crash ]

-http/tests/devtools/console/console-save-to-temp-var.js [ Crash ]

-http/tests/devtools/console/console-proxy.js [ Crash ]

-http/tests/devtools/console/console-tainted-globals.js [ Crash ]

-http/tests/devtools/console/worker-eval-contains-stack.js [ Crash ]

-http/tests/devtools/console/console-edit-expanded-tree.js [ Crash ]

-http/tests/devtools/console/console-log-short-hand-method.js [ Crash ]

-http/tests/devtools/console/nested-worker-eval-contains-stack.js [ Crash ]

-http/tests/devtools/console/viewport-testing/console-stick-to-bottom-expand-object.js [ Crash ]

-http/tests/devtools/console/viewport-testing/console-key-expand.js [ Crash ]

-http/tests/devtools/console/console-format-es6-2.js [ Crash ]

-http/tests/devtools/console/console-top-level-await.js [ Crash ]

-http/tests/devtools/console/exception-objects.js [ Crash ]

-http/tests/devtools/console/console-smart-enter.js [ Crash ]

-http/tests/devtools/console/console-uncaught-promise.js [ Crash ]

-http/tests/devtools/console/console-dirxml.js [ Crash ]

-http/tests/devtools/console/console-truncate-long-messages.js [ Crash ]

-http/tests/devtools/console/console-eval-object-literal.js [ Crash ]

-http/tests/devtools/console/console-format-es6.js [ Crash ]

-http/tests/devtools/console/console-format-array-prototype.js [ Crash ]

-http/tests/devtools/console/console-dir.js [ Crash ]

-http/tests/devtools/console/console-big-array.js [ Crash ]

-http/tests/devtools/console/console-call-getter-on-proto.js [ Crash ]

-http/tests/devtools/console/console-functions.js [ Crash ]

-http/tests/devtools/console/console-format-broken-unicode.js [ Crash ]

-http/tests/devtools/console/console-log-object-with-getter.js [ Crash ]

-http/tests/devtools/console/console-dir-es6.js [ Crash ]

-http/tests/devtools/indexeddb/live-update-indexeddb-content.js [ Crash ]

-http/tests/devtools/indexeddb/delete-entry.js [ Crash ]

-http/tests/devtools/network/network-disable-cache-xhrs.js [ Crash ]

-http/tests/devtools/network/network-cachedresources-with-same-urls.js [ Crash ]

-http/tests/devtools/network/cached-resource-destroyed-too-big-discarded.js [ Crash ]

-http/tests/devtools/network/network-timing.js [ Crash ]

-http/tests/devtools/network/async-xhr-json-mime-type.js [ Crash ]

-http/tests/devtools/network/cached-resource-destroyed-moved-to-storage.js [ Crash ]

-http/tests/devtools/unit/text-prompt-hint.js [ Crash ]

-http/tests/devtools/sxg/sxg-navigation-redirect.js [ Crash ]

-http/tests/devtools/elements/styles-1/color-aware-property-value-edit.js [ Crash ]

-http/tests/devtools/elements/shadow/shadow-distribution.js [ Crash ]

-http/tests/devtools/elements/highlight/highlight-display-locked-in-frame.js [ Crash ]

+# tags: [ Android Fuchsia Linux Mac Mac10.12 Mac10.13 Win Win7 Win10 ]
+# tags: [ Release Debug ]
+# results: [ Timeout Crash Pass Failure Slow Skip ]
+
+# Expectations for --force-renderer-accessibility
+# crbug.com/1138028 tracks the removal of these failure expectations
+
+compositing/iframes/content-visibility-hidden-frame.html [ Crash ]
+compositing/iframes/content-visibility-hidden-div-with-frame.html [ Crash ]
+wpt_internal/display-lock/css-content-visibility/accessibility/content-visibility-accessibility-004.html [ Crash ]
+inspector-protocol/css/css-get-platform-fonts-display-locked.js [ Crash ]
+fast/forms/fieldset/overflow-scroll-interaction.html [ Crash ]
+fast/forms/color/color-picker-appearance-color-well-right-keyboard-navigation-from-bottom-left-corner.html [ Crash ]
+fast/forms/color/color-picker-appearance-color-well-left-keyboard-navigation-from-top-right-corner.html [ Crash ]
+fast/forms/color/color-picker-appearance-color-well-left-keyboard-navigation-from-bottom-right-corner.html [ Crash ]
+fast/forms/color/color-picker-appearance-color-well-right-keyboard-navigation-from-top-left-corner.html [ Crash ]
+fast/forms/color/color-picker-appearance-color-well-right-accelerated-keyboard-navigation-from-bottom-left-corner.html [ Crash ]
+fast/forms/color/color-picker-escape-cancellation-mouse-change.html [ Crash ]
+fast/forms/color/color-picker-appearance-color-well-left-accelerated-keyboard-navigation-from-top-right-corner.html [ Crash ]
+fast/forms/color/color-picker-escape-cancellation-revert.html [ Crash ]
+fast/forms/color/color-picker-appearance-color-well-up-keyboard-navigation-from-bottom-left-corner.html [ Crash ]
+fast/forms/color/color-picker-appearance-color-well-right-edge-no-right-movement.html [ Crash ]
+fast/forms/color/color-picker-appearance-color-well-drag.html [ Crash ]
+fast/forms/color/color-picker-appearance-color-well-click.html [ Crash ]
+fast/forms/color/color-picker-appearance-color-well-keyboard-navigation-after-drag.html [ Crash ]
+fast/forms/color/color-picker-appearance-color-well-left-accelerated-keyboard-navigation-from-bottom-right-corner.html [ Crash ]
+fast/forms/color/color-picker-appearance-color-well-down-accelerated-keyboard-navigation-from-top-left-corner.html [ Crash ]
+fast/forms/color/color-picker-appearance-color-well-up-accelerated-keyboard-navigation-from-bottom-left-corner.html [ Crash ]
+fast/forms/color/color-picker-appearance-color-well-down-keyboard-navigation-from-top-right-corner.html [ Crash ]
+fast/forms/color/color-picker-events-coordinates.html [ Crash ]
+fast/forms/color/color-picker-appearance-color-well-up-keyboard-navigation-from-bottom-right-corner.html [ Crash ]
+fast/forms/color/color-picker-appearance-color-well-down-keyboard-navigation-from-top-left-corner.html [ Crash ]
+fast/forms/color/color-picker-appearance-color-well-top-edge-no-up-movement.html [ Crash ]
+fast/forms/color/color-picker-appearance-color-well-down-accelerated-keyboard-navigation-from-top-right-corner.html [ Crash ]
+fast/forms/color/color-picker-appearance-color-well-left-edge-no-left-movement.html [ Crash ]
+fast/forms/color/color-picker-appearance-color-well-up-accelerated-keyboard-navigation-from-bottom-right-corner.html [ Crash ]
+fast/forms/color/color-picker-appearance-color-well-right-accelerated-keyboard-navigation-from-top-left-corner.html [ Crash ]
+fast/deprecated-flexbox/line-clamp-crash.html [ Crash ]
+fast/deprecated-flexbox/dynamically-change-line-clamp.html [ Crash ]
+fast/css-generated-content/after-with-inline-continuation.html [ Crash ]
+fast/css-generated-content/after-with-first-letter-float-crash.html [ Crash ]
+fast/css-generated-content/table-row-after-no-crash.html [ Crash ]
+fast/css-generated-content/positioned-div-with-floating-after-content-crash.html [ Crash ]
+fast/ruby/ruby-text-before-after-content.html [ Crash ]
+fast/ruby/ruby-beforeafter.html [ Crash ]
+fast/css/text-overflow-ellipsis-text-align-right.html [ Crash ]
+fast/css/text-overflow-ellipsis-strict.html [ Crash ]
+fast/css/text-overflow-ellipsis-block-with-border-and-padding.html [ Crash ]
+fast/css/vertical-text-overflow-ellipsis-text-align-justify.html [ Crash ]
+fast/css/vertical-text-overflow-ellipsis-text-align-center.html [ Crash ]
+fast/css/text-overflow-ellipsis.html [ Crash ]
+fast/css/text-overflow-ellipsis-text-align-left.html [ Crash ]
+fast/css/vertical-text-overflow-ellipsis-text-align-right.html [ Crash ]
+fast/css/text-overflow-ellipsis-text-align-center.html [ Crash ]
+fast/css/vertical-text-overflow-ellipsis-text-align-left.html [ Crash ]
+fast/css/text-overflow-ellipsis-text-align-justify.html [ Crash ]
+paint/markers/inline-spelling-markers-hidpi-composited.html [ Crash ]
+paint/markers/inline_spelling_markers.html [ Crash ]
+paint/markers/composition-marker-split.html [ Crash ]
+paint/markers/inline-spelling-markers-hidpi.html [ Crash ]
+paint/markers/active-suggestion-marker-split.html [ Crash ]
+paint/markers/suggestion-marker-split.html [ Crash ]
+external/wpt/css/css-contain/content-visibility/content-visibility-033.sub.https.html [ Crash ]
+external/wpt/css/css-text/hyphens/hyphens-manual-inline-011.html [ Crash ]
+external/wpt/css/css-text/hyphens/hyphens-manual-inline-012.html [ Crash ]
+external/wpt/css/css-text/text-transform/text-transform-upperlower-044.html [ Crash ]
+external/wpt/css/css-text/text-transform/text-transform-upperlower-041.html [ Crash ]
+external/wpt/css/css-text/text-transform/text-transform-upperlower-043.html [ Crash ]
+external/wpt/css/css-ui/text-overflow-006.html [ Crash ]
+external/wpt/css/css-ui/text-overflow-013.html [ Crash ]
+external/wpt/css/css-ui/text-overflow-028.html [ Crash ]
+external/wpt/css/css-ui/text-overflow-027.html [ Crash ]
+external/wpt/css/css-overflow/webkit-line-clamp-031.html [ Crash ]
+external/wpt/css/css-overflow/webkit-line-clamp-034.html [ Crash ]
+external/wpt/css/css-overflow/webkit-line-clamp-025.html [ Crash ]
+external/wpt/css/css-pseudo/marker-hyphens.html [ Crash ]
+external/wpt/html/semantics/forms/input-change-event-properties.html [ Crash ]
+accessibility/contenteditable-notifications.html [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-rule-color-inherit-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-clip-002.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-margin-nested-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-basic-005.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-fill-auto-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-width-count-002.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-rule-shorthand-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-003.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-height-block-child-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-rule-percent-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-count-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-basic-006.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-columns-003.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-margin-nested-firstchild-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-basic-008.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-columns-004.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-columns-006.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-rule-fraction-002.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-columns-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-clip-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-rule-fraction-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-list-item-002.html [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-rule-stacking-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-columns-005.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-collapsing-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-width-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-rule-samelength-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-width-count-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-width-small-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-margin-003.html [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-columns-002.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-shorthand-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-rule-px-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-rule-003.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-block-no-clip-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-float-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-inherit-003.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-overflowing-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-count-002.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-rule-shorthand-2.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-block-no-clip-002.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-basic-007.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-margin-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-columns-007.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-rule-color-inherit-002.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-fill-auto-003.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-margin-bottom-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-height-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-containing-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-002.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-width-ch-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-margin-002.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-rule-large-001.xht [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-contain/contain-size-multicol-001.html [ Crash ]
+virtual/layout_ng_block_frag/external/wpt/css/css-contain/content-visibility/content-visibility-033.sub.https.html [ Crash ]
+virtual/layout_ng_block_frag/fast/forms/fieldset/overflow-scroll-interaction.html [ Crash ]
+virtual/layout_ng_block_frag/fast/multicol/float-not-removed-crash.html [ Crash ]
+virtual/layout_ng_block_frag/fast/multicol/change-column-rule.html [ Crash ]
+virtual/layout_ng_block_frag/fast/multicol/span/anonymous-split-block-crash.html [ Crash ]
+virtual/layout_ng_block_frag/fast/multicol/span/clone-anonymous-block-non-inline-child-crash.html [ Crash ]
+virtual/layout_ng_block_frag/fast/multicol/span/anonymous-before-child-parent-crash.html [ Crash ]
+virtual/layout_ng_block_frag/fast/multicol/huge-column-gap-crash.html [ Crash ]
+virtual/layout_ng_block_frag/fast/multicol/huge-column-count.html [ Crash ]
+virtual/text-antialias/ellipsis-in-relative-inline-2.html [ Crash ]
+virtual/text-antialias/hide-atomic-inlines-after-ellipsis.html [ Crash ]
+virtual/text-antialias/hyphen-min-preferred-width.html [ Crash ]
+virtual/text-antialias/soft-hyphen-4.html [ Crash ]
+virtual/text-antialias/whitespace/whitespace-and-margin-wrap-after-list-marker-crash.html [ Crash ]
+virtual/text-antialias/text-transform-upper-lithuanian.html [ Crash ]
+virtual/text-antialias/atomic-inline-before-ellipsis.html [ Crash ]
+virtual/text-antialias/text-transform-lower-turkic.html [ Crash ]
+virtual/text-antialias/ellipsis-in-relative-inline-3.html [ Crash ]
+virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/content-visibility/content-visibility-033.sub.https.html [ Crash ]
+virtual/layout_ng_fragment_traversal/external/wpt/css/css-contain/content-visibility/content-visibility-032.html [ Crash ]
+http/tests/devtools/sources/source-frame-toolbar-items.js [ Crash ]
+http/tests/devtools/sources/debugger/rethrow-error-from-bindings-crash.js [ Crash ]
+http/tests/devtools/sources/debugger/debugger-minified-variables-evalution.js [ Crash ]
+http/tests/devtools/sources/debugger/debugger-proto-property.js [ Crash ]
+http/tests/devtools/sources/debugger/debugger-completions-on-call-frame.js [ Crash ]
+http/tests/devtools/sources/debugger/debugger-es6-harmony-scopes.js [ Crash ]
+http/tests/devtools/sources/debugger-ui/reveal-not-skipped.js [ Crash ]
+http/tests/devtools/sources/debugger-ui/debugger-save-to-temp-var.js [ Crash ]
+http/tests/devtools/sources/debugger-ui/continue-to-location-markers-in-top-level-function.js [ Crash ]
+http/tests/devtools/sources/debugger-ui/custom-element-lifecycle-events.js [ Crash ]
+http/tests/devtools/sources/debugger-ui/debugger-expand-scope.js [ Crash ]
+http/tests/devtools/sources/debugger-ui/debugger-inline-values.js [ Crash ]
+http/tests/devtools/sources/debugger-ui/watch-expressions-preserve-expansion.js [ Crash ]
+http/tests/devtools/sources/debugger-pause/debugger-pause-on-exception.js [ Crash ]
+http/tests/devtools/sources/debugger-pause/skip-pauses-until-reload.js [ Crash ]
+http/tests/devtools/sources/debugger-pause/debugger-pause-on-promise-rejection.js [ Crash ]
+http/tests/devtools/sources/debugger-pause/debugger-eval-on-call-frame-inside-iframe.js [ Crash ]
+http/tests/devtools/sources/debugger-async/async-await/async-callstack-async-await3.js [ Crash ]
+http/tests/devtools/sources/debugger-async/async-await/async-pause-on-exception.js [ Crash ]
+http/tests/devtools/sources/debugger-breakpoints/dom-breakpoints.js [ Crash ]
+http/tests/devtools/sources/debugger-breakpoints/breakpoints-in-anonymous-script-with-two-targets.js [ Crash ]
+http/tests/devtools/sources/debugger-frameworks/frameworks-dom-xhr-event-breakpoints.js [ Crash ]
+http/tests/devtools/console/console-edit-property-value.js [ Crash ]
+http/tests/devtools/console/console-save-to-temp-var.js [ Crash ]
+http/tests/devtools/console/console-proxy.js [ Crash ]
+http/tests/devtools/console/console-tainted-globals.js [ Crash ]
+http/tests/devtools/console/worker-eval-contains-stack.js [ Crash ]
+http/tests/devtools/console/console-edit-expanded-tree.js [ Crash ]
+http/tests/devtools/console/console-log-short-hand-method.js [ Crash ]
+http/tests/devtools/console/nested-worker-eval-contains-stack.js [ Crash ]
+http/tests/devtools/console/viewport-testing/console-stick-to-bottom-expand-object.js [ Crash ]
+http/tests/devtools/console/viewport-testing/console-key-expand.js [ Crash ]
+http/tests/devtools/console/console-format-es6-2.js [ Crash ]
+http/tests/devtools/console/console-top-level-await.js [ Crash ]
+http/tests/devtools/console/exception-objects.js [ Crash ]
+http/tests/devtools/console/console-smart-enter.js [ Crash ]
+http/tests/devtools/console/console-uncaught-promise.js [ Crash ]
+http/tests/devtools/console/console-dirxml.js [ Crash ]
+http/tests/devtools/console/console-truncate-long-messages.js [ Crash ]
+http/tests/devtools/console/console-eval-object-literal.js [ Crash ]
+http/tests/devtools/console/console-format-es6.js [ Crash ]
+http/tests/devtools/console/console-format-array-prototype.js [ Crash ]
+http/tests/devtools/console/console-dir.js [ Crash ]
+http/tests/devtools/console/console-big-array.js [ Crash ]
+http/tests/devtools/console/console-call-getter-on-proto.js [ Crash ]
+http/tests/devtools/console/console-functions.js [ Crash ]
+http/tests/devtools/console/console-format-broken-unicode.js [ Crash ]
+http/tests/devtools/console/console-log-object-with-getter.js [ Crash ]
+http/tests/devtools/console/console-dir-es6.js [ Crash ]
+http/tests/devtools/indexeddb/live-update-indexeddb-content.js [ Crash ]
+http/tests/devtools/indexeddb/delete-entry.js [ Crash ]
+http/tests/devtools/network/network-disable-cache-xhrs.js [ Crash ]
+http/tests/devtools/network/network-cachedresources-with-same-urls.js [ Crash ]
+http/tests/devtools/network/cached-resource-destroyed-too-big-discarded.js [ Crash ]
+http/tests/devtools/network/network-timing.js [ Crash ]
+http/tests/devtools/network/async-xhr-json-mime-type.js [ Crash ]
+http/tests/devtools/network/cached-resource-destroyed-moved-to-storage.js [ Crash ]
+http/tests/devtools/unit/text-prompt-hint.js [ Crash ]
+http/tests/devtools/sxg/sxg-navigation-redirect.js [ Crash ]
+http/tests/devtools/elements/styles-1/color-aware-property-value-edit.js [ Crash ]
+http/tests/devtools/elements/shadow/shadow-distribution.js [ Crash ]
+http/tests/devtools/elements/highlight/highlight-display-locked-in-frame.js [ Crash ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 229fbf0..2f6d8d5 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -2631,6 +2631,7 @@
 crbug.com/958381 [ Mac ] external/wpt/css/CSS2/tables/table-anonymous-objects-206.xht [ Failure ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 [ Mac10.15 ] virtual/threaded/external/wpt/animation-worklet/worklet-animation-local-time-null-2.https.html [ Failure ]
 crbug.com/626703 external/wpt/infrastructure/testdriver/actions/iframe.html [ Timeout ]
 crbug.com/626703 external/wpt/infrastructure/testdriver/actions/crossOrigin.sub.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/html/semantics/embedded-content/media-elements/preserves-pitch.html [ Timeout ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
index 0c242e2..0739e14c 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -172927,7 +172927,7 @@
       []
      ],
      "otpcredential-helper.js": [
-      "3cf4510585d61c683e78140452ad8fe3fd9150fe",
+      "0c6ce8b1f38ca321900efae35a53977da9370acb",
       []
      ],
      "otpcredential-iframe.html": [
@@ -206077,7 +206077,7 @@
       []
      ],
      "cssstyledeclaration-custom-properties-expected.txt": [
-      "bf3d544556516f9558ce0ed786685c937f83b0f9",
+      "8594790fd714eb3ba5d0580d4532f71e7d69f2e3",
       []
      ],
      "cssstyledeclaration-properties-expected.txt": [
@@ -206089,7 +206089,7 @@
       []
      ],
      "getComputedStyle-detached-subtree-expected.txt": [
-      "54aa713bb71272a388086270b9335ac86fc97e37",
+      "dd133f578f21c273840a1dcff71d8a59d9a6b10b",
       []
      ],
      "getComputedStyle-insets-absolute-expected.txt": [
@@ -232818,7 +232818,7 @@
      []
     ],
     "MediaRecorder-stop-expected.txt": [
-     "456c138116c929ecd0f4fc3d23c95ee83e32b71e",
+     "ad4d44b24755b2e26f7ce22669edd930647ddc67",
      []
     ],
     "OWNERS": [
@@ -237241,7 +237241,7 @@
       []
      ],
      "mock-sms-receiver.js": [
-      "c4aa9a86f2c8a15303f96cc9859b2ec146eb2f58",
+      "903456d6830481cfd8d977120105359d4fc43774",
       []
      ],
      "mock-textdetection.js": [
@@ -242632,7 +242632,7 @@
        []
       ],
       "github_checks_output.py": [
-       "b34e33dd9e817a80ac60a022fbfb6f0cb9c13766",
+       "fcc6f8ce5911a24ee761889b184da42a03485071",
        []
       ],
       "sink_task.py": [
@@ -370622,13 +370622,6 @@
       {}
      ]
     ],
-    "longtask-before-observer.window.js": [
-     "b7d4eb9d1de1ac1b91a2e6c9b5d124413b6dc0b9",
-     [
-      "longtask-timing/longtask-before-observer.window.html",
-      {}
-     ]
-    ],
     "longtask-in-childiframe-crossorigin.html": [
      "d0fdf742804d722a6682e8f2b455284dc83fa4b9",
      [
@@ -372992,7 +372985,7 @@
      ]
     ],
     "MediaRecorder-stop.html": [
-     "ad6fa8809f6ad3af26969bbcb6a761280e5d705c",
+     "7e19bc0c054472fdf8161bff41f99f2e601c0abb",
      [
       null,
       {}
diff --git a/third_party/blink/web_tests/external/wpt/mediacapture-record/MediaRecorder-stop-expected.txt b/third_party/blink/web_tests/external/wpt/mediacapture-record/MediaRecorder-stop-expected.txt
index 456c138..ad4d44b2 100644
--- a/third_party/blink/web_tests/external/wpt/mediacapture-record/MediaRecorder-stop-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/mediacapture-record/MediaRecorder-stop-expected.txt
@@ -1,9 +1,9 @@
 This is a testharness.js-based test.
 PASS MediaRecorder will stop recording and fire a stop event when all tracks are ended
 PASS MediaRecorder will stop recording and fire a stop event when stop() is called
-PASS MediaRecorder will fire an exception when stopped after creation
-PASS MediaRecorder will fire an exception when stopped after having just been stopped
-PASS MediaRecorder will fire an exception when stopped after having just been spontaneously stopped
+FAIL MediaRecorder will not fire an exception when stopped after creation promise_test: Unhandled rejection with value: object "InvalidStateError: Failed to execute 'stop' on 'MediaRecorder': The MediaRecorder's state is 'inactive'."
+FAIL MediaRecorder will not fire an exception when stopped after having just been stopped promise_test: Unhandled rejection with value: object "InvalidStateError: Failed to execute 'stop' on 'MediaRecorder': The MediaRecorder's state is 'inactive'."
+FAIL MediaRecorder will not fire an exception when stopped after having just been spontaneously stopped promise_test: Unhandled rejection with value: object "InvalidStateError: Failed to execute 'stop' on 'MediaRecorder': The MediaRecorder's state is 'inactive'."
 FAIL MediaRecorder will fire start event even if stopped synchronously promise_test: Unhandled rejection with value: object "TypeError: Cannot read property 'getUserMedia' of undefined"
 FAIL MediaRecorder will fire start event even if a track is removed synchronously promise_test: Unhandled rejection with value: object "TypeError: Cannot read property 'getUserMedia' of undefined"
 Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/mediacapture-record/MediaRecorder-stop.html b/third_party/blink/web_tests/external/wpt/mediacapture-record/MediaRecorder-stop.html
index ad6fa88..7e19bc0 100644
--- a/third_party/blink/web_tests/external/wpt/mediacapture-record/MediaRecorder-stop.html
+++ b/third_party/blink/web_tests/external/wpt/mediacapture-record/MediaRecorder-stop.html
@@ -83,24 +83,24 @@
 
     promise_test(async t => {
         const recorder = new MediaRecorder(createVideoStream());
-        assert_throws_dom("InvalidStateError", () => { recorder.stop(); });
+        recorder.stop();
         await Promise.race([
             new Promise((_, reject) => recorder.onstop =
                 _ => reject(new Error("onstop should never have been called"))),
             new Promise(r => t.step_timeout(r, 0))]);
-    }, "MediaRecorder will fire an exception when stopped after creation");
+    }, "MediaRecorder will not fire an exception when stopped after creation");
 
     promise_test(async t => {
         const recorder = new MediaRecorder(createVideoStream());
         recorder.start();
         recorder.stop();
         let event = await new Promise(r => recorder.onstop = r);
-        assert_throws_dom("InvalidStateError", () => { recorder.stop(); });
+        recorder.stop();
         await Promise.race([
             new Promise((_, reject) => recorder.onstop =
                 _ => reject(new Error("onstop should never have been called"))),
             new Promise(r => t.step_timeout(r, 0))]);
-    }, "MediaRecorder will fire an exception when stopped after having just been stopped");
+    }, "MediaRecorder will not fire an exception when stopped after having just been stopped");
 
     promise_test(async t => {
         const stream = createVideoStream();
@@ -108,12 +108,12 @@
         recorder.start();
         stream.getVideoTracks()[0].stop();
         let event = await new Promise(r => recorder.onstop = r);
-        assert_throws_dom("InvalidStateError", () => { recorder.stop(); });
+        recorder.stop();
         await Promise.race([
             new Promise((_, reject) => recorder.onstop =
                 _ => reject(new Error("onstop should never have been called"))),
             new Promise(r => t.step_timeout(r, 0))]);
-    }, "MediaRecorder will fire an exception when stopped after having just been spontaneously stopped");
+    }, "MediaRecorder will not fire an exception when stopped after having just been spontaneously stopped");
 
     promise_test(async t => {
         const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true });
diff --git a/third_party/blink/web_tests/external/wpt/tools/ci/tc/github_checks_output.py b/third_party/blink/web_tests/external/wpt/tools/ci/tc/github_checks_output.py
index b34e33dd..fcc6f8ce 100644
--- a/third_party/blink/web_tests/external/wpt/tools/ci/tc/github_checks_output.py
+++ b/third_party/blink/web_tests/external/wpt/tools/ci/tc/github_checks_output.py
@@ -1,9 +1,11 @@
+import io
+from six import ensure_text
+
 MYPY = False
 if MYPY:
     # MYPY is set to True when run under Mypy.
-    from typing import Any
-    from typing import Optional
-    from typing import Text
+    from typing import AnyStr, Optional, Text
+
 
 class GitHubChecksOutputter(object):
     """Provides a method to output data to be shown in the GitHub Checks UI.
@@ -12,23 +14,27 @@
     to enable developers to quickly understand what has gone wrong. The output
     supports markdown format.
 
-    See https://docs.taskcluster.net/docs/reference/integrations/github/checks#custom-text-output-in-checks
+    https://docs.taskcluster.net/docs/reference/integrations/github/checks#custom-text-output-in-checks
     """
     def __init__(self, path):
         # type: (Text) -> None
         self.path = path
 
     def output(self, line):
-        # type: (Any) -> None
-        # TODO(stephenmcgruer): Once mypy 0.790 is released, we can change this
-        # to AnyStr, as that release teaches mypy about the mode flags of open.
-        # See https://github.com/python/typeshed/pull/4146
-        with open(self.path, 'a') as f:
-            f.write(line)
-            f.write('\n')
+        # type: (AnyStr) -> None
+        text = ensure_text(line)
+        # NOTE: mypy types the "text mode" of open() in Python 2 as BinaryIO,
+        # which makes sense as we cannot specify its encoding (it's
+        # platform-dependent), while io.open() is closer to open() in Python 3.
+        # TODO: use the built-in open() when we are Py3-only.
+        with io.open(self.path, mode="a") as f:
+            f.write(text)
+            f.write(u"\n")
 
 
 __outputter = None
+
+
 def get_gh_checks_outputter(filepath):
     # type: (Optional[Text]) -> Optional[GitHubChecksOutputter]
     """Return the outputter for GitHub Checks output, if enabled.
diff --git a/third_party/closure_compiler/closure_args.gni b/third_party/closure_compiler/closure_args.gni
index 55d57471..b4e511e 100644
--- a/third_party/closure_compiler/closure_args.gni
+++ b/third_party/closure_compiler/closure_args.gni
@@ -57,6 +57,22 @@
   "chrome_pass=false",
 ]
 
+mojom_js_args = [
+  "js_module_root=gen/mojo/public/js/",
+  "js_module_root=gen/mojom-webui/",
+
+  # Mojom WebUI JS modules load bindings.js which may be compiled and stripped
+  # of type annotations. Rewrite these references to the uncompiled equivalent
+  # for compilation and type-checking.
+  "browser_resolver_prefix_replacements=\"chrome://resources/mojo/mojo/public/js/bindings.js=/bindings_uncompiled.js\"",
+
+  # Shared Mojom WebUI JS modules are by convention exposed through URLs like
+  # chrome://resources/mojo/<path-to-module>. At build time these will be given
+  # as gen/<path-to-module> for compilation, so we can rewrite them as absolute
+  # paths.
+  "browser_resolver_prefix_replacements=\"chrome://resources/mojo/=/\"",
+]
+
 polymer3_args = js_modules_args + [
                   "browser_resolver_prefix_replacements=\"../polymer/polymer_bundled.min.js=../polymer/polymer_bundled.js\"",
                   "browser_resolver_prefix_replacements=\"chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js=../../third_party/polymer/v3_0/components-chromium/polymer/polymer_bundled.js\"",
diff --git a/third_party/libgav1/BUILD.gn b/third_party/libgav1/BUILD.gn
index 431e195..e58224e 100644
--- a/third_party/libgav1/BUILD.gn
+++ b/third_party/libgav1/BUILD.gn
@@ -39,7 +39,7 @@
   }
 }
 
-if (enable_libgav1_decoder) {
+if (enable_libgav1_decoder || use_libgav1_parser) {
   # Separate from libgav1 because utils/constants.cc and dsp/constants.cc
   # generate the same object file, constants.o.
   source_set("libgav1_utils") {
@@ -64,6 +64,7 @@
 
     sources = gav1_dsp_sources
   }
+
   static_library("libgav1") {
     configs -= [ "//build/config/compiler:chromium_code" ]
     configs += [ "//build/config/compiler:no_chromium_code" ]
diff --git a/third_party/libgav1/options.gni b/third_party/libgav1/options.gni
index 32498968..2e5a582 100644
--- a/third_party/libgav1/options.gni
+++ b/third_party/libgav1/options.gni
@@ -8,4 +8,6 @@
   # Enable libgav1 decoder.
   enable_libgav1_decoder =
       is_chromeos && (target_cpu == "arm" || target_cpu == "arm64")
+  use_libgav1_parser =
+      is_chromeos && (target_cpu == "x86" || target_cpu == "x64")
 }
diff --git a/third_party/openxr/BUILD.gn b/third_party/openxr/BUILD.gn
index 1b2f2e4..7c1161d 100644
--- a/third_party/openxr/BUILD.gn
+++ b/third_party/openxr/BUILD.gn
@@ -24,6 +24,7 @@
       "src/src/common/extra_algorithms.h",
       "src/src/common/filesystem_utils.cpp",
       "src/src/common/filesystem_utils.hpp",
+      "src/src/common/hex_and_handles.cpp",
       "src/src/common/hex_and_handles.h",
       "src/src/common/loader_interfaces.h",
       "src/src/common/object_info.cpp",
@@ -58,10 +59,6 @@
       "src/src",
     ]
 
-    if (is_win) {
-      libs = [ "Pathcch.lib" ]
-    }
-
     deps = [ "//third_party/jsoncpp" ]
 
     public_configs = [ ":config" ]
@@ -76,7 +73,6 @@
       "-Wno-microsoft-cast",
       "-Wno-microsoft-include",
       "-Wno-unused-function",
-      "-Wno-extra-semi",
     ]
   }
 
diff --git a/third_party/openxr/README.chromium b/third_party/openxr/README.chromium
index 4c83f87..9500a9d 100644
--- a/third_party/openxr/README.chromium
+++ b/third_party/openxr/README.chromium
@@ -1,8 +1,8 @@
 Name: OpenXR SDK
 Short Name: OpenXR
 URL: https://github.com/KhronosGroup/OpenXR-SDK
-Version: 1.0.11sd
-Revision: e3a4e41d61544d8e2eba73f00da99b6818ec472b
+Version: 1.0.5sd
+Revision: 9e97b73e7dd2bfc07745489d728f6a36665c648f
 License: Apache 2.0
 License File: src/LICENSE
 Security Critical: yes
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec
index 86b1096..6fb5d5b 100644
--- a/tools/gritsettings/resource_ids.spec
+++ b/tools/gritsettings/resource_ids.spec
@@ -484,6 +484,9 @@
   "content/shell/shell_resources.grd": {
     "includes": [2940],
   },
+  "content/test/web_ui_mojo_test_resources.grd": {
+    "includes": [2950],
+  },
 
   # This file is generated during the build.
   "<(SHARED_INTERMEDIATE_DIR)/content/browser/tracing/tracing_resources.grd": {
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 0e1aede..452188ed 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -70544,6 +70544,9 @@
 </enum>
 
 <enum name="SyncEventCode">
+  <obsolete>
+    Removed 2020-10.
+  </obsolete>
   <summary>
     Sync UI events. The codes are listed in profile_syncer_service.h with more
     details.
@@ -73450,6 +73453,10 @@
   <int value="9" label="kTest"/>
   <int value="10" label="kWebScriptExec"/>
   <int value="11" label="kVoiceSearch"/>
+  <int value="12" label="kExtensionMessagingBothPrivileged"/>
+  <int value="13" label="kExtensionMessagingSenderPrivileged"/>
+  <int value="14" label="kExtensionMessagingReceiverPrivileged"/>
+  <int value="15" label="kExtensionMessagingNeitherPrivileged"/>
 </enum>
 
 <enum name="UserCertContentDisposition">
diff --git a/tools/metrics/histograms/histograms_xml/accessibility/histograms.xml b/tools/metrics/histograms/histograms_xml/accessibility/histograms.xml
index d01c265..722dc7c 100644
--- a/tools/metrics/histograms/histograms_xml/accessibility/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/accessibility/histograms.xml
@@ -424,6 +424,17 @@
   </summary>
 </histogram>
 
+<histogram name="Accessibility.FocusHighlight.ToggleEnabled"
+    enum="BooleanEnabled" expires_after="2021-03-31">
+  <owner>aboxhall@chromium.org</owner>
+  <owner>chrome-a11y-core@google.com</owner>
+  <summary>
+    The value of the &quot;show a quick focus highlight&quot; setting, logged
+    immediately after toggling. This will show us how often users are turning
+    the feature on, and how often they are turning it back off again.
+  </summary>
+</histogram>
+
 <histogram name="Accessibility.ImageLabels" enum="BooleanEnabled"
     expires_after="M89">
   <owner>katie@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/apps/OWNERS b/tools/metrics/histograms/histograms_xml/apps/OWNERS
new file mode 100644
index 0000000..c5805f3
--- /dev/null
+++ b/tools/metrics/histograms/histograms_xml/apps/OWNERS
@@ -0,0 +1,7 @@
+# Prefer chromium-metrics-reviews@google.com instead.
+# Use the following owners only if:
+#  - The reviewer is available for review.
+#  - You work in the same area as them.
+#  - They are already a good reviewer for the non-metrics part of the CL.
+# See tools/metrics/histograms/histograms_xml/OWNERS for details.
+tby@chromium.org
diff --git a/tools/metrics/histograms/histograms_xml/ash/OWNERS b/tools/metrics/histograms/histograms_xml/ash/OWNERS
new file mode 100644
index 0000000..c5805f3
--- /dev/null
+++ b/tools/metrics/histograms/histograms_xml/ash/OWNERS
@@ -0,0 +1,7 @@
+# Prefer chromium-metrics-reviews@google.com instead.
+# Use the following owners only if:
+#  - The reviewer is available for review.
+#  - You work in the same area as them.
+#  - They are already a good reviewer for the non-metrics part of the CL.
+# See tools/metrics/histograms/histograms_xml/OWNERS for details.
+tby@chromium.org
diff --git a/tools/metrics/histograms/histograms_xml/auto/OWNERS b/tools/metrics/histograms/histograms_xml/auto/OWNERS
new file mode 100644
index 0000000..c5805f3
--- /dev/null
+++ b/tools/metrics/histograms/histograms_xml/auto/OWNERS
@@ -0,0 +1,7 @@
+# Prefer chromium-metrics-reviews@google.com instead.
+# Use the following owners only if:
+#  - The reviewer is available for review.
+#  - You work in the same area as them.
+#  - They are already a good reviewer for the non-metrics part of the CL.
+# See tools/metrics/histograms/histograms_xml/OWNERS for details.
+tby@chromium.org
diff --git a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml
index 79ea37c2..721136b2 100644
--- a/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml
+++ b/tools/metrics/histograms/histograms_xml/histogram_suffixes_list.xml
@@ -2747,18 +2747,6 @@
   <affected-histogram name="CloudPrint.UrlFetcherUploadSize"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="CodecInfo" separator=".">
-  <suffix name="H264.4k.Hw" label=""/>
-  <suffix name="H264.4k.Sw" label=""/>
-  <suffix name="H264.Hd.Hw" label=""/>
-  <suffix name="H264.Hd.Sw" label=""/>
-  <suffix name="Vp9.4k.Hw" label=""/>
-  <suffix name="Vp9.4k.Sw" label=""/>
-  <suffix name="Vp9.Hd.Hw" label=""/>
-  <suffix name="Vp9.Hd.Sw" label=""/>
-  <affected-histogram name="WebRTC.Video.DecodeTimePerFrameInMs"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="CompositingLCDTextDisabledCountSuffixes"
     separator=".">
   <obsolete>
@@ -9393,17 +9381,6 @@
   <affected-histogram name="NativeFileSystemAPI.WritePermissionRequestOutcome"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="NativeWindowVisibility" separator=".">
-  <suffix name="Hidden"
-      label="The native window is not visible because it is in a minimized
-             window"/>
-  <suffix name="Occluded"
-      label="The native window is fully covered by other windows"/>
-  <suffix name="Visible"
-      label="The native window is visible or partially visible."/>
-  <affected-histogram name="Windows.NativeWindowVisibility"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="NatType" separator=".">
   <suffix name="NoNAT" label=""/>
   <suffix name="NonSymNAT" label=""/>
@@ -13849,49 +13826,6 @@
   <affected-histogram name="UMA.PersistentAllocator.Allocs"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="PersistentMemoryErrors" separator="."
-    ordering="prefix,2">
-  <suffix name="BrowserMetrics" label="For browser process metrics."/>
-  <suffix name="CrashpadMetrics" label="For metrics from Crashpad."/>
-  <suffix name="FieldTrialAllocator" label="For field-trial allocator."/>
-  <suffix name="GpuMetrics" label="For GPU process metrics."/>
-  <suffix name="NotificationHelperMetrics"
-      label="For notification_helper process metrics."/>
-  <suffix name="PpapiBrokerMetrics"
-      label="For &quot;PPAPI broker&quot; process metrics."/>
-  <suffix name="PpapiPluginMetrics"
-      label="For &quot;PPAPI plugin&quot; process metrics."/>
-  <suffix name="RendererMetrics" label="For renderer process metrics."/>
-  <suffix name="SandboxHelperMetrics"
-      label="For &quot;sandbox helper&quot; process metrics."/>
-  <suffix name="SetupMetrics" label="For setup metrics."/>
-  <suffix name="UtilityMetrics"
-      label="For &quot;utility&quot; process metrics."/>
-  <suffix name="ZygoteMetrics" label="For &quot;zygote&quot; process metrics."/>
-  <affected-histogram name="UMA.PersistentAllocator.Errors"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="PersistentMemoryUsedPct" separator="."
-    ordering="prefix,2">
-  <suffix name="BrowserMetrics" label="For browser process metrics."/>
-  <suffix name="FieldTrialAllocator" label="For field-trial allocator."/>
-  <suffix name="GpuMetrics" label="For GPU process metrics."/>
-  <suffix name="NotificationHelperMetrics"
-      label="For notification_helper process metrics."/>
-  <suffix name="PpapiBrokerMetrics"
-      label="For &quot;PPAPI broker&quot; process metrics."/>
-  <suffix name="PpapiPluginMetrics"
-      label="For &quot;PPAPI plugin&quot; process metrics."/>
-  <suffix name="RendererMetrics" label="For renderer process metrics."/>
-  <suffix name="SandboxHelperMetrics"
-      label="For &quot;sandbox helper&quot; process metrics."/>
-  <suffix name="SetupMetrics" label="For setup metrics."/>
-  <suffix name="UtilityMetrics"
-      label="For &quot;utility&quot; process metrics."/>
-  <suffix name="ZygoteMetrics" label="For &quot;zygote&quot; process metrics."/>
-  <affected-histogram name="UMA.PersistentAllocator.UsedPct"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="PhoneHubFeature" separator=".">
   <suffix name="NotificationBadge" label="Notification badge sub-feature.">
     <obsolete>
@@ -19306,16 +19240,6 @@
   <affected-histogram name="Net.TrustTokens.RequestHelperFactoryOutcome"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="UkmSourceIdTypes" separator=".">
-  <suffix name="App" label="Restricted to app source id types."/>
-  <suffix name="Default" label="Restricted to default source id type."/>
-  <suffix name="Navigation" label="Restricted to navigation source id types."/>
-  <suffix name="Ukm"
-      label="Restricted to UKM source id types. Deprecated and replaced by
-             'Default' in 2020/05."/>
-  <affected-histogram name="UKM.Sources.SerializedCount2"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="UnconsentedPrimaryAccountType" separator=".">
   <suffix name="NoSyncConsumer" label="A consumer account, no sync."/>
   <suffix name="NoSyncEnterprise" label="An enterprise account, no sync."/>
@@ -19405,20 +19329,6 @@
   <affected-histogram name="V8.WasmModuleSizeBytes"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="VariationsHeadersURLValidationResult" separator=".">
-  <suffix name="Append"
-      label="Result when checking whether to append a header."/>
-  <suffix name="Remove"
-      label="Result when checking whether to remove a header."/>
-  <affected-histogram name="Variations.Headers.URLValidationResult"/>
-</histogram_suffixes>
-
-<histogram_suffixes name="VideoAdaptationReason" separator=".">
-  <suffix name="Cpu" label="Adapt reason: CPU."/>
-  <suffix name="Quality" label="Adapt reason: quality."/>
-  <affected-histogram name="WebRTC.Video.AdaptChangesPerMinute"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="VideoCaptureFrameDrop" separator=".">
   <suffix name="DeviceCapture" label=""/>
   <suffix name="DisplayCapture" label=""/>
@@ -19448,28 +19358,6 @@
   <affected-histogram name="Media.VideoDecodeStatsDB.OpTiming"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="VideoEncodedQpStats" separator=".">
-  <suffix name="H264"
-      label="Video codec: H264. QP range: 0-51. No spatial layers."/>
-  <suffix name="Vp8"
-      label="Video codec: VP8. QP range: 0-127. Single stream sent."/>
-  <suffix name="Vp8.S0"
-      label="Video codec: VP8. QP range: 0-127. Spatial index 0."/>
-  <suffix name="Vp8.S1"
-      label="Video codec: VP8. QP range: 0-127. Spatial index 1."/>
-  <suffix name="Vp8.S2"
-      label="Video codec: VP8. QP range: 0-127. Spatial index 2."/>
-  <suffix name="Vp9"
-      label="Video codec: VP9. QP range: 0-255. No spatial layers."/>
-  <suffix name="Vp9.S0"
-      label="Video codec: VP9. QP range: 0-255. Spatial layer 0."/>
-  <suffix name="Vp9.S1"
-      label="Video codec: VP9. QP range: 0-255. Spatial layer 1."/>
-  <suffix name="Vp9.S2"
-      label="Video codec: VP9. QP range: 0-255. Spatial layer 2."/>
-  <affected-histogram name="WebRTC.Video.Encoded.Qp"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="VideoFrameRateRange" separator=".">
   <suffix name="24fps" label="24 fps"/>
   <suffix name="25fps" label="25 fps"/>
@@ -19744,17 +19632,6 @@
   <affected-histogram name="Media.UnderflowDuration2"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="WebRtcCodecs" separator=".">
-  <suffix name="Av1" label=""/>
-  <suffix name="Generic" label=""/>
-  <suffix name="H264" label=""/>
-  <suffix name="Multiplex" label=""/>
-  <suffix name="Vp8" label=""/>
-  <suffix name="Vp9" label=""/>
-  <affected-histogram
-      name="WebRTC.Video.HardwareDecodedFramesBetweenSoftwareFallbacks"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="WebRTCEchoCancellerEstimate" separator=".">
   <suffix name="Max" label="The maximum over the time interval"/>
   <suffix name="Min" label="The minimum over the time interval"/>
@@ -19777,16 +19654,6 @@
   <affected-histogram name="WebRTC.Audio.EchoCanceller.SuppressorGainBand1"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="WebRtcLoggingEvent" separator=".">
-  <suffix name="Discard" label="Discard"/>
-  <suffix name="Start" label="Start"/>
-  <suffix name="UploadFailed" label="Upload failed"/>
-  <suffix name="UploadStarted" label="Upload started"/>
-  <suffix name="UploadStoredStarted" label="Upload of a stored log started"/>
-  <suffix name="UploadSuccessful" label="Upload successful"/>
-  <affected-histogram name="WebRtcTextLogging"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="WebRTCMediaType" separator=".">
   <suffix name="Audio" label="Audio"/>
   <suffix name="Data" label="Data"/>
diff --git a/tools/metrics/histograms/histograms_xml/local/OWNERS b/tools/metrics/histograms/histograms_xml/local/OWNERS
new file mode 100644
index 0000000..c5805f3
--- /dev/null
+++ b/tools/metrics/histograms/histograms_xml/local/OWNERS
@@ -0,0 +1,7 @@
+# Prefer chromium-metrics-reviews@google.com instead.
+# Use the following owners only if:
+#  - The reviewer is available for review.
+#  - You work in the same area as them.
+#  - They are already a good reviewer for the non-metrics part of the CL.
+# See tools/metrics/histograms/histograms_xml/OWNERS for details.
+tby@chromium.org
diff --git a/tools/metrics/histograms/histograms_xml/media/histograms.xml b/tools/metrics/histograms/histograms_xml/media/histograms.xml
index 141f43d..2d23ddf9 100644
--- a/tools/metrics/histograms/histograms_xml/media/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/media/histograms.xml
@@ -127,7 +127,7 @@
 </histogram>
 
 <histogram name="Media.Audio.Autoplay" enum="AutoplaySource"
-    expires_after="2020-04-05">
+    expires_after="2021-06-01">
   <owner>mlamouri@chromium.org</owner>
   <owner>media-dev@chromium.org</owner>
   <summary>Records the autoplay source of audios.</summary>
@@ -3405,7 +3405,7 @@
 </histogram>
 
 <histogram name="Media.Video.Autoplay" enum="AutoplaySource"
-    expires_after="2021-04-01">
+    expires_after="2021-06-01">
   <owner>mlamouri@google.com</owner>
   <owner>media-dev@chromium.org</owner>
   <summary>
@@ -3415,14 +3415,14 @@
 </histogram>
 
 <histogram name="Media.Video.Autoplay.Muted" enum="AutoplaySource"
-    expires_after="2021-04-01">
+    expires_after="2021-06-01">
   <owner>mlamouri@google.com</owner>
   <owner>media-dev@chromium.org</owner>
   <summary>Records the autoplay source of muted videos.</summary>
 </histogram>
 
 <histogram name="Media.Video.Autoplay.Muted.PlayMethod.BecomesVisible"
-    enum="Boolean" expires_after="2021-04-01">
+    enum="Boolean" expires_after="2021-06-01">
   <owner>mlamouri@google.com</owner>
   <owner>media-dev@chromium.org</owner>
   <summary>
@@ -3435,7 +3435,7 @@
 </histogram>
 
 <histogram name="Media.Video.Autoplay.Muted.PlayMethod.OffscreenDuration"
-    units="ms" expires_after="2021-04-01">
+    units="ms" expires_after="2021-06-01">
   <owner>mlamouri@google.com</owner>
   <owner>media-dev@chromium.org</owner>
   <summary>
@@ -3445,7 +3445,7 @@
 </histogram>
 
 <histogram name="Media.Video.Autoplay.Muted.UnmuteAction" enum="BooleanSuccess"
-    expires_after="2021-04-01">
+    expires_after="2021-06-01">
   <owner>mlamouri@google.com</owner>
   <owner>media-dev@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/others/OWNERS b/tools/metrics/histograms/histograms_xml/others/OWNERS
index 0ed37e86..0f60bbb 100644
--- a/tools/metrics/histograms/histograms_xml/others/OWNERS
+++ b/tools/metrics/histograms/histograms_xml/others/OWNERS
@@ -3,5 +3,6 @@
 #  - The reviewer is available for review.
 #  - You work in the same area as them.
 #  - They are already a good reviewer for the non-metrics part of the CL.
-# See tools/metrics/histograms/OWNERS for details.
+# See tools/metrics/histograms/histograms_xml/OWNERS for details.
 tbansal@chromium.org
+tby@chromium.org
diff --git a/tools/metrics/histograms/histograms_xml/others/histograms.xml b/tools/metrics/histograms/histograms_xml/others/histograms.xml
index 5f6bd69..c42b419 100644
--- a/tools/metrics/histograms/histograms_xml/others/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/others/histograms.xml
@@ -7023,9 +7023,10 @@
 </histogram>
 
 <histogram base="true" name="JSDialogs.Scheme" enum="NavigationScheme"
-    expires_after="2020-11-15">
+    expires_after="2021-06-01">
   <owner>avi@chromium.org</owner>
   <owner>carlosil@chromium.org</owner>
+  <owner>ericmill@google.com</owner>
   <owner>meacer@chromium.org</owner>
   <summary>The scheme of the URL showing a JavaScript dialog.</summary>
 </histogram>
diff --git a/tools/metrics/histograms/histograms_xml/password/histograms.xml b/tools/metrics/histograms/histograms_xml/password/histograms.xml
index 1486f21..0aa742b 100644
--- a/tools/metrics/histograms/histograms_xml/password/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/password/histograms.xml
@@ -845,7 +845,7 @@
 </histogram>
 
 <histogram name="PasswordManager.CompromisedCredentials" enum="CompromiseType"
-    expires_after="2020-11-26">
+    expires_after="2021-04-26">
   <owner>bdea@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -1824,7 +1824,7 @@
 </histogram>
 
 <histogram name="PasswordManager.RemoveCompromisedCredentials.RemoveReason"
-    enum="RemoveCompromisedCredentialsReason" expires_after="2020-11-26">
+    enum="RemoveCompromisedCredentialsReason" expires_after="2021-04-04">
   <owner>bdea@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/histograms_xml/power/OWNERS b/tools/metrics/histograms/histograms_xml/power/OWNERS
new file mode 100644
index 0000000..c5805f3
--- /dev/null
+++ b/tools/metrics/histograms/histograms_xml/power/OWNERS
@@ -0,0 +1,7 @@
+# Prefer chromium-metrics-reviews@google.com instead.
+# Use the following owners only if:
+#  - The reviewer is available for review.
+#  - You work in the same area as them.
+#  - They are already a good reviewer for the non-metrics part of the CL.
+# See tools/metrics/histograms/histograms_xml/OWNERS for details.
+tby@chromium.org
diff --git a/tools/metrics/histograms/histograms_xml/sync/histograms.xml b/tools/metrics/histograms/histograms_xml/sync/histograms.xml
index fd130e5..85ec85f 100644
--- a/tools/metrics/histograms/histograms_xml/sync/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/sync/histograms.xml
@@ -365,7 +365,10 @@
 </histogram>
 
 <histogram name="Sync.EventCodes" enum="SyncEventCode"
-    expires_after="2021-04-04">
+    expires_after="2020-10-13">
+  <obsolete>
+    Removed as of 10/2020.
+  </obsolete>
   <owner>mastiz@chromium.org</owner>
   <owner>treib@chromium.org</owner>
   <summary>A UI event occured.</summary>
diff --git a/tools/metrics/histograms/histograms_xml/ukm/histograms.xml b/tools/metrics/histograms/histograms_xml/ukm/histograms.xml
index 39ffa16..e65ccf47 100644
--- a/tools/metrics/histograms/histograms_xml/ukm/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/ukm/histograms.xml
@@ -226,11 +226,23 @@
   </summary>
 </histogram>
 
-<histogram name="UKM.Sources.SerializedCount2" units="sources"
-    expires_after="2021-02-14">
+<histogram name="UKM.Sources.SerializedCount2{UkmSourceIdTypes}"
+    units="sources" expires_after="2021-02-14">
   <owner>rkaplow@chromium.org</owner>
   <owner>ukm-team@google.com</owner>
-  <summary>Number of serialized UKM sources when storing a UKM log.</summary>
+  <summary>
+    Number of serialized UKM sources when storing a UKM log. {UkmSourceIdTypes}
+  </summary>
+  <token key="UkmSourceIdTypes">
+    <variant name=""/>
+    <variant name=".App" summary="Restricted to app source id types."/>
+    <variant name=".Default" summary="Restricted to default source id type."/>
+    <variant name=".Navigation"
+        summary="Restricted to navigation source id types."/>
+    <variant name=".Ukm"
+        summary="Restricted to UKM source id types. Deprecated and replaced
+                 by 'Default' in 2020/05."/>
+  </token>
 </histogram>
 
 <histogram name="UKM.Sources.UnmatchedSourcesCount" units="sources"
diff --git a/tools/metrics/histograms/histograms_xml/uma/histograms.xml b/tools/metrics/histograms/histograms_xml/uma/histograms.xml
index a5cc51e..3911db14 100644
--- a/tools/metrics/histograms/histograms_xml/uma/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/uma/histograms.xml
@@ -355,26 +355,75 @@
   </summary>
 </histogram>
 
-<histogram base="true" name="UMA.PersistentAllocator.Errors"
+<histogram name="UMA.PersistentAllocator.{PersistentMemoryErrors}Errors"
     enum="PersistentAllocatorErrors" expires_after="M85">
   <owner>bcwhite@chromium.org</owner>
   <owner>asvitkine@chromium.org</owner>
   <owner>src/base/metrics/OWNERS</owner>
   <summary>
     Errors detected by the persistent memory allocator. These are set when they
-    occur.
+    occur. {PersistentMemoryErrors}
   </summary>
+  <token key="PersistentMemoryErrors">
+    <variant name="">
+      <obsolete>
+        Base histogram. Use suffixes of this histogram instead.
+      </obsolete>
+    </variant>
+    <variant name="BrowserMetrics." summary="For browser process metrics."/>
+    <variant name="CrashpadMetrics." summary="For metrics from Crashpad."/>
+    <variant name="FieldTrialAllocator." summary="For field-trial allocator."/>
+    <variant name="GpuMetrics." summary="For GPU process metrics."/>
+    <variant name="NotificationHelperMetrics."
+        summary="For notification_helper process metrics."/>
+    <variant name="PpapiBrokerMetrics."
+        summary="For &quot;PPAPI broker&quot; process metrics."/>
+    <variant name="PpapiPluginMetrics."
+        summary="For &quot;PPAPI plugin&quot; process metrics."/>
+    <variant name="RendererMetrics." summary="For renderer process metrics."/>
+    <variant name="SandboxHelperMetrics."
+        summary="For &quot;sandbox helper&quot; process metrics."/>
+    <variant name="SetupMetrics." summary="For setup metrics."/>
+    <variant name="UtilityMetrics."
+        summary="For &quot;utility&quot; process metrics."/>
+    <variant name="ZygoteMetrics."
+        summary="For &quot;zygote&quot; process metrics."/>
+  </token>
 </histogram>
 
-<histogram base="true" name="UMA.PersistentAllocator.UsedPct" units="%"
-    expires_after="M87">
+<histogram name="UMA.PersistentAllocator.{PersistentMemoryUsedPct}UsedPct"
+    units="%" expires_after="M87">
   <owner>bcwhite@chromium.org</owner>
   <owner>asvitkine@chromium.org</owner>
   <owner>src/base/metrics/OWNERS</owner>
   <summary>
     Percentage of persistent memory segment that has been allocated. This is
-    updated only once per reporting cycle.
+    updated only once per reporting cycle. {PersistentMemoryUsedPct}
   </summary>
+  <token key="PersistentMemoryUsedPct">
+    <variant name="">
+      <obsolete>
+        Base histogram. Use suffixes of this histogram instead.
+      </obsolete>
+    </variant>
+    <variant name="BrowserMetrics." summary="For browser process metrics."/>
+    <variant name="FieldTrialAllocator." summary="For field-trial allocator."/>
+    <variant name="GpuMetrics." summary="For GPU process metrics."/>
+    <variant name="NotificationHelperMetrics."
+        summary="For notification_helper process metrics."/>
+    <variant name="PpapiBrokerMetrics."
+        summary="For &quot;PPAPI broker&quot; process metrics."/>
+    <variant name="PpapiPluginMetrics."
+        summary="For &quot;PPAPI plugin&quot; process metrics."/>
+    <variant name="RendererMetrics." summary="For renderer process metrics."/>
+    <variant name="SandboxHelperMetrics."
+        summary="For &quot;sandbox helper&quot; process metrics."/>
+    <variant name="SetupMetrics." summary="For setup metrics."/>
+    <variant name="UtilityMetrics."
+        summary="For &quot;utility&quot; process metrics."/>
+    <variant name="ZygoteMetrics."
+        summary="For &quot;zygote&quot; process metrics."/>
+  </token>
 </histogram>
 
 <histogram name="UMA.PersistentHistograms.InitResult"
diff --git a/tools/metrics/histograms/histograms_xml/variations/histograms.xml b/tools/metrics/histograms/histograms_xml/variations/histograms.xml
index fe3b5b61..faf8fb9e 100644
--- a/tools/metrics/histograms/histograms_xml/variations/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/variations/histograms.xml
@@ -157,7 +157,8 @@
   </summary>
 </histogram>
 
-<histogram base="true" name="Variations.Headers.URLValidationResult"
+<histogram
+    name="Variations.Headers.URLValidationResult{VariationsHeadersURLValidationResult}"
     enum="VariationsHeadersURLValidationResult" expires_after="2020-12-15">
   <owner>asvitkine@chromium.org</owner>
   <owner>jwd@chromium.org</owner>
@@ -167,8 +168,19 @@
     when determining (i) whether the URL to which the request is being sent
     should have a variations header and (ii) whether--after a redirect--the
     request to which a variations header was added should have the variations
-    header removed.
+    header removed. {VariationsHeadersURLValidationResult}
   </summary>
+  <token key="VariationsHeadersURLValidationResult">
+    <variant name="">
+      <obsolete>
+        Base histogram. Use suffixes of this histogram instead.
+      </obsolete>
+    </variant>
+    <variant name=".Append"
+        summary="Result when checking whether to append a header."/>
+    <variant name=".Remove"
+        summary="Result when checking whether to remove a header."/>
+  </token>
 </histogram>
 
 <histogram name="Variations.LoadPermanentConsistencyCountryResult"
diff --git a/tools/metrics/histograms/histograms_xml/web_audio/histograms.xml b/tools/metrics/histograms/histograms_xml/web_audio/histograms.xml
index a9eef438..a8413d5 100644
--- a/tools/metrics/histograms/histograms_xml/web_audio/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/web_audio/histograms.xml
@@ -128,7 +128,7 @@
 </histogram>
 
 <histogram name="WebAudio.Autoplay" enum="WebAudioAutoplayStatus"
-    expires_after="M87">
+    expires_after="2021-06-01">
   <owner>mlamouri@google.com</owner>
   <owner>media-dev@chromium.org</owner>
   <owner>rtoy@chromium.org</owner>
@@ -141,7 +141,7 @@
 </histogram>
 
 <histogram name="WebAudio.Autoplay.CrossOrigin" enum="WebAudioAutoplayStatus"
-    expires_after="M87">
+    expires_after="2021-06-01">
   <owner>mlamouri@google.com</owner>
   <owner>media-dev@chromium.org</owner>
   <owner>rtoy@chromium.org</owner>
@@ -153,7 +153,7 @@
 </histogram>
 
 <histogram name="WebAudio.Autoplay.UnlockType"
-    enum="WebAudioAutoplayUnlockType" expires_after="M87">
+    enum="WebAudioAutoplayUnlockType" expires_after="2021-06-01">
   <owner>mlamouri@google.com</owner>
   <owner>media-dev@chromium.org</owner>
   <owner>rtoy@chromium.org</owner>
diff --git a/tools/metrics/histograms/histograms_xml/web_rtc/histograms.xml b/tools/metrics/histograms/histograms_xml/web_rtc/histograms.xml
index 19c918d..b91ed87 100644
--- a/tools/metrics/histograms/histograms_xml/web_rtc/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/web_rtc/histograms.xml
@@ -1591,16 +1591,21 @@
   </summary>
 </histogram>
 
-<histogram name="WebRTC.Video.AdaptChangesPerMinute" units="changes/minute"
-    expires_after="never">
+<histogram name="WebRTC.Video.AdaptChangesPerMinute{VideoAdaptationReason}"
+    units="changes/minute" expires_after="never">
 <!-- expires-never: WebRTC health metric. -->
 
   <owner>asapersson@chromium.org</owner>
   <owner>webrtc-video@google.com</owner>
   <summary>
     The average number of adaptation changes per minute for a sent video stream.
-    Recorded when a stream is removed.
+    Recorded when a stream is removed. {VideoAdaptationReason}
   </summary>
+  <token key="VideoAdaptationReason">
+    <variant name=""/>
+    <variant name=".Cpu" summary="Adapt reason: CPU."/>
+    <variant name=".Quality" summary="Adapt reason: quality."/>
+  </token>
 </histogram>
 
 <histogram name="WebRTC.Video.AverageRoundTripTimeInMilliseconds" units="ms"
@@ -1730,13 +1735,28 @@
   </summary>
 </histogram>
 
-<histogram base="true" name="WebRTC.Video.DecodeTimePerFrameInMs" units="ms"
+<histogram name="WebRTC.Video.DecodeTimePerFrameInMs{CodecInfo}" units="ms"
     expires_after="2021-02-28">
   <owner>kron@chromium.org</owner>
   <summary>
     The decode time per frame for a received video stream. Continously updated
-    after each frame has been decoded.
+    after each frame has been decoded. {CodecInfo}
   </summary>
+  <token key="CodecInfo">
+    <variant name="">
+      <obsolete>
+        Base histogram. Use suffixes of this histogram instead.
+      </obsolete>
+    </variant>
+    <variant name=".H264.4k.Hw" summary=""/>
+    <variant name=".H264.4k.Sw" summary=""/>
+    <variant name=".H264.Hd.Hw" summary=""/>
+    <variant name=".H264.Hd.Sw" summary=""/>
+    <variant name=".Vp9.4k.Hw" summary=""/>
+    <variant name=".Vp9.4k.Sw" summary=""/>
+    <variant name=".Vp9.Hd.Hw" summary=""/>
+    <variant name=".Vp9.Hd.Sw" summary=""/>
+  </token>
 </histogram>
 
 <histogram name="WebRTC.Video.DelayedFramesToRenderer" units="%"
@@ -1821,15 +1841,36 @@
   </summary>
 </histogram>
 
-<histogram name="WebRTC.Video.Encoded.Qp" units="qp value"
+<histogram name="WebRTC.Video.Encoded.Qp{VideoEncodedQpStats}" units="qp value"
     expires_after="never">
 <!-- expires-never: WebRTC health metric. -->
 
   <owner>asapersson@chromium.org</owner>
   <summary>
     The average QP (quantizer value) per frame for a sent video stream. Recorded
-    when a stream is removed.
+    when a stream is removed. {VideoEncodedQpStats}
   </summary>
+  <token key="VideoEncodedQpStats">
+    <variant name=""/>
+    <variant name=".H264"
+        summary="Video codec: H264. QP range: 0-51. No spatial layers."/>
+    <variant name=".Vp8"
+        summary="Video codec: VP8. QP range: 0-127. Single stream sent."/>
+    <variant name=".Vp8.S0"
+        summary="Video codec: VP8. QP range: 0-127. Spatial index 0."/>
+    <variant name=".Vp8.S1"
+        summary="Video codec: VP8. QP range: 0-127. Spatial index 1."/>
+    <variant name=".Vp8.S2"
+        summary="Video codec: VP8. QP range: 0-127. Spatial index 2."/>
+    <variant name=".Vp9"
+        summary="Video codec: VP9. QP range: 0-255. No spatial layers."/>
+    <variant name=".Vp9.S0"
+        summary="Video codec: VP9. QP range: 0-255. Spatial layer 0."/>
+    <variant name=".Vp9.S1"
+        summary="Video codec: VP9. QP range: 0-255. Spatial layer 1."/>
+    <variant name=".Vp9.S2"
+        summary="Video codec: VP9. QP range: 0-255. Spatial layer 2."/>
+  </token>
 </histogram>
 
 <histogram name="WebRTC.Video.Encoder.CodecType" enum="WebRtcVideoCodecs"
@@ -1956,15 +1997,28 @@
   </summary>
 </histogram>
 
-<histogram base="true"
-    name="WebRTC.Video.HardwareDecodedFramesBetweenSoftwareFallbacks"
+<histogram
+    name="WebRTC.Video.HardwareDecodedFramesBetweenSoftwareFallbacks{WebRtcCodecs}"
     units="frames" expires_after="2021-03-16">
   <owner>kron@chromium.org</owner>
   <owner>webrtc-video@google.com</owner>
   <summary>
     The number of hardware decoded frames between fallbacks to software decoder
-    for a received video stream.
+    for a received video stream. {WebRtcCodecs}
   </summary>
+  <token key="WebRtcCodecs">
+    <variant name="">
+      <obsolete>
+        Base histogram. Use suffixes of this histogram instead.
+      </obsolete>
+    </variant>
+    <variant name=".Av1" summary=""/>
+    <variant name=".Generic" summary=""/>
+    <variant name=".H264" summary=""/>
+    <variant name=".Multiplex" summary=""/>
+    <variant name=".Vp8" summary=""/>
+    <variant name=".Vp9" summary=""/>
+  </token>
 </histogram>
 
 <histogram name="WebRTC.Video.InputFramesPerSecond" units="fps"
@@ -3264,16 +3318,6 @@
   </summary>
 </histogram>
 
-<histogram base="true" name="WebRtcTextLogging"
-    enum="WebRtcLoggingWebAppIdHash" expires_after="2021-06-01">
-  <owner>guidou@chromium.org</owner>
-  <owner>webrtc-dev@chromium.org</owner>
-  <summary>
-    Counts the number of WebRTC text log events per web application. Suffixed by
-    event.
-  </summary>
-</histogram>
-
 <histogram name="WebRtcTextLogging.UploadFailureNetErrorCode"
     enum="NetErrorCodes" expires_after="2021-06-01">
   <owner>guidou@chromium.org</owner>
@@ -3295,6 +3339,30 @@
   </summary>
 </histogram>
 
+<histogram name="WebRtcTextLogging{WebRtcLoggingEvent}"
+    enum="WebRtcLoggingWebAppIdHash" expires_after="2021-06-01">
+  <owner>guidou@chromium.org</owner>
+  <owner>webrtc-dev@chromium.org</owner>
+  <summary>
+    Counts the number of WebRTC text log events per web application. Suffixed by
+    event. {WebRtcLoggingEvent}
+  </summary>
+  <token key="WebRtcLoggingEvent">
+    <variant name="">
+      <obsolete>
+        Base histogram. Use suffixes of this histogram instead.
+      </obsolete>
+    </variant>
+    <variant name=".Discard" summary="Discard"/>
+    <variant name=".Start" summary="Start"/>
+    <variant name=".UploadFailed" summary="Upload failed"/>
+    <variant name=".UploadStarted" summary="Upload started"/>
+    <variant name=".UploadStoredStarted"
+        summary="Upload of a stored log started"/>
+    <variant name=".UploadSuccessful" summary="Upload successful"/>
+  </token>
+</histogram>
+
 </histograms>
 
 </histogram-configuration>
diff --git a/tools/metrics/histograms/histograms_xml/windows/histograms.xml b/tools/metrics/histograms/histograms_xml/windows/histograms.xml
index d77bde2..73d24af 100644
--- a/tools/metrics/histograms/histograms_xml/windows/histograms.xml
+++ b/tools/metrics/histograms/histograms_xml/windows/histograms.xml
@@ -188,15 +188,25 @@
   </summary>
 </histogram>
 
-<histogram name="Windows.NativeWindowVisibility" units="windows"
-    expires_after="2021-02-01">
+<histogram name="Windows.NativeWindowVisibility{NativeWindowVisibility}"
+    units="windows" expires_after="2021-02-01">
   <owner>davidbienvenu@chromium.org</owner>
   <owner>fdoray@chromium.org</owner>
   <summary>
     The number of Chrome browser windows in a given visibility state. This is
     computed using ComputeNativeWindowOcclusionStatus() and is recorded every 10
-    minutes.
+    minutes. {NativeWindowVisibility}
   </summary>
+  <token key="NativeWindowVisibility">
+    <variant name=""/>
+    <variant name=".Hidden"
+        summary="The native window is not visible because it is in a
+                 minimized window"/>
+    <variant name=".Occluded"
+        summary="The native window is fully covered by other windows"/>
+    <variant name=".Visible"
+        summary="The native window is visible or partially visible."/>
+  </token>
 </histogram>
 
 <histogram name="Windows.OOPSelectFileDialog.ProcessError" enum="BooleanError"
diff --git a/tools/metrics/histograms/suffixes_to_variants.py b/tools/metrics/histograms/suffixes_to_variants.py
index 54a14b67..af4f204c 100644
--- a/tools/metrics/histograms/suffixes_to_variants.py
+++ b/tools/metrics/histograms/suffixes_to_variants.py
@@ -31,10 +31,7 @@
 
 def _ExtractOwnerNodes(node):
   """Extracts all owners from |node|. Returns None if not exists."""
-  owners = node.getElementsByTagName('owner')
-  if not owners:
-    return None
-  return owners
+  return node.getElementsByTagName('owner')
 
 
 def _RemoveSuffixesComment(node, histogram_suffixes_name):
@@ -223,7 +220,7 @@
   return paths
 
 
-def SuffixesToVariantsMigation(args):
+def SuffixesToVariantsMigration(args):
   """Migates all histogram suffixes to patterned histograms."""
   histogram_suffixes_list = minidom.parse(open(HISTOGRAM_SUFFIXES_LIST_PATH))
   histogram_suffixes_nodes = histogram_suffixes_list.getElementsByTagName(
@@ -269,4 +266,4 @@
   args = parser.parse_args()
   assert len(args.start) == 1 and len(args.end) == 1, (
       'start and end flag should only contain a single letter.')
-  SuffixesToVariantsMigation(args)
+  SuffixesToVariantsMigration(args)
diff --git a/tools/perf/core/bot_platforms.py b/tools/perf/core/bot_platforms.py
index 0331c94f..c98a5555 100644
--- a/tools/perf/core/bot_platforms.py
+++ b/tools/perf/core/bot_platforms.py
@@ -333,7 +333,7 @@
 ])
 _MAC_HIGH_END_EXECUTABLE_CONFIGS = frozenset([
     _base_perftests(),
-    _dawn_perf_tests(),
+    _dawn_perf_tests(330),
     _media_perftests(),
     _net_perftests(),
     _performance_browser_tests(),
@@ -359,7 +359,7 @@
     _angle_perftests(),
     _base_perftests(),
     _components_perftests(),
-    _dawn_perf_tests(),
+    _dawn_perf_tests(600),
     _media_perftests(),
     _views_perftests(),
 ])
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index d29c8239..1969e9ff 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,12 +5,12 @@
             "remote_path": "perfetto_binaries/trace_processor_shell/win/935a915963e1482109b102c82585d78c12112b31/trace_processor_shell.exe"
         },
         "mac": {
-            "hash": "6813eb2daae90337ab8677136a57f14db7b4517c",
-            "remote_path": "perfetto_binaries/trace_processor_shell/mac/ca4153fa8b09210e26af59a6c9136c32fb60876f/trace_processor_shell"
+            "hash": "eedc74edfa9a270f9253e946efe24eedda17a19f",
+            "remote_path": "perfetto_binaries/trace_processor_shell/mac/7411aeba4d3b11872828b8b15ac9bfddd63f4e6c/trace_processor_shell"
         },
         "linux": {
             "hash": "3de252246e71082910ec46bb45676946ccdd447d",
-            "remote_path": "perfetto_binaries/trace_processor_shell/linux/ca4153fa8b09210e26af59a6c9136c32fb60876f/trace_processor_shell"
+            "remote_path": "perfetto_binaries/trace_processor_shell/linux/7411aeba4d3b11872828b8b15ac9bfddd63f4e6c/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/ui/accessibility/ax_mode.cc b/ui/accessibility/ax_mode.cc
index 7919464..c4121222 100644
--- a/ui/accessibility/ax_mode.cc
+++ b/ui/accessibility/ax_mode.cc
@@ -6,6 +6,7 @@
 
 #include <vector>
 
+#include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
 
 namespace ui {
@@ -15,13 +16,13 @@
 }
 
 std::string AXMode::ToString() const {
-  std::vector<std::string> tokens;
+  std::vector<base::StringPiece> tokens;
 
   // Written as a loop with a switch so that this crashes if a new
   // mode flag is added without adding support for logging it.
   for (uint32_t mode_flag = AXMode::kFirstModeFlag;
        mode_flag <= AXMode::kLastModeFlag; mode_flag = mode_flag << 1) {
-    const char* flag_name = nullptr;
+    base::StringPiece flag_name;
     switch (mode_flag) {
       case AXMode::kNativeAPIs:
         flag_name = "kNativeAPIs";
@@ -46,7 +47,7 @@
         break;
     }
 
-    DCHECK(flag_name);
+    DCHECK(!flag_name.empty());
 
     if (has_mode(mode_flag))
       tokens.push_back(flag_name);
diff --git a/ui/base/ime/chromeos/mock_component_extension_ime_manager_delegate.cc b/ui/base/ime/chromeos/mock_component_extension_ime_manager_delegate.cc
index 99647f9..a3dbe56 100644
--- a/ui/base/ime/chromeos/mock_component_extension_ime_manager_delegate.cc
+++ b/ui/base/ime/chromeos/mock_component_extension_ime_manager_delegate.cc
@@ -8,19 +8,21 @@
 namespace chromeos {
 namespace input_method {
 
-MockComponentExtIMEManagerDelegate::MockComponentExtIMEManagerDelegate() {}
+MockComponentExtensionIMEManagerDelegate::
+    MockComponentExtensionIMEManagerDelegate() {}
 
-MockComponentExtIMEManagerDelegate::~MockComponentExtIMEManagerDelegate() =
-    default;
+MockComponentExtensionIMEManagerDelegate::
+    ~MockComponentExtensionIMEManagerDelegate() = default;
 
 std::vector<ComponentExtensionIME>
-    MockComponentExtIMEManagerDelegate::ListIME() {
+MockComponentExtensionIMEManagerDelegate::ListIME() {
   return ime_list_;
 }
 
-void MockComponentExtIMEManagerDelegate::Load(Profile* profile,
-                                              const std::string& extension_id,
-                                              const std::string& manifest,
-                                              const base::FilePath& path) {}
+void MockComponentExtensionIMEManagerDelegate::Load(
+    Profile* profile,
+    const std::string& extension_id,
+    const std::string& manifest,
+    const base::FilePath& path) {}
 }  // namespace input_method
 }  // namespace chromeos
diff --git a/ui/base/ime/chromeos/mock_component_extension_ime_manager_delegate.h b/ui/base/ime/chromeos/mock_component_extension_ime_manager_delegate.h
index 280e021..2b6967c 100644
--- a/ui/base/ime/chromeos/mock_component_extension_ime_manager_delegate.h
+++ b/ui/base/ime/chromeos/mock_component_extension_ime_manager_delegate.h
@@ -12,11 +12,12 @@
 namespace chromeos {
 namespace input_method {
 
-class COMPONENT_EXPORT(UI_BASE_IME_CHROMEOS) MockComponentExtIMEManagerDelegate
+class COMPONENT_EXPORT(UI_BASE_IME_CHROMEOS)
+    MockComponentExtensionIMEManagerDelegate
     : public ComponentExtensionIMEManagerDelegate {
  public:
-  MockComponentExtIMEManagerDelegate();
-  ~MockComponentExtIMEManagerDelegate() override;
+  MockComponentExtensionIMEManagerDelegate();
+  ~MockComponentExtensionIMEManagerDelegate() override;
 
   std::vector<ComponentExtensionIME> ListIME() override;
   void Load(Profile*,
@@ -31,7 +32,7 @@
  private:
   std::vector<ComponentExtensionIME> ime_list_;
 
-  DISALLOW_COPY_AND_ASSIGN(MockComponentExtIMEManagerDelegate);
+  DISALLOW_COPY_AND_ASSIGN(MockComponentExtensionIMEManagerDelegate);
 };
 
 }  // namespace input_method
diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc
index 3dc9e4d..26328de 100644
--- a/ui/gfx/render_text.cc
+++ b/ui/gfx/render_text.cc
@@ -1958,6 +1958,30 @@
   return result;
 }
 
+// static
+void RenderText::MergeIntersectingRects(std::vector<Rect>& rects) {
+  if (rects.size() < 2)
+    return;
+
+  std::sort(rects.begin(), rects.end(),
+            [](const Rect& a, const Rect& b) { return a.x() < b.x(); });
+
+  size_t merge_candidate = 0;
+  for (size_t i = 1; i < rects.size(); i++) {
+    if (rects[i].Intersects(rects[merge_candidate])) {
+      DCHECK_EQ(rects[i].y(), rects[merge_candidate].y());
+      DCHECK_EQ(rects[i].height(), rects[merge_candidate].height());
+      rects[merge_candidate].Union(rects[i]);
+    } else {
+      merge_candidate++;
+      if (merge_candidate != i)
+        rects[merge_candidate] = rects[i];
+    }
+  }
+
+  rects.resize(merge_candidate + 1);
+}
+
 void RenderText::OnTextAttributeChanged() {
   layout_text_.clear();
   display_text_.clear();
diff --git a/ui/gfx/render_text.h b/ui/gfx/render_text.h
index 4b39abb9..be9c345 100644
--- a/ui/gfx/render_text.h
+++ b/ui/gfx/render_text.h
@@ -808,6 +808,10 @@
   static gfx::Rect ExpandToBeVerticallySymmetric(const gfx::Rect& rect,
                                                  const gfx::Rect& display_rect);
 
+  // Given |rects|, sort them along the x-axis and merge intersecting rects
+  // using union. Expects all selections in the text to be from the same line.
+  static void MergeIntersectingRects(std::vector<Rect>& rects);
+
   // Resets |cached_cursor_x_| to null. When non-null, CURSOR_UP, CURSOR_DOWN
   // movements use this value instead of the current cursor x position to
   // determine the next cursor x position.
diff --git a/ui/gfx/render_text_harfbuzz.cc b/ui/gfx/render_text_harfbuzz.cc
index 16b6f859..02c9776 100644
--- a/ui/gfx/render_text_harfbuzz.cc
+++ b/ui/gfx/render_text_harfbuzz.cc
@@ -1447,6 +1447,7 @@
     if (line.segments.size() > 1 && IsNewlineSegment(line.segments[0]))
       line_start_x += line.segments[0].width();
 
+    std::vector<Rect> current_line_rects;
     for (const internal::LineSegment& segment : line.segments) {
       const Range intersection = segment.char_range.Intersect(display_range);
       DCHECK(!intersection.is_reversed());
@@ -1459,9 +1460,12 @@
         int end_x = base::ClampCeil(selected_span.end() - line_start_x);
         Rect rect(start_x, 0, end_x - start_x,
                   base::ClampCeil(line.size.height()));
-        rects.push_back(rect + GetLineOffset(line_index));
+        current_line_rects.push_back(rect + GetLineOffset(line_index));
       }
     }
+    MergeIntersectingRects(current_line_rects);
+    rects.insert(rects.end(), current_line_rects.begin(),
+                 current_line_rects.end());
   }
   return rects;
 }
diff --git a/ui/gfx/render_text_test_api.h b/ui/gfx/render_text_test_api.h
index 1577a69..07c48f4 100644
--- a/ui/gfx/render_text_test_api.h
+++ b/ui/gfx/render_text_test_api.h
@@ -102,6 +102,10 @@
     return RenderText::ExpandToBeVerticallySymmetric(rect, display_rect);
   }
 
+  static void MergeIntersectingRects(std::vector<Rect>& rects) {
+    RenderText::MergeIntersectingRects(rects);
+  }
+
   void reset_cached_cursor_x() { render_text_->reset_cached_cursor_x(); }
 
   int GetLineContainingYCoord(float text_y) {
diff --git a/ui/gfx/render_text_unittest.cc b/ui/gfx/render_text_unittest.cc
index 44d050c5..f7df7bb 100644
--- a/ui/gfx/render_text_unittest.cc
+++ b/ui/gfx/render_text_unittest.cc
@@ -403,6 +403,16 @@
     }
   }
 
+  // Test that the rect defined by |left|, |top|, |width| and |height| is filled
+  // with the same color.
+  void EnsureRectIsAllSameColor(int left,
+                                int top,
+                                int width,
+                                int height) const {
+    SkColor buffer_color = buffer_[left + top * stride_];
+    EnsureSolidRect(buffer_color, left, top, width, height);
+  }
+
  private:
   const char* string_;
   const SkColor* buffer_;
@@ -1047,6 +1057,40 @@
   ExpectTextLog({{6}});
 }
 
+// Tests that when a selection is made and the selection background is
+// translucent, the selection renders properly. See crbug.com/1134440.
+TEST_F(RenderTextTest, SelectWithTranslucentBackground) {
+  constexpr float kGlyphWidth = 5.5f;
+  constexpr Size kCanvasSize(300, 50);
+  constexpr SkColor kTranslucentBlue = SkColorSetARGB(0x7F, 0x00, 0x00, 0xFF);
+  const char* kTestString{"A B C D"};
+
+  SkBitmap bitmap;
+  bitmap.allocPixels(
+      SkImageInfo::MakeN32Premul(kCanvasSize.width(), kCanvasSize.height()));
+  cc::SkiaPaintCanvas paint_canvas(bitmap);
+  Canvas canvas(&paint_canvas, 1.0f);
+  paint_canvas.clear(SK_ColorWHITE);
+
+  SetGlyphWidth(kGlyphWidth);
+  RenderText* render_text = GetRenderText();
+  render_text->set_selection_background_focused_color(kTranslucentBlue);
+  render_text->set_focused(true);
+
+  render_text->SetText(UTF8ToUTF16(kTestString));
+  render_text->SelectRange(Range(0, 7));
+  const Rect text_rect = Rect(render_text->GetStringSize());
+  render_text->SetDisplayRect(text_rect);
+  render_text->Draw(&canvas);
+  const uint32_t* buffer = static_cast<const uint32_t*>(bitmap.getPixels());
+  ASSERT_NE(nullptr, buffer);
+  TestRectangleBuffer rect_buffer(kTestString, buffer, kCanvasSize.width(),
+                                  kCanvasSize.height());
+
+  // This whole slice should be the same color and opacity.
+  rect_buffer.EnsureRectIsAllSameColor(0, 0, text_rect.width() - 1, 1);
+}
+
 TEST_F(RenderTextTest, SelectRangeColoredGrapheme) {
   RenderText* render_text = GetRenderText();
   render_text->SetText(UTF8ToUTF16("x\u0065\u0301y"));
@@ -7574,6 +7618,42 @@
                 Rect(20, 20, 400, 40), test_display_rect));
 }
 
+TEST_F(RenderTextTest, MergeIntersectingRects) {
+  // Basic case.
+  std::vector<Rect> test_rects{Rect(0, 0, 10, 10), Rect(5, 0, 10, 10),
+                               Rect(10, 0, 5, 10), Rect(12, 0, 5, 10)};
+  test::RenderTextTestApi::MergeIntersectingRects(test_rects);
+  ASSERT_EQ(1u, test_rects.size());
+  EXPECT_EQ(Rect(0, 0, 17, 10), test_rects[0]);
+
+  // Case where some rects intersect and some don't.
+  test_rects = std::vector<Rect>{Rect(0, 0, 10, 10), Rect(5, 0, 10, 10),
+                                 Rect(16, 0, 10, 10), Rect(25, 0, 10, 10),
+                                 Rect(40, 0, 10, 10)};
+  test::RenderTextTestApi::MergeIntersectingRects(test_rects);
+  ASSERT_EQ(3u, test_rects.size());
+  EXPECT_EQ(Rect(0, 0, 15, 10), test_rects[0]);
+  EXPECT_EQ(Rect(16, 0, 19, 10), test_rects[1]);
+  EXPECT_EQ(Rect(40, 0, 10, 10), test_rects[2]);
+
+  // Case where no rects intersect.
+  test_rects = std::vector<Rect>{Rect(0, 0, 10, 10), Rect(11, 0, 10, 10),
+                                 Rect(22, 0, 10, 10), Rect(33, 0, 10, 10)};
+  test::RenderTextTestApi::MergeIntersectingRects(test_rects);
+  ASSERT_EQ(4u, test_rects.size());
+  EXPECT_EQ(Rect(0, 0, 10, 10), test_rects[0]);
+  EXPECT_EQ(Rect(11, 0, 10, 10), test_rects[1]);
+  EXPECT_EQ(Rect(22, 0, 10, 10), test_rects[2]);
+  EXPECT_EQ(Rect(33, 0, 10, 10), test_rects[3]);
+
+  // Rects are out-of-order.
+  test_rects = std::vector<Rect>{Rect(10, 0, 5, 10), Rect(0, 0, 10, 10),
+                                 Rect(12, 0, 5, 10), Rect(5, 0, 10, 10)};
+  test::RenderTextTestApi::MergeIntersectingRects(test_rects);
+  ASSERT_EQ(1u, test_rects.size());
+  EXPECT_EQ(Rect(0, 0, 17, 10), test_rects[0]);
+}
+
 // Ensures that text is centered vertically and consistently when either the
 // display rectangle height changes, or when the minimum line height changes.
 // The difference between the two is the selection rectangle, which should match
diff --git a/ui/views/controls/button/md_text_button.cc b/ui/views/controls/button/md_text_button.cc
index 4b6f451..6cb095d2 100644
--- a/ui/views/controls/button/md_text_button.cc
+++ b/ui/views/controls/button/md_text_button.cc
@@ -169,11 +169,16 @@
   UpdateColors();
 }
 
-void MdTextButton::SetCustomPadding(const gfx::Insets& padding) {
+void MdTextButton::SetCustomPadding(
+    const base::Optional<gfx::Insets>& padding) {
   custom_padding_ = padding;
   UpdatePadding();
 }
 
+base::Optional<gfx::Insets> MdTextButton::GetCustomPadding() const {
+  return custom_padding_.value_or(CalculateDefaultPadding());
+}
+
 void MdTextButton::SetText(const base::string16& text) {
   LabelButton::SetText(text);
   UpdatePadding();
@@ -300,6 +305,7 @@
 ADD_PROPERTY_METADATA(bool, Prominent)
 ADD_PROPERTY_METADATA(float, CornerRadius)
 ADD_PROPERTY_METADATA(base::Optional<SkColor>, BgColorOverride)
+ADD_PROPERTY_METADATA(base::Optional<gfx::Insets>, CustomPadding)
 END_METADATA
 
 }  // namespace views
diff --git a/ui/views/controls/button/md_text_button.h b/ui/views/controls/button/md_text_button.h
index b9aa8505..f1be12a 100644
--- a/ui/views/controls/button/md_text_button.h
+++ b/ui/views/controls/button/md_text_button.h
@@ -41,7 +41,8 @@
   float GetCornerRadius() const;
 
   // See |custom_padding_|.
-  void SetCustomPadding(const gfx::Insets& padding);
+  void SetCustomPadding(const base::Optional<gfx::Insets>& padding);
+  base::Optional<gfx::Insets> GetCustomPadding() const;
 
   // LabelButton:
   void OnThemeChanged() override;
@@ -80,6 +81,13 @@
   DISALLOW_COPY_AND_ASSIGN(MdTextButton);
 };
 
+BEGIN_VIEW_BUILDER(VIEWS_EXPORT, MdTextButton, LabelButton)
+VIEW_BUILDER_PROPERTY(bool, Prominent)
+VIEW_BUILDER_PROPERTY(base::Optional<SkColor>, BgColorOverride)
+VIEW_BUILDER_PROPERTY(float, CornerRadius)
+VIEW_BUILDER_PROPERTY(base::Optional<gfx::Insets>, CustomPadding)
+END_VIEW_BUILDER(VIEWS_EXPORT, MdTextButton)
+
 }  // namespace views
 
 #endif  // UI_VIEWS_CONTROLS_BUTTON_MD_TEXT_BUTTON_H_
diff --git a/ui/views/examples/ax_example.cc b/ui/views/examples/ax_example.cc
index 03513d0..395b283 100644
--- a/ui/views/examples/ax_example.cc
+++ b/ui/views/examples/ax_example.cc
@@ -29,13 +29,14 @@
   layout->SetMainAxisAlignment(LayoutAlignment::kStart);
   layout->SetCrossAxisAlignment(LayoutAlignment::kStart);
 
-  announce_button_ = container->AddChildView(
-      std::make_unique<MdTextButton>(this, base::ASCIIToUTF16("AnnounceText")));
-}
+  auto announce_text = [](AxExample* example) {
+    example->announce_button_->GetViewAccessibility().AnnounceText(
+        base::ASCIIToUTF16("Button pressed."));
+  };
 
-void AxExample::ButtonPressed(Button* sender, const ui::Event& event) {
-  sender->GetViewAccessibility().AnnounceText(
-      base::ASCIIToUTF16("Button pressed."));
+  announce_button_ = container->AddChildView(std::make_unique<MdTextButton>(
+      base::BindRepeating(announce_text, base::Unretained(this)),
+      base::ASCIIToUTF16("AnnounceText")));
 }
 
 }  // namespace examples
diff --git a/ui/views/examples/ax_example.h b/ui/views/examples/ax_example.h
index 2be51f6..4b38291 100644
--- a/ui/views/examples/ax_example.h
+++ b/ui/views/examples/ax_example.h
@@ -6,16 +6,16 @@
 #define UI_VIEWS_EXAMPLES_AX_EXAMPLE_H_
 
 #include "base/macros.h"
-#include "ui/views/controls/button/button.h"
 #include "ui/views/examples/example_base.h"
 
 namespace views {
 
+class Button;
+
 namespace examples {
 
 // ButtonExample simply counts the number of clicks.
-class VIEWS_EXAMPLES_EXPORT AxExample : public ExampleBase,
-                                        public ButtonListener {
+class VIEWS_EXAMPLES_EXPORT AxExample : public ExampleBase {
  public:
   AxExample();
   ~AxExample() override;
@@ -24,9 +24,6 @@
   void CreateExampleView(View* container) override;
 
  private:
-  // ButtonListener:
-  void ButtonPressed(Button* sender, const ui::Event& event) override;
-
   Button* announce_button_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(AxExample);
diff --git a/ui/views/examples/button_example.cc b/ui/views/examples/button_example.cc
index 17f44efed..0230ecbc 100644
--- a/ui/views/examples/button_example.cc
+++ b/ui/views/examples/button_example.cc
@@ -17,6 +17,9 @@
 #include "ui/views/controls/button/md_text_button.h"
 #include "ui/views/examples/examples_window.h"
 #include "ui/views/layout/box_layout.h"
+#include "ui/views/layout/box_layout_view.h"
+#include "ui/views/layout/fill_layout.h"
+#include "ui/views/metadata/view_factory.h"
 #include "ui/views/resources/grit/views_resources.h"
 #include "ui/views/view.h"
 
@@ -41,42 +44,60 @@
 ButtonExample::~ButtonExample() = default;
 
 void ButtonExample::CreateExampleView(View* container) {
-  container->SetBackground(CreateSolidBackground(SK_ColorWHITE));
-  auto layout = std::make_unique<BoxLayout>(BoxLayout::Orientation::kVertical,
-                                            gfx::Insets(10), 10);
-  layout->set_cross_axis_alignment(BoxLayout::CrossAxisAlignment::kCenter);
-  container->SetLayoutManager(std::move(layout));
-
-  auto label_button =
-      std::make_unique<LabelButton>(this, ASCIIToUTF16(kLabelButton));
-  label_button->SetFocusForPlatform();
-  label_button->SetRequestFocusOnPress(true);
-  label_button_ = container->AddChildView(std::move(label_button));
-
-  md_button_ = container->AddChildView(std::make_unique<views::MdTextButton>(
-      this, base::ASCIIToUTF16("Material Design")));
-
-  auto md_disabled_button = std::make_unique<views::MdTextButton>(
-      this, ASCIIToUTF16("Material Design Disabled Button"));
-  md_disabled_button->SetState(Button::STATE_DISABLED);
-  md_disabled_button_ = container->AddChildView(std::move(md_disabled_button));
-
-  auto md_default_button = std::make_unique<views::MdTextButton>(
-      this, base::ASCIIToUTF16("Default"));
-  md_default_button->SetIsDefault(true);
-  md_default_button_ = container->AddChildView(std::move(md_default_button));
-
+  container->SetLayoutManager(std::make_unique<FillLayout>());
   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
-  auto image_button = std::make_unique<ImageButton>(this);
-  image_button->SetFocusForPlatform();
-  image_button->SetRequestFocusOnPress(true);
-  image_button->SetImage(ImageButton::STATE_NORMAL,
-                         rb.GetImageNamed(IDR_CLOSE).ToImageSkia());
-  image_button->SetImage(ImageButton::STATE_HOVERED,
-                         rb.GetImageNamed(IDR_CLOSE_H).ToImageSkia());
-  image_button->SetImage(ImageButton::STATE_PRESSED,
-                         rb.GetImageNamed(IDR_CLOSE_P).ToImageSkia());
-  image_button_ = container->AddChildView(std::move(image_button));
+
+  auto view =
+      Builder<BoxLayoutView>()
+          .SetOrientation(BoxLayout::Orientation::kVertical)
+          .SetInsideBorderInsets(gfx::Insets(10))
+          .SetBetweenChildSpacing(10)
+          .SetCrossAxisAlignment(BoxLayout::CrossAxisAlignment::kCenter)
+          .SetBackground(CreateSolidBackground(SK_ColorWHITE))
+          .AddChildren(
+              {Builder<LabelButton>()
+                   .CopyAddressTo(&label_button_)
+                   .SetText(ASCIIToUTF16(kLabelButton))
+                   .SetFocusForPlatform()
+                   .SetRequestFocusOnPress(true),
+               Builder<MdTextButton>()
+                   .CopyAddressTo(&md_button_)
+                   .SetText(base::ASCIIToUTF16("Material Design")),
+               Builder<MdTextButton>()
+                   .CopyAddressTo(&md_disabled_button_)
+                   .SetText(ASCIIToUTF16("Material Design Disabled Button"))
+                   .SetState(Button::STATE_DISABLED),
+               Builder<MdTextButton>()
+                   .CopyAddressTo(&md_default_button_)
+                   .SetText(base::ASCIIToUTF16("Default"))
+                   .SetIsDefault(true),
+               Builder<ImageButton>()
+                   .CopyAddressTo(&image_button_)
+                   .SetFocusForPlatform()
+                   .SetRequestFocusOnPress(true)})
+          .Build();
+
+  auto start_throbber_cb = [](Button* button) { button->StartThrobbing(5); };
+  label_button_->set_callback(
+      base::BindRepeating(&ButtonExample::LabelButtonPressed,
+                          base::Unretained(this), label_button_));
+  md_button_->set_callback(base::BindRepeating(start_throbber_cb, md_button_));
+  md_disabled_button_->set_callback(
+      base::BindRepeating(&ButtonExample::LabelButtonPressed,
+                          base::Unretained(this), md_disabled_button_));
+  md_default_button_->set_callback(
+      base::BindRepeating(start_throbber_cb, md_default_button_));
+  image_button_->set_callback(base::BindRepeating(
+      &ButtonExample::ImageButtonPressed, base::Unretained(this)));
+
+  image_button_->SetImage(ImageButton::STATE_NORMAL,
+                          rb.GetImageNamed(IDR_CLOSE).ToImageSkia());
+  image_button_->SetImage(ImageButton::STATE_HOVERED,
+                          rb.GetImageNamed(IDR_CLOSE_H).ToImageSkia());
+  image_button_->SetImage(ImageButton::STATE_PRESSED,
+                          rb.GetImageNamed(IDR_CLOSE_P).ToImageSkia());
+
+  container->AddChildView(std::move(view));
 }
 
 void ButtonExample::LabelButtonPressed(LabelButton* label_button,
@@ -112,15 +133,8 @@
   example_view()->GetLayoutManager()->Layout(example_view());
 }
 
-void ButtonExample::ButtonPressed(Button* sender, const ui::Event& event) {
-  if (sender == label_button_)
-    LabelButtonPressed(label_button_, event);
-  else if (sender == md_button_ || sender == md_default_button_)
-    static_cast<Button*>(sender)->StartThrobbing(5);
-  else if (sender == md_disabled_button_)
-    LabelButtonPressed(md_disabled_button_, event);
-  else
-    PrintStatus("Image Button Pressed! count: %d", ++count_);
+void ButtonExample::ImageButtonPressed() {
+  PrintStatus("Image Button Pressed! count: %d", ++count_);
 }
 
 }  // namespace examples
diff --git a/ui/views/examples/button_example.h b/ui/views/examples/button_example.h
index 649a842..f3693d6 100644
--- a/ui/views/examples/button_example.h
+++ b/ui/views/examples/button_example.h
@@ -6,9 +6,16 @@
 #define UI_VIEWS_EXAMPLES_BUTTON_EXAMPLE_H_
 
 #include "base/macros.h"
-#include "ui/views/controls/button/button.h"
 #include "ui/views/examples/example_base.h"
 
+namespace gfx {
+class ImageSkia;
+}  // namespace gfx
+
+namespace ui {
+class Event;
+}  // namespace ui
+
 namespace views {
 
 class ImageButton;
@@ -18,8 +25,7 @@
 namespace examples {
 
 // ButtonExample simply counts the number of clicks.
-class VIEWS_EXAMPLES_EXPORT ButtonExample : public ExampleBase,
-                                            public ButtonListener {
+class VIEWS_EXAMPLES_EXPORT ButtonExample : public ExampleBase {
  public:
   ButtonExample();
   ~ButtonExample() override;
@@ -29,9 +35,7 @@
 
  private:
   void LabelButtonPressed(LabelButton* label_button, const ui::Event& event);
-
-  // ButtonListener:
-  void ButtonPressed(Button* sender, const ui::Event& event) override;
+  void ImageButtonPressed();
 
   // Example buttons.
   LabelButton* label_button_ = nullptr;
diff --git a/ui/views/examples/button_sticker_sheet.cc b/ui/views/examples/button_sticker_sheet.cc
index 2c5fc4b..bdc711f 100644
--- a/ui/views/examples/button_sticker_sheet.cc
+++ b/ui/views/examples/button_sticker_sheet.cc
@@ -76,16 +76,17 @@
 // button in |*primary| is a call-to-action button, and the button in
 // |*secondary| is a regular button.
 std::vector<std::unique_ptr<MdTextButton>> MakeButtonsInState(
-    ButtonListener* listener,
     Button::ButtonState state) {
   std::vector<std::unique_ptr<MdTextButton>> buttons;
   const base::string16 button_text = base::ASCIIToUTF16("Button");
-  auto primary = std::make_unique<views::MdTextButton>(listener, button_text);
+  auto primary = std::make_unique<views::MdTextButton>(
+      Button::PressedCallback(), button_text);
   primary->SetProminent(true);
   primary->SetState(state);
   buttons.push_back(std::move(primary));
 
-  auto secondary = std::make_unique<views::MdTextButton>(listener, button_text);
+  auto secondary = std::make_unique<views::MdTextButton>(
+      Button::PressedCallback(), button_text);
   secondary->SetState(state);
   buttons.push_back(std::move(secondary));
   return buttons;
@@ -108,19 +109,15 @@
   AddLabeledRowToGridLayout(layout, std::string(), std::move(plainLabel));
 
   AddLabeledRowToGridLayout(layout, "Default",
-                            MakeButtonsInState(this, Button::STATE_NORMAL));
+                            MakeButtonsInState(Button::STATE_NORMAL));
   AddLabeledRowToGridLayout(layout, "Normal",
-                            MakeButtonsInState(this, Button::STATE_NORMAL));
+                            MakeButtonsInState(Button::STATE_NORMAL));
   AddLabeledRowToGridLayout(layout, "Hovered",
-                            MakeButtonsInState(this, Button::STATE_HOVERED));
+                            MakeButtonsInState(Button::STATE_HOVERED));
   AddLabeledRowToGridLayout(layout, "Pressed",
-                            MakeButtonsInState(this, Button::STATE_PRESSED));
+                            MakeButtonsInState(Button::STATE_PRESSED));
   AddLabeledRowToGridLayout(layout, "Disabled",
-                            MakeButtonsInState(this, Button::STATE_DISABLED));
-}
-
-void ButtonStickerSheet::ButtonPressed(Button* button, const ui::Event& event) {
-  // Ignore button presses.
+                            MakeButtonsInState(Button::STATE_DISABLED));
 }
 
 }  // namespace examples
diff --git a/ui/views/examples/button_sticker_sheet.h b/ui/views/examples/button_sticker_sheet.h
index 3b8888e..692ac73 100644
--- a/ui/views/examples/button_sticker_sheet.h
+++ b/ui/views/examples/button_sticker_sheet.h
@@ -6,7 +6,6 @@
 #define UI_VIEWS_EXAMPLES_BUTTON_STICKER_SHEET_H_
 
 #include "base/macros.h"
-#include "ui/views/controls/button/button.h"
 #include "ui/views/examples/example_base.h"
 
 namespace views {
@@ -16,8 +15,7 @@
 // design button styles. This example only looks right with `--secondary-ui-md`.
 // It is designed to be as visually similar to the UI Harmony spec's sticker
 // sheet for buttons as possible.
-class VIEWS_EXAMPLES_EXPORT ButtonStickerSheet : public ExampleBase,
-                                                 public ButtonListener {
+class VIEWS_EXAMPLES_EXPORT ButtonStickerSheet : public ExampleBase {
  public:
   ButtonStickerSheet();
   ~ButtonStickerSheet() override;
@@ -25,9 +23,6 @@
   // ExampleBase:
   void CreateExampleView(View* container) override;
 
-  // ButtonListener:
-  void ButtonPressed(Button* sender, const ui::Event& event) override;
-
  private:
   DISALLOW_COPY_AND_ASSIGN(ButtonStickerSheet);
 };
diff --git a/ui/views/examples/colored_dialog_example.cc b/ui/views/examples/colored_dialog_example.cc
index 7f623e3c..c1ca5336 100644
--- a/ui/views/examples/colored_dialog_example.cc
+++ b/ui/views/examples/colored_dialog_example.cc
@@ -27,11 +27,12 @@
 namespace views {
 namespace examples {
 
-class ThemeTrackingCheckbox : public views::Checkbox,
-                              public views::ButtonListener {
+class ThemeTrackingCheckbox : public views::Checkbox {
  public:
   explicit ThemeTrackingCheckbox(const base::string16& label)
-      : Checkbox(label, this) {}
+      : Checkbox(label,
+                 base::BindRepeating(&ThemeTrackingCheckbox::ButtonPressed,
+                                     base::Unretained(this))) {}
   ThemeTrackingCheckbox(const ThemeTrackingCheckbox&) = delete;
   ThemeTrackingCheckbox& operator=(const ThemeTrackingCheckbox&) = delete;
   ~ThemeTrackingCheckbox() override = default;
@@ -39,12 +40,10 @@
   // views::Checkbox
   void OnThemeChanged() override {
     views::Checkbox::OnThemeChanged();
-
     SetChecked(GetNativeTheme()->ShouldUseDarkColors());
   }
 
-  // ButtonListener
-  void ButtonPressed(views::Button* sender, const ui::Event& event) override {
+  void ButtonPressed() {
     GetNativeTheme()->set_use_dark_colors(GetChecked());
     GetWidget()->ThemeChanged();
   }
@@ -52,10 +51,10 @@
 
 class TextVectorImageButton : public views::MdTextButton {
  public:
-  TextVectorImageButton(ButtonListener* listener,
+  TextVectorImageButton(PressedCallback callback,
                         const base::string16& text,
                         const gfx::VectorIcon& icon)
-      : MdTextButton(listener, text), icon_(icon) {}
+      : MdTextButton(callback, text), icon_(icon) {}
   TextVectorImageButton(const TextVectorImageButton&) = delete;
   TextVectorImageButton& operator=(const TextVectorImageButton&) = delete;
   ~TextVectorImageButton() override = default;
@@ -125,7 +124,9 @@
       l10n_util::GetStringUTF16(IDS_COLORED_DIALOG_CHOOSER_CHECKBOX)));
 
   AddChildView(std::make_unique<TextVectorImageButton>(
-      this, l10n_util::GetStringUTF16(IDS_COLORED_DIALOG_CHOOSER_BUTTON),
+      base::BindRepeating(&ColoredDialogChooser::ButtonPressed,
+                          base::Unretained(this)),
+      l10n_util::GetStringUTF16(IDS_COLORED_DIALOG_CHOOSER_BUTTON),
       views::kInfoIcon));
 
   confirmation_label_ = AddChildView(
@@ -135,8 +136,7 @@
 
 ColoredDialogChooser::~ColoredDialogChooser() = default;
 
-void ColoredDialogChooser::ButtonPressed(Button* sender,
-                                         const ui::Event& event) {
+void ColoredDialogChooser::ButtonPressed() {
   // Create the colored dialog.
   views::Widget* widget = DialogDelegate::CreateDialogWidget(
       new ColoredDialog(base::BindOnce(&ColoredDialogChooser::OnFeedbackSubmit,
diff --git a/ui/views/examples/colored_dialog_example.h b/ui/views/examples/colored_dialog_example.h
index 42a4ddf..6418415 100644
--- a/ui/views/examples/colored_dialog_example.h
+++ b/ui/views/examples/colored_dialog_example.h
@@ -6,7 +6,6 @@
 #define UI_VIEWS_EXAMPLES_COLORED_DIALOG_EXAMPLE_H_
 
 #include "base/timer/timer.h"
-#include "ui/views/controls/button/button.h"
 #include "ui/views/controls/textfield/textfield_controller.h"
 #include "ui/views/examples/example_base.h"
 #include "ui/views/view.h"
@@ -14,7 +13,6 @@
 
 namespace views {
 
-class Button;
 class Label;
 
 namespace examples {
@@ -41,15 +39,14 @@
   views::Textfield* textfield_;
 };
 
-class ColoredDialogChooser : public views::View, public views::ButtonListener {
+class ColoredDialogChooser : public views::View {
  public:
   ColoredDialogChooser();
   ColoredDialogChooser(const ColoredDialogChooser&) = delete;
   ColoredDialogChooser& operator=(const ColoredDialogChooser&) = delete;
   ~ColoredDialogChooser() override;
 
-  // ButtonListener
-  void ButtonPressed(views::Button* sender, const ui::Event& event) override;
+  void ButtonPressed();
 
  private:
   void OnFeedbackSubmit(base::string16 text);
diff --git a/ui/views/examples/dialog_example.cc b/ui/views/examples/dialog_example.cc
index d4cfe71..38ad5f9 100644
--- a/ui/views/examples/dialog_example.cc
+++ b/ui/views/examples/dialog_example.cc
@@ -169,8 +169,10 @@
       kFixed, kButtonsColumnId, kFixed,
       provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL));
 
-  show_ = layout->AddView(
-      std::make_unique<views::MdTextButton>(this, base::ASCIIToUTF16("Show")));
+  show_ = layout->AddView(std::make_unique<views::MdTextButton>(
+      base::BindRepeating(&DialogExample::ShowButtonPressed,
+                          base::Unretained(this)),
+      base::ASCIIToUTF16("Show")));
 }
 
 void DialogExample::StartRowWithLabel(GridLayout* layout, const char* label) {
@@ -194,7 +196,10 @@
 }
 
 void DialogExample::AddCheckbox(GridLayout* layout, Checkbox** member) {
-  auto checkbox = std::make_unique<Checkbox>(base::string16(), this);
+  auto callback = member == &bubble_ ? &DialogExample::BubbleCheckboxPressed
+                                     : &DialogExample::OtherCheckboxPressed;
+  auto checkbox = std::make_unique<Checkbox>(
+      base::string16(), base::BindRepeating(callback, base::Unretained(this)));
   checkbox->SetChecked(true);
   *member = layout->AddView(std::move(checkbox));
 }
@@ -243,49 +248,48 @@
   widget->OnSizeConstraintsChanged();
 }
 
-void DialogExample::ButtonPressed(Button* sender, const ui::Event& event) {
-  if (sender == show_) {
-    if (bubble_->GetChecked()) {
-      // |bubble| will be destroyed by its widget when the widget is destroyed.
-      Bubble* bubble = new Bubble(this, sender);
-      last_dialog_ = bubble;
-      BubbleDialogDelegateView::CreateBubble(bubble);
-    } else {
-      // |dialog| will be destroyed by its widget when the widget is destroyed.
-      Dialog* dialog = new Dialog(this);
-      last_dialog_ = dialog;
-      dialog->InitDelegate();
+void DialogExample::ShowButtonPressed() {
+  if (bubble_->GetChecked()) {
+    // |bubble| will be destroyed by its widget when the widget is destroyed.
+    Bubble* bubble = new Bubble(this, show_);
+    last_dialog_ = bubble;
+    BubbleDialogDelegateView::CreateBubble(bubble);
+  } else {
+    // |dialog| will be destroyed by its widget when the widget is destroyed.
+    Dialog* dialog = new Dialog(this);
+    last_dialog_ = dialog;
+    dialog->InitDelegate();
 
-      // constrained_window::CreateBrowserModalDialogViews() allows dialogs to
-      // be created as MODAL_TYPE_WINDOW without specifying a parent.
-      gfx::NativeView parent = nullptr;
-      if (mode_->GetSelectedIndex() != kFakeModeless)
-        parent = example_view()->GetWidget()->GetNativeView();
+    // constrained_window::CreateBrowserModalDialogViews() allows dialogs to
+    // be created as MODAL_TYPE_WINDOW without specifying a parent.
+    gfx::NativeView parent = nullptr;
+    if (mode_->GetSelectedIndex() != kFakeModeless)
+      parent = example_view()->GetWidget()->GetNativeView();
 
-      DialogDelegate::CreateDialogWidget(
-          dialog, example_view()->GetWidget()->GetNativeWindow(), parent);
-    }
-    last_dialog_->GetWidget()->Show();
-    return;
+    DialogDelegate::CreateDialogWidget(
+        dialog, example_view()->GetWidget()->GetNativeWindow(), parent);
   }
+  last_dialog_->GetWidget()->Show();
+}
 
-  if (sender == bubble_) {
-    if (bubble_->GetChecked() && GetModalType() != ui::MODAL_TYPE_CHILD) {
-      mode_->SetSelectedIndex(ui::MODAL_TYPE_CHILD);
-      LogStatus("You nearly always want Child Modal for bubbles.");
-    }
-    persistent_bubble_->SetEnabled(bubble_->GetChecked());
-    OnPerformAction();  // Validate the modal type.
-
-    if (!bubble_->GetChecked() && GetModalType() == ui::MODAL_TYPE_CHILD) {
-      // Do something reasonable when simply unchecking bubble and re-enable.
-      mode_->SetSelectedIndex(ui::MODAL_TYPE_WINDOW);
-      OnPerformAction();
-    }
-    return;
+void DialogExample::BubbleCheckboxPressed() {
+  if (bubble_->GetChecked() && GetModalType() != ui::MODAL_TYPE_CHILD) {
+    mode_->SetSelectedIndex(ui::MODAL_TYPE_CHILD);
+    LogStatus("You nearly always want Child Modal for bubbles.");
   }
+  persistent_bubble_->SetEnabled(bubble_->GetChecked());
+  OnPerformAction();  // Validate the modal type.
 
-  // Other buttons are all checkboxes. Update the dialog if there is one.
+  if (!bubble_->GetChecked() && GetModalType() == ui::MODAL_TYPE_CHILD) {
+    // Do something reasonable when simply unchecking bubble and re-enable.
+    mode_->SetSelectedIndex(ui::MODAL_TYPE_WINDOW);
+    OnPerformAction();
+  }
+}
+
+void DialogExample::OtherCheckboxPressed() {
+  // Buttons other than show and bubble are pressed. They are all checkboxes.
+  // Update the dialog if there is one.
   if (last_dialog_) {
     last_dialog_->DialogModelChanged();
     ResizeDialog();
diff --git a/ui/views/examples/dialog_example.h b/ui/views/examples/dialog_example.h
index a4c8905..25c2490 100644
--- a/ui/views/examples/dialog_example.h
+++ b/ui/views/examples/dialog_example.h
@@ -7,7 +7,7 @@
 
 #include "base/macros.h"
 #include "ui/base/models/simple_combobox_model.h"
-#include "ui/views/controls/button/button.h"
+#include "ui/base/ui_base_types.h"
 #include "ui/views/controls/textfield/textfield_controller.h"
 #include "ui/views/examples/example_base.h"
 
@@ -25,7 +25,6 @@
 
 // An example that exercises BubbleDialogDelegateView or DialogDelegateView.
 class VIEWS_EXAMPLES_EXPORT DialogExample : public ExampleBase,
-                                            public ButtonListener,
                                             public TextfieldController {
  public:
   DialogExample();
@@ -61,8 +60,9 @@
   // Resize the dialog Widget to match the preferred size. Triggers Layout().
   void ResizeDialog();
 
-  // ButtonListener:
-  void ButtonPressed(Button* sender, const ui::Event& event) override;
+  void ShowButtonPressed();
+  void BubbleCheckboxPressed();
+  void OtherCheckboxPressed();
 
   // TextfieldController:
   void ContentsChanged(Textfield* sender,
diff --git a/ui/views/examples/label_example.cc b/ui/views/examples/label_example.cc
index ee036c5..b163737 100644
--- a/ui/views/examples/label_example.cc
+++ b/ui/views/examples/label_example.cc
@@ -125,21 +125,21 @@
   AddCustomLabel(container);
 }
 
-void LabelExample::ButtonPressed(Button* button, const ui::Event& event) {
-  if (button == multiline_) {
-    custom_label_->SetMultiLine(multiline_->GetChecked());
-  } else if (button == shadows_) {
-    gfx::ShadowValues shadows;
-    if (shadows_->GetChecked()) {
-      shadows.push_back(gfx::ShadowValue(gfx::Vector2d(), 1, SK_ColorRED));
-      shadows.push_back(gfx::ShadowValue(gfx::Vector2d(2, 2), 0, SK_ColorGRAY));
-    }
-    custom_label_->SetShadows(shadows);
-  } else if (button == selectable_) {
-    custom_label_->SetSelectable(selectable_->GetChecked());
+void LabelExample::MultilineCheckboxPressed() {
+  custom_label_->SetMultiLine(multiline_->GetChecked());
+}
+
+void LabelExample::ShadowsCheckboxPressed() {
+  gfx::ShadowValues shadows;
+  if (shadows_->GetChecked()) {
+    shadows.push_back(gfx::ShadowValue(gfx::Vector2d(), 1, SK_ColorRED));
+    shadows.push_back(gfx::ShadowValue(gfx::Vector2d(2, 2), 0, SK_ColorGRAY));
   }
-  custom_label_->parent()->parent()->InvalidateLayout();
-  custom_label_->SchedulePaint();
+  custom_label_->SetShadows(shadows);
+}
+
+void LabelExample::SelectableCheckboxPressed() {
+  custom_label_->SetSelectable(selectable_->GetChecked());
 }
 
 void LabelExample::ContentsChanged(Textfield* sender,
@@ -187,12 +187,18 @@
   column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 0,
                         GridLayout::ColumnSize::kUsePreferred, 0, 0);
   layout->StartRow(0, 1);
-  multiline_ = layout->AddView(
-      std::make_unique<Checkbox>(base::ASCIIToUTF16("Multiline"), this));
-  shadows_ = layout->AddView(
-      std::make_unique<Checkbox>(base::ASCIIToUTF16("Shadows"), this));
-  selectable_ = layout->AddView(
-      std::make_unique<Checkbox>(base::ASCIIToUTF16("Selectable"), this));
+  multiline_ = layout->AddView(std::make_unique<Checkbox>(
+      base::ASCIIToUTF16("Multiline"),
+      base::BindRepeating(&LabelExample::MultilineCheckboxPressed,
+                          base::Unretained(this))));
+  shadows_ = layout->AddView(std::make_unique<Checkbox>(
+      base::ASCIIToUTF16("Shadows"),
+      base::BindRepeating(&LabelExample::ShadowsCheckboxPressed,
+                          base::Unretained(this))));
+  selectable_ = layout->AddView(std::make_unique<Checkbox>(
+      base::ASCIIToUTF16("Selectable"),
+      base::BindRepeating(&LabelExample::SelectableCheckboxPressed,
+                          base::Unretained(this))));
   layout->AddPaddingRow(0, 8);
 
   column_set = layout->AddColumnSet(2);
diff --git a/ui/views/examples/label_example.h b/ui/views/examples/label_example.h
index d98fac41..d30c86f 100644
--- a/ui/views/examples/label_example.h
+++ b/ui/views/examples/label_example.h
@@ -6,7 +6,6 @@
 #define UI_VIEWS_EXAMPLES_LABEL_EXAMPLE_H_
 
 #include "base/macros.h"
-#include "ui/views/controls/button/button.h"
 #include "ui/views/controls/textfield/textfield_controller.h"
 #include "ui/views/examples/example_base.h"
 
@@ -20,7 +19,6 @@
 namespace examples {
 
 class VIEWS_EXAMPLES_EXPORT LabelExample : public ExampleBase,
-                                           public ButtonListener,
                                            public TextfieldController {
  public:
   LabelExample();
@@ -29,8 +27,9 @@
   // ExampleBase:
   void CreateExampleView(View* container) override;
 
-  // ButtonListener:
-  void ButtonPressed(Button* button, const ui::Event& event) override;
+  void MultilineCheckboxPressed();
+  void ShadowsCheckboxPressed();
+  void SelectableCheckboxPressed();
 
   // TextfieldController:
   void ContentsChanged(Textfield* sender,
diff --git a/url/mojom/BUILD.gn b/url/mojom/BUILD.gn
index 4c9f079..364d81b 100644
--- a/url/mojom/BUILD.gn
+++ b/url/mojom/BUILD.gn
@@ -40,6 +40,8 @@
       traits_public_deps = [ "//url" ]
     },
   ]
+
+  webui_module_path = "chrome://resources/mojo/url/mojom"
 }
 
 mojom("url_mojom_origin") {
diff --git a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/FullscreenCallbackTest.java b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/FullscreenCallbackTest.java
index 92a4ffe..aeee4ea 100644
--- a/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/FullscreenCallbackTest.java
+++ b/weblayer/browser/android/javatests/src/org/chromium/weblayer/test/FullscreenCallbackTest.java
@@ -12,6 +12,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.weblayer.shell.InstrumentationActivity;
 
@@ -44,6 +45,7 @@
 
     @Test
     @SmallTest
+    @DisabledTest(message = "crbug.com/1133893")
     public void testFullscreen() {
         // Second touch exits.
         EventUtils.simulateTouchCenterOfView(mActivity.getWindow().getDecorView());
diff --git a/weblayer/browser/content_browser_client_impl.cc b/weblayer/browser/content_browser_client_impl.cc
index 89291ba8..6666686df 100644
--- a/weblayer/browser/content_browser_client_impl.cc
+++ b/weblayer/browser/content_browser_client_impl.cc
@@ -638,7 +638,7 @@
 ContentBrowserClientImpl::GetControllerPresentationServiceDelegate(
     content::WebContents* web_contents) {
 #if defined(OS_ANDROID)
-  if (WebLayerFactoryImplAndroid::GetClientMajorVersion() < 87)
+  if (WebLayerFactoryImplAndroid::GetClientMajorVersion() < 88)
     return nullptr;
 
   if (base::FeatureList::IsEnabled(features::kMediaRouter)) {
diff --git a/weblayer/browser/java/AndroidManifest_monochrome.xml b/weblayer/browser/java/AndroidManifest_monochrome.xml
new file mode 100644
index 0000000..6eaac4d3
--- /dev/null
+++ b/weblayer/browser/java/AndroidManifest_monochrome.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2020 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. -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:dist="http://schemas.android.com/apk/distribution"
+    featureSplit="weblayer">
+    <uses-split android:name="chrome" />
+
+    <dist:module dist:onDemand="false">
+        <dist:fusing dist:include="true" />
+    </dist:module>
+
+    <application />
+</manifest>
diff --git a/weblayer/browser/java/BUILD.gn b/weblayer/browser/java/BUILD.gn
index ba1bd6fe..87352c9 100644
--- a/weblayer/browser/java/BUILD.gn
+++ b/weblayer/browser/java/BUILD.gn
@@ -150,6 +150,7 @@
     "org/chromium/weblayer_private/media/MediaRouteDialogFragmentImpl.java",
     "org/chromium/weblayer_private/media/MediaRouterClientImpl.java",
     "org/chromium/weblayer_private/media/MediaSessionManager.java",
+    "org/chromium/weblayer_private/media/MediaSessionNotificationHelper.java",
     "org/chromium/weblayer_private/media/MediaStreamManager.java",
     "org/chromium/weblayer_private/metrics/MetricsServiceClient.java",
     "org/chromium/weblayer_private/metrics/UmaUtils.java",
@@ -362,6 +363,7 @@
     "org/chromium/weblayer_private/interfaces/NavigationState.java",
     "org/chromium/weblayer_private/interfaces/NewTabType.java",
     "org/chromium/weblayer_private/interfaces/ObjectWrapper.java",
+    "org/chromium/weblayer_private/interfaces/RemoteMediaServiceConstants.java",
     "org/chromium/weblayer_private/interfaces/ScrollNotificationType.java",
     "org/chromium/weblayer_private/interfaces/SettingType.java",
     "org/chromium/weblayer_private/interfaces/SiteSettingsFragmentArgs.java",
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java
index 61967b6..0b2a8cd 100644
--- a/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java
+++ b/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java
@@ -79,6 +79,7 @@
 import org.chromium.weblayer_private.interfaces.ObjectWrapper;
 import org.chromium.weblayer_private.interfaces.StrictModeWorkaround;
 import org.chromium.weblayer_private.media.MediaRouteDialogFragmentImpl;
+import org.chromium.weblayer_private.media.MediaRouterClientImpl;
 import org.chromium.weblayer_private.media.MediaSessionManager;
 import org.chromium.weblayer_private.media.MediaStreamManager;
 import org.chromium.weblayer_private.metrics.MetricsServiceClient;
@@ -405,6 +406,19 @@
     }
 
     @Override
+    public void onRemoteMediaServiceStarted(IObjectWrapper sessionService, Intent intent) {
+        StrictModeWorkaround.apply();
+        MediaRouterClientImpl.serviceStarted(
+                ObjectWrapper.unwrap(sessionService, Service.class), intent);
+    }
+
+    @Override
+    public void onRemoteMediaServiceDestroyed(int id) {
+        StrictModeWorkaround.apply();
+        MediaRouterClientImpl.serviceDestroyed(id);
+    }
+
+    @Override
     public IBinder initializeImageDecoder(IObjectWrapper appContext, IObjectWrapper remoteContext) {
         StrictModeWorkaround.apply();
 
@@ -513,6 +527,42 @@
         }
     }
 
+    public static Intent createRemoteMediaServiceIntent() {
+        if (sClient == null) {
+            throw new IllegalStateException("WebLayer should have been initialized already.");
+        }
+
+        try {
+            return sClient.createRemoteMediaServiceIntent();
+        } catch (RemoteException e) {
+            throw new APICallException(e);
+        }
+    }
+
+    public static int getPresentationApiNotificationId() {
+        if (sClient == null) {
+            throw new IllegalStateException("WebLayer should have been initialized already.");
+        }
+
+        try {
+            return sClient.getPresentationApiNotificationId();
+        } catch (RemoteException e) {
+            throw new APICallException(e);
+        }
+    }
+
+    public static int getRemotePlaybackApiNotificationId() {
+        if (sClient == null) {
+            throw new IllegalStateException("WebLayer should have been initialized already.");
+        }
+
+        try {
+            return sClient.getRemotePlaybackApiNotificationId();
+        } catch (RemoteException e) {
+            throw new APICallException(e);
+        }
+    }
+
     public static String getClientApplicationName() {
         Context context = ContextUtils.getApplicationContext();
         return new StringBuilder()
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayer.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayer.aidl
index bef8113..b607c00 100644
--- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayer.aidl
+++ b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayer.aidl
@@ -104,4 +104,8 @@
   IObjectWrapper getApplicationContext() = 20;
   IMediaRouteDialogFragment createMediaRouteDialogFragmentImpl(
       in IRemoteFragmentClient remoteFragmentClient) = 21;
+
+  // Added in Version 88.
+  void onRemoteMediaServiceStarted(in IObjectWrapper sessionService, in Intent intent) = 22;
+  void onRemoteMediaServiceDestroyed(int id) = 23;
 }
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayerClient.aidl b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayerClient.aidl
index cc6781a..933e850 100644
--- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayerClient.aidl
+++ b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayerClient.aidl
@@ -18,4 +18,7 @@
   long getClassLoaderCreationTime() = 4;
   long getContextCreationTime() = 5;
   long getWebLayerLoaderCreationTime() = 6;
+  Intent createRemoteMediaServiceIntent() = 7;
+  int getPresentationApiNotificationId() = 8;
+  int getRemotePlaybackApiNotificationId() = 9;
 }
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/RemoteMediaServiceConstants.java b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/RemoteMediaServiceConstants.java
new file mode 100644
index 0000000..121f11a
--- /dev/null
+++ b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/RemoteMediaServiceConstants.java
@@ -0,0 +1,10 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.weblayer_private.interfaces;
+
+/** Keys for remote media service intent extras. */
+public interface RemoteMediaServiceConstants {
+    String NOTIFICATION_ID_KEY = "remote_media_service_notification_id_key";
+}
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/media/MediaRouterClientImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/media/MediaRouterClientImpl.java
index 86a596bd..ac609b92 100644
--- a/weblayer/browser/java/org/chromium/weblayer_private/media/MediaRouterClientImpl.java
+++ b/weblayer/browser/java/org/chromium/weblayer_private/media/MediaRouterClientImpl.java
@@ -4,23 +4,46 @@
 
 package org.chromium.weblayer_private.media;
 
+import android.app.Service;
 import android.content.Intent;
+import android.support.v4.media.session.MediaSessionCompat;
 
 import androidx.fragment.app.FragmentManager;
 
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.base.annotations.JNINamespace;
+import org.chromium.components.browser_ui.media.MediaNotificationController;
 import org.chromium.components.browser_ui.media.MediaNotificationInfo;
+import org.chromium.components.browser_ui.media.MediaNotificationManager;
+import org.chromium.components.browser_ui.notifications.NotificationWrapper;
+import org.chromium.components.browser_ui.notifications.NotificationWrapperBuilder;
 import org.chromium.components.media_router.MediaRouterClient;
 import org.chromium.content_public.browser.WebContents;
 import org.chromium.weblayer_private.IntentUtils;
 import org.chromium.weblayer_private.TabImpl;
+import org.chromium.weblayer_private.WebLayerImpl;
+import org.chromium.weblayer_private.interfaces.RemoteMediaServiceConstants;
 
 /** Provides WebLayer-specific behavior for Media Router. */
 @JNINamespace("weblayer")
 public class MediaRouterClientImpl extends MediaRouterClient {
+    static int sPresentationNotificationId;
+    static int sRemotingNotificationId;
+
     private MediaRouterClientImpl() {}
 
+    public static void serviceStarted(Service service, Intent intent) {
+        int notificationId = intent.getIntExtra(RemoteMediaServiceConstants.NOTIFICATION_ID_KEY, 0);
+        if (notificationId == 0) {
+            throw new RuntimeException("Invalid RemoteMediaService notification id");
+        }
+        MediaSessionNotificationHelper.serviceStarted(service, intent, notificationId);
+    }
+
+    public static void serviceDestroyed(int notificationId) {
+        MediaSessionNotificationHelper.serviceDestroyed(notificationId);
+    }
+
     @Override
     public int getTabId(WebContents webContents) {
         TabImpl tab = TabImpl.fromWebContents(webContents);
@@ -34,7 +57,19 @@
 
     @Override
     public void showNotification(MediaNotificationInfo notificationInfo) {
-        // TODO: implement.
+        MediaNotificationManager.show(notificationInfo, () -> {
+            return new MediaRouterNotificationControllerDelegate(notificationInfo.id);
+        });
+    }
+
+    @Override
+    public int getPresentationNotificationId() {
+        return getPresentationNotificationIdFromClient();
+    }
+
+    @Override
+    public int getRemotingNotificationId() {
+        return getRemotingNotificationIdFromClient();
     }
 
     @Override
@@ -51,4 +86,62 @@
 
         MediaRouterClient.setInstance(new MediaRouterClientImpl());
     }
+
+    private static class MediaRouterNotificationControllerDelegate
+            implements MediaNotificationController.Delegate {
+        // The ID distinguishes between Presentation and Remoting services/notifications.
+        private final int mNotificationId;
+
+        MediaRouterNotificationControllerDelegate(int notificationId) {
+            mNotificationId = notificationId;
+        }
+
+        @Override
+        public Intent createServiceIntent() {
+            return WebLayerImpl.createRemoteMediaServiceIntent().putExtra(
+                    RemoteMediaServiceConstants.NOTIFICATION_ID_KEY, mNotificationId);
+        }
+
+        @Override
+        public String getAppName() {
+            return WebLayerImpl.getClientApplicationName();
+        }
+
+        @Override
+        public String getNotificationGroupName() {
+            if (mNotificationId == getPresentationNotificationIdFromClient()) {
+                return "org.chromium.weblayer.PresentationApi";
+            }
+
+            assert mNotificationId == getRemotingNotificationIdFromClient();
+            return "org.chromium.weblayer.RemotePlaybackApi";
+        }
+
+        @Override
+        public NotificationWrapperBuilder createNotificationWrapperBuilder() {
+            return MediaSessionNotificationHelper.createNotificationWrapperBuilder(mNotificationId);
+        }
+
+        @Override
+        public void onMediaSessionUpdated(MediaSessionCompat session) {
+            // TODO(estade): implement.
+        }
+
+        @Override
+        public void logNotificationShown(NotificationWrapper notification) {}
+    }
+
+    private static int getPresentationNotificationIdFromClient() {
+        if (sPresentationNotificationId == 0) {
+            sPresentationNotificationId = WebLayerImpl.getPresentationApiNotificationId();
+        }
+        return sPresentationNotificationId;
+    }
+
+    private static int getRemotingNotificationIdFromClient() {
+        if (sRemotingNotificationId == 0) {
+            sRemotingNotificationId = WebLayerImpl.getRemotePlaybackApiNotificationId();
+        }
+        return sRemotingNotificationId;
+    }
 }
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/media/MediaSessionManager.java b/weblayer/browser/java/org/chromium/weblayer_private/media/MediaSessionManager.java
index 3311c77..35d8948 100644
--- a/weblayer/browser/java/org/chromium/weblayer_private/media/MediaSessionManager.java
+++ b/weblayer/browser/java/org/chromium/weblayer_private/media/MediaSessionManager.java
@@ -12,14 +12,10 @@
 import org.chromium.components.browser_ui.media.MediaNotificationInfo;
 import org.chromium.components.browser_ui.media.MediaNotificationManager;
 import org.chromium.components.browser_ui.media.MediaSessionHelper;
-import org.chromium.components.browser_ui.notifications.ForegroundServiceUtils;
-import org.chromium.components.browser_ui.notifications.NotificationMetadata;
 import org.chromium.components.browser_ui.notifications.NotificationWrapper;
 import org.chromium.components.browser_ui.notifications.NotificationWrapperBuilder;
 import org.chromium.weblayer_private.IntentUtils;
 import org.chromium.weblayer_private.WebLayerImpl;
-import org.chromium.weblayer_private.WebLayerNotificationChannels;
-import org.chromium.weblayer_private.WebLayerNotificationWrapperBuilder;
 
 /**
  * A glue class for MediaSession.
@@ -31,24 +27,11 @@
     private static int sNotificationId;
 
     public static void serviceStarted(Service service, Intent intent) {
-        MediaNotificationController controller = getController();
-        if (controller != null && controller.processIntent(service, intent)) return;
-
-        // The service has been started with startForegroundService() but the
-        // notification hasn't been shown. See similar logic in {@link
-        // ChromeMediaNotificationControllerDelegate}.
-        MediaNotificationController.finishStartingForegroundServiceOnO(
-                service, createNotificationWrapperBuilder().buildNotificationWrapper());
-        // Call stopForeground to guarantee Android unset the foreground bit.
-        ForegroundServiceUtils.getInstance().stopForeground(
-                service, Service.STOP_FOREGROUND_REMOVE);
-        service.stopSelf();
+        MediaSessionNotificationHelper.serviceStarted(service, intent, getNotificationId());
     }
 
     public static void serviceDestroyed() {
-        MediaNotificationController controller = getController();
-        if (controller != null) controller.onServiceDestroyed();
-        MediaNotificationManager.clear(getNotificationId());
+        MediaSessionNotificationHelper.serviceDestroyed(getNotificationId());
     }
 
     public static MediaSessionHelper.Delegate createMediaSessionHelperDelegate(int tabId) {
@@ -60,7 +43,7 @@
 
             @Override
             public boolean fetchLargeFaviconImage() {
-                // TODO(crbug.com/1076463): WebLayer doesn't support favicons.
+                // TODO(crbug.com/1137625): implement.
                 return false;
             }
 
@@ -108,7 +91,8 @@
 
         @Override
         public NotificationWrapperBuilder createNotificationWrapperBuilder() {
-            return MediaSessionManager.createNotificationWrapperBuilder();
+            return MediaSessionNotificationHelper.createNotificationWrapperBuilder(
+                    getNotificationId());
         }
 
         @Override
@@ -120,22 +104,8 @@
         public void logNotificationShown(NotificationWrapper notification) {}
     }
 
-    private static NotificationWrapperBuilder createNotificationWrapperBuilder() {
-        // Only the null tag will work as expected, because {@link Service#startForeground()} only
-        // takes an ID and no tag. If we pass a tag here, then the notification that's used to
-        // display a paused state (no foreground service) will not be identified as the same one
-        // that's used with the foreground service.
-        return WebLayerNotificationWrapperBuilder.create(
-                WebLayerNotificationChannels.ChannelId.MEDIA_PLAYBACK,
-                new NotificationMetadata(0, null /*notificationTag*/, getNotificationId()));
-    }
-
     private static int getNotificationId() {
         if (sNotificationId == 0) sNotificationId = WebLayerImpl.getMediaSessionNotificationId();
         return sNotificationId;
     }
-
-    private static MediaNotificationController getController() {
-        return MediaNotificationManager.getController(getNotificationId());
-    }
 }
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/media/MediaSessionNotificationHelper.java b/weblayer/browser/java/org/chromium/weblayer_private/media/MediaSessionNotificationHelper.java
new file mode 100644
index 0000000..fbd9b5da
--- /dev/null
+++ b/weblayer/browser/java/org/chromium/weblayer_private/media/MediaSessionNotificationHelper.java
@@ -0,0 +1,55 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.weblayer_private.media;
+
+import android.app.Service;
+import android.content.Intent;
+
+import org.chromium.components.browser_ui.media.MediaNotificationController;
+import org.chromium.components.browser_ui.media.MediaNotificationManager;
+import org.chromium.components.browser_ui.notifications.ForegroundServiceUtils;
+import org.chromium.components.browser_ui.notifications.NotificationMetadata;
+import org.chromium.components.browser_ui.notifications.NotificationWrapperBuilder;
+import org.chromium.weblayer_private.WebLayerNotificationChannels;
+import org.chromium.weblayer_private.WebLayerNotificationWrapperBuilder;
+
+/**
+ * A helper class for management of MediaSession (local device), Presentation API and Remote
+ * Playback API (casting) notifications and foreground services.
+ */
+class MediaSessionNotificationHelper {
+    static void serviceStarted(Service service, Intent intent, int notificationId) {
+        MediaNotificationController controller =
+                MediaNotificationManager.getController(notificationId);
+        if (controller != null && controller.processIntent(service, intent)) return;
+
+        // The service has been started with startForegroundService() but the
+        // notification hasn't been shown. See similar logic in {@link
+        // ChromeMediaNotificationControllerDelegate}.
+        MediaNotificationController.finishStartingForegroundServiceOnO(service,
+                createNotificationWrapperBuilder(notificationId).buildNotificationWrapper());
+        // Call stopForeground to guarantee Android unset the foreground bit.
+        ForegroundServiceUtils.getInstance().stopForeground(
+                service, Service.STOP_FOREGROUND_REMOVE);
+        service.stopSelf();
+    }
+
+    static void serviceDestroyed(int notificationId) {
+        MediaNotificationController controller =
+                MediaNotificationManager.getController(notificationId);
+        if (controller != null) controller.onServiceDestroyed();
+        MediaNotificationManager.clear(notificationId);
+    }
+
+    static NotificationWrapperBuilder createNotificationWrapperBuilder(int notificationId) {
+        // Only the null tag will work as expected, because {@link Service#startForeground()} only
+        // takes an ID and no tag. If we pass a tag here, then the notification that's used to
+        // display a paused state (no foreground service) will not be identified as the same one
+        // that's used with the foreground service.
+        return WebLayerNotificationWrapperBuilder.create(
+                WebLayerNotificationChannels.ChannelId.MEDIA_PLAYBACK,
+                new NotificationMetadata(0, null /*notificationTag*/, notificationId));
+    }
+}
diff --git a/weblayer/public/java/AndroidManifest.xml b/weblayer/public/java/AndroidManifest.xml
index fc088aac..20fc81b6 100644
--- a/weblayer/public/java/AndroidManifest.xml
+++ b/weblayer/public/java/AndroidManifest.xml
@@ -85,6 +85,13 @@
             </intent-filter>
         </service>
 
+        <service android:name="org.chromium.weblayer.RemoteMediaService"
+            android:exported="false">
+            <intent-filter>
+                <action android:name="android.intent.action.MEDIA_BUTTON" />
+            </intent-filter>
+        </service>
+
         <!-- Service for decoding images in a sandboxed process. -->
         <service
             android:name="org.chromium.weblayer.ImageDecoderService"
diff --git a/weblayer/public/java/BUILD.gn b/weblayer/public/java/BUILD.gn
index a346309..a76b3cf 100644
--- a/weblayer/public/java/BUILD.gn
+++ b/weblayer/public/java/BUILD.gn
@@ -70,6 +70,7 @@
     "org/chromium/weblayer/LoadError.java",
     "org/chromium/weblayer/MediaCaptureCallback.java",
     "org/chromium/weblayer/MediaCaptureController.java",
+    "org/chromium/weblayer/MediaPlaybackBaseService.java",
     "org/chromium/weblayer/MediaRouteDialogFragment.java",
     "org/chromium/weblayer/MediaSessionService.java",
     "org/chromium/weblayer/NavigateParams.java",
@@ -82,6 +83,7 @@
     "org/chromium/weblayer/ObserverList.java",
     "org/chromium/weblayer/Profile.java",
     "org/chromium/weblayer/RemoteFragment.java",
+    "org/chromium/weblayer/RemoteMediaService.java",
     "org/chromium/weblayer/ScrollNotificationType.java",
     "org/chromium/weblayer/ScrollOffsetCallback.java",
     "org/chromium/weblayer/SettingType.java",
diff --git a/weblayer/public/java/org/chromium/weblayer/MediaPlaybackBaseService.java b/weblayer/public/java/org/chromium/weblayer/MediaPlaybackBaseService.java
new file mode 100644
index 0000000..3184735
--- /dev/null
+++ b/weblayer/public/java/org/chromium/weblayer/MediaPlaybackBaseService.java
@@ -0,0 +1,101 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.weblayer;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.RemoteException;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+/**
+ * Base class that provides common functionality for media playback services that are associated
+ * with an active media session and Android notification.
+ */
+abstract class MediaPlaybackBaseService extends Service {
+    // True when the start command has been forwarded to the impl.
+    boolean mStarted;
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return null;
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+
+        if (!WebLayer.hasWebLayerInitializationStarted()) {
+            stopSelf();
+            return;
+        }
+
+        init();
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        WebLayer webLayer = getWebLayer();
+        if (webLayer == null) {
+            stopSelf();
+        } else {
+            try {
+                forwardStartCommandToImpl(webLayer, intent);
+            } catch (RemoteException e) {
+                throw new RuntimeException(e);
+            }
+            mStarted = true;
+        }
+
+        return START_NOT_STICKY;
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+
+        if (!mStarted) return;
+
+        try {
+            forwardDestroyToImpl();
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /** Called to do initialization when the service is created. */
+    void init() {}
+
+    /**
+     * Called to forward {@link onStartCommand()} to the WebLayer implementation.
+     *
+     * @param webLayer the implementation.
+     * @param intent the intent that started the service.
+     */
+    abstract void forwardStartCommandToImpl(@NonNull WebLayer webLayer, Intent intent)
+            throws RemoteException;
+
+    /**
+     * Called to forward {@link onDestroy()} to the WebLayer implementation.
+     *
+     * This will only be called if {@link forwardStartCommandToImpl()} was previously called, and
+     * there should always be a loaded {@link WebLayer} available via {@link getWebLayer()}.
+     */
+    abstract void forwardDestroyToImpl() throws RemoteException;
+
+    /** Returns the loaded {@link WebLayer}, or null if none is loaded. */
+    @Nullable
+    WebLayer getWebLayer() {
+        WebLayer webLayer;
+        try {
+            webLayer = WebLayer.getLoadedWebLayer(getApplication());
+        } catch (UnsupportedVersionException e) {
+            throw new RuntimeException(e);
+        }
+        return webLayer;
+    }
+}
diff --git a/weblayer/public/java/org/chromium/weblayer/MediaSessionService.java b/weblayer/public/java/org/chromium/weblayer/MediaSessionService.java
index e3cf06e..e1a6003 100644
--- a/weblayer/public/java/org/chromium/weblayer/MediaSessionService.java
+++ b/weblayer/public/java/org/chromium/weblayer/MediaSessionService.java
@@ -9,9 +9,10 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.media.AudioManager;
-import android.os.IBinder;
 import android.os.RemoteException;
 
+import androidx.annotation.NonNull;
+
 import org.chromium.weblayer_private.interfaces.ObjectWrapper;
 
 /**
@@ -21,24 +22,20 @@
  * foreground when the MediaSession is active.
  * @since 85
  */
-public class MediaSessionService extends Service {
+public class MediaSessionService extends MediaPlaybackBaseService {
     // A helper to automatically pause the media session when a user removes headphones.
     private BroadcastReceiver mAudioBecomingNoisyReceiver;
 
     @Override
-    public IBinder onBind(Intent intent) {
-        return null;
+    public void onDestroy() {
+        super.onDestroy();
+        if (mAudioBecomingNoisyReceiver != null) {
+            unregisterReceiver(mAudioBecomingNoisyReceiver);
+        }
     }
 
     @Override
-    public void onCreate() {
-        super.onCreate();
-
-        if (!WebLayer.hasWebLayerInitializationStarted()) {
-            stopSelf();
-            return;
-        }
-
+    void init() {
         mAudioBecomingNoisyReceiver = new BroadcastReceiver() {
             @Override
             public void onReceive(Context context, Intent intent) {
@@ -57,43 +54,13 @@
     }
 
     @Override
-    public void onDestroy() {
-        super.onDestroy();
-
-        if (mAudioBecomingNoisyReceiver == null) return;
-
-        try {
-            getWebLayer().getImpl().onMediaSessionServiceDestroyed();
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-
-        unregisterReceiver(mAudioBecomingNoisyReceiver);
+    void forwardStartCommandToImpl(@NonNull WebLayer webLayer, Intent intent)
+            throws RemoteException {
+        webLayer.getImpl().onMediaSessionServiceStarted(ObjectWrapper.wrap(this), intent);
     }
 
     @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        try {
-            WebLayer webLayer = getWebLayer();
-            if (webLayer == null) {
-                stopSelf();
-            } else {
-                webLayer.getImpl().onMediaSessionServiceStarted(ObjectWrapper.wrap(this), intent);
-            }
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-
-        return START_NOT_STICKY;
-    }
-
-    private WebLayer getWebLayer() {
-        WebLayer webLayer;
-        try {
-            webLayer = WebLayer.getLoadedWebLayer(getApplication());
-        } catch (UnsupportedVersionException e) {
-            throw new RuntimeException(e);
-        }
-        return webLayer;
+    void forwardDestroyToImpl() throws RemoteException {
+        getWebLayer().getImpl().onMediaSessionServiceDestroyed();
     }
 }
diff --git a/weblayer/public/java/org/chromium/weblayer/RemoteMediaService.java b/weblayer/public/java/org/chromium/weblayer/RemoteMediaService.java
new file mode 100644
index 0000000..1a3b64fe
--- /dev/null
+++ b/weblayer/public/java/org/chromium/weblayer/RemoteMediaService.java
@@ -0,0 +1,40 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.weblayer;
+
+import android.content.Intent;
+import android.os.RemoteException;
+
+import androidx.annotation.NonNull;
+
+import org.chromium.weblayer_private.interfaces.ObjectWrapper;
+import org.chromium.weblayer_private.interfaces.RemoteMediaServiceConstants;
+
+/**
+ * A foreground {@link Service} for Presentation API and Remote Playback API.
+ *
+ * Like {@link MediaSessionService}, this class is associated with a notification for an ongoing
+ * media session. The difference is that the media for this service is played back on a remote
+ * device, i.e. casting.
+ *
+ * @since 88
+ */
+public class RemoteMediaService extends MediaPlaybackBaseService {
+    private int mId;
+
+    @Override
+    void forwardStartCommandToImpl(@NonNull WebLayer webLayer, Intent intent)
+            throws RemoteException {
+        mId = intent.getIntExtra(RemoteMediaServiceConstants.NOTIFICATION_ID_KEY, 0);
+        if (mId == 0) throw new RuntimeException("Invalid RemoteMediaService notification id");
+
+        webLayer.getImpl().onRemoteMediaServiceStarted(ObjectWrapper.wrap(this), intent);
+    }
+
+    @Override
+    void forwardDestroyToImpl() throws RemoteException {
+        getWebLayer().getImpl().onRemoteMediaServiceDestroyed(mId);
+    }
+}
diff --git a/weblayer/public/java/org/chromium/weblayer/WebLayer.java b/weblayer/public/java/org/chromium/weblayer/WebLayer.java
index 7dca1ca..943207a 100644
--- a/weblayer/public/java/org/chromium/weblayer/WebLayer.java
+++ b/weblayer/public/java/org/chromium/weblayer/WebLayer.java
@@ -749,6 +749,26 @@
         public long getWebLayerLoaderCreationTime() {
             return sWebLayerLoaderCreationTime;
         }
+
+        @Override
+        public Intent createRemoteMediaServiceIntent() {
+            StrictModeWorkaround.apply();
+            return new Intent(WebLayer.getAppContext(), RemoteMediaService.class);
+        }
+
+        @Override
+        public int getPresentationApiNotificationId() {
+            StrictModeWorkaround.apply();
+            // The id is part of the public library to avoid conflicts.
+            return R.id.weblayer_presentation_api_notification;
+        }
+
+        @Override
+        public int getRemotePlaybackApiNotificationId() {
+            StrictModeWorkaround.apply();
+            // The id is part of the public library to avoid conflicts.
+            return R.id.weblayer_remote_playback_api_notification;
+        }
     }
 
     @VerifiesOnO
diff --git a/weblayer/public/java/res/values/ids.xml b/weblayer/public/java/res/values/ids.xml
index 300c7e62..ed73b87 100644
--- a/weblayer/public/java/res/values/ids.xml
+++ b/weblayer/public/java/res/values/ids.xml
@@ -5,4 +5,6 @@
 
 <resources>
     <item type="id" name="weblayer_media_session_notification" />
+    <item type="id" name="weblayer_presentation_api_notification" />
+    <item type="id" name="weblayer_remote_playback_api_notification" />
 </resources>
diff --git a/weblayer/weblayer_module.gni b/weblayer/weblayer_module.gni
new file mode 100644
index 0000000..98004e72
--- /dev/null
+++ b/weblayer/weblayer_module.gni
@@ -0,0 +1,9 @@
+# Copyright 2020 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.
+
+weblayer_module_desc = {
+  name = "weblayer"
+  android_manifest = "//weblayer/browser/java/AndroidManifest_monochrome.xml"
+  supports_isolated_split = true
+}